geodesign / django-raster

Django-raster allows you to create tiled map services (TMS) and raster map algebra end points for web maps. It is Python-based, and requires GeoDjango with a PostGIS backend.
BSD 3-Clause "New" or "Revised" License
96 stars 39 forks source link

Django raster for panorama view of big images #48

Open al-muammar opened 4 years ago

al-muammar commented 4 years ago

I'm trying to implement panoramic view of big images (not geo-related). This is an example of what I would like to do: http://www.precipoint.com/o8-oil-microscope-scanner/

From the example above I see that they use leaflet.js and images with .gtif format. It seems that all of the machinery from django-raster could be reused. The first question: is it the right choice to use django raster for this?

The second question. When uploading an image via the admin website (I set up srid to 3857), the following exception occurs:

  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/raster/models.py", line 241, in parse_raster_layer_if_status_is_unparsed
    parse(instance.id)
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/raster/tasks.py", line 129, in parse
    all_in_one(rasterlayer_id, zoom_range)
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/celery/local.py", line 191, in __call__
    return self._get_current_object()(*a, **kw)
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/celery/app/task.py", line 392, in __call__
    return self.run(*args, **kwargs)
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/raster/tasks.py", line 75, in all_in_one
    create_tiles(rasterlayer_id, zoom_range, True)
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/celery/local.py", line 191, in __call__
    return self._get_current_object()(*a, **kw)
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/celery/app/task.py", line 392, in __call__
    return self.run(*args, **kwargs)
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/raster/tasks.py", line 39, in create_tiles
    parser.create_tiles(zoom)
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/raster/tiles/parser.py", line 286, in create_tiles
    self.populate_tile_level(zoom)
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/raster/tiles/parser.py", line 309, in populate_tile_level
    self.process_quadrant(indexrange, zoom)
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/raster/tiles/parser.py", line 348, in process_quadrant
    'height': (indexrange[3] - indexrange[1] + 1) * self.tilesize,
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/django/contrib/gis/gdal/raster/source.py", line 413, in warp
    c_void_p(), c_void_p(), c_void_p()
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/django/contrib/gis/gdal/prototypes/errcheck.py", line 118, in check_errcode
    check_err(result, cpl=cpl)
  File "~/.virtualenvs/testsite/lib/python3.7/site-packages/django/contrib/gis/gdal/error.py", line 59, in check_err
    raise e(msg)
django.contrib.gis.gdal.error.GDALException: FileIO

Before that I usually see:

GDAL_ERROR 1: b'The transformation is already "north up" or a transformation between pixel/line and georeferenced coordinates cannot be computed for /tmp/tmpb3y4vimd/almost-there_XFSV2t1.tiff. There is no affine transformation and no GCPs
. Specify transformation option SRC_METHOD=NO_GEOTRANSFORM to bypass this check.'

And after the server returns 500 I see sometimes (probably, because the directory is deleted):

GDAL_ERROR 1: b'Unable to save auxiliary information in /tmp/abcdef/almost-there_2mg1OYo.tif.aux.xml.'

How to overcome that?

yellowcap commented 4 years ago

Since your image is not a GEO-Tiff file, probably it does not contain a proper projection definition. For django-raster to work, the input files need to be GeoTiff files or similar, which have a projection stored internally or as a metadata file that comes with the geographical image.

But maybe you don't need to tile your image in the first place. If the image is not too large, you could try the following directly in Leaflet, without tiling the image first:

https://leafletjs.com/examples/crs-simple/crs-simple.html

If your image is too big and that does not work for you, you could try to assign coordinates to the file. Maybe https://gdal.org/programs/gdal_edit.html could work for you. You can simply choose any bounding box in a projection of your choice and assign that to the file. If you do this right, django-raster should be able to parse it.

al-muammar commented 4 years ago

Thanks for your response, @yellowcap! We have quite large images, so crs simple, unfortunately, won't fit our needs. I was able to add coordinate system and tweaked a bit the target resolution via gdal_edit.py. Here is what I have now:

$ gdalinfo image.tif
Driver: GTiff/GeoTIFF
Files: image.tif
Size is 1024, 1024
Coordinate System is:
GEOGCS["WGS 84",
    DATUM["WGS_1984",
        SPHEROID["WGS 84",6378137,298.257223563,
            AUTHORITY["EPSG","7030"]],
        AUTHORITY["EPSG","6326"]],
    PRIMEM["Greenwich",0],
    UNIT["degree",0.0174532925199433],
    AUTHORITY["EPSG","4326"]]
Origin = (0.000000000000000,0.000000000000000)
Pixel Size = (0.000197629362510,-0.000197629362510)
Metadata:
  AREA_OR_POINT=Area
Image Structure Metadata:
  INTERLEAVE=BAND
Corner Coordinates:
Upper Left  (   0.0000000,   0.0000000) (  0d 0' 0.01"E,  0d 0' 0.01"N)
Lower Left  (   0.0000000,  -0.2023725) (  0d 0' 0.01"E,  0d12' 8.54"S)
Upper Right (   0.2023725,   0.0000000) (  0d12' 8.54"E,  0d 0' 0.01"N)
Lower Right (   0.2023725,  -0.2023725) (  0d12' 8.54"E,  0d12' 8.54"S)
Center      (   0.1011862,  -0.1011862) (  0d 6' 4.27"E,  0d 6' 4.27"S)
Band 1 Block=1024x8 Type=Byte, ColorInterp=Gray
  Offset: -2.17033597936372,   Scale:1.97629362506295e-05

I successfully added a RasterLayer. Here are condensed logs:

[2020-05-19 10:09:53] Started parsing raster.
[2020-05-19 10:09:53] Clearing all existing tiles.
[2020-05-19 10:09:53] Finished clearing existing tiles.
[2020-05-19 10:09:53] Extracting metadata from raster.
[2020-05-19 10:09:53] Finished extracting metadata from raster.
[2020-05-19 10:09:53] Transforming raster to SRID 3857
[2020-05-19 10:09:53] Finished transforming raster.
[2020-05-19 10:09:53] Creating 1 tiles in 1 quadrants at zoom 0.
...
[2020-05-19 10:09:54] Creating 64 tiles in 1 quadrants at zoom 17.
[2020-05-19 10:09:54] Starting tile creation for quadrant 18 at zoom level 17
[2020-05-19 10:09:54] Finished parsing at zoom level 17.
[2020-05-19 10:09:54] Successfully finished parsing raster

Unfortunately, I'm unable to view anything with leaflet. It just outputs an empty screen. It seems to be a problem in the raster serving layer. I've opened a random tile and it has:

Tilex: 32769
Tiley: 32769
Tilez: 16

I picked my RasterLayer pk and formed a url: raster/tiles/43/16/32769/32769.png and it returns me an empty png. The same with any other raster tile. Here is my file example for reproduction. image.tif.zip

ansaril3 commented 4 years ago

@yellowcap it'll be very helpful if you send an example/tutorial with processing a raster file with django-raster and opening it in the leaflet (or any map viewer).

Thank you!