[GIS] Raster functionality in GeoDjango

django-rastergeodjangoraster

Does anyone know of good tutorials on how to build raster models (using PostGIS) in GeoDjango? I found Geodjango read raster files from 3 years ago, as well as some sparse documentation for django-raster, but no real examples or tutorials of how to use the module.

Could someone point me to example code for how to implement django-raster?


I've successfully gotten raster data into a GeoDjango model/postgis database, but now am having trouble rendering it. The code I have:

In my models.py:

class testRaster(models.Model):
    raster_id = models.TextField(primary_key=True, default=1)
    name = models.TextField(default='test_layer')
    raster = models.RasterField()

In my html:

new L.tileLayer('/raster/tiles/1/{z}/{x}/{y}.png');

I think my understanding of the layer_id as referenced in the django-raster docs is slightly off.

Also, I am unsure if:

  1. I should even be using tileLayer, since the test raster I am using is quite small and may not even have been tiled.
  2. If I should be passing the tiles link through a Django URL like so:

new L.tileLayer('{% url '/raster/tiles/1/{z}/{x}/{y}.png' %}');

Best Answer

How to use rasters in Django depends on your use case of course. In the simplest case, if your rasters are relatively small and do not need tiling, you can simply declare a model with a raster field and assign rasters to it.

# models.py
from django.contrib.gis.db import models
class RasterWithName(models.Model):
    raster = models.RasterField()
    name = models.TextField()

# In the django shell
from django.contrib.gis.gdal import GDALRaster
# Open raster file using GDALRaster.
raster = GDALRaster('/path/to/your/raster.tif')
# Store file content in database using the raster field.
RasterWithName.objects.create(raster=raster, name='My new raster')

Loading a raster into postgis is as simple as that. Note that like that every time you will get one instance of the RasterWithName model, it will load the entire raster. This works fine for smaller rasters, but for large ones this might be clunky, depending on how you want to use it.

Saving one model instance does load the data into postgres, its not more complicated than that. However, you still do not have views or url endpoints to render the raster on the web. You can use external software to serve the rasters (such as mapserver for instance).

If you want to stay within the Django universe, I would use the django-raster package. It has a tiling engine, which splits your rasters into tiles instead of loading them as one object. It also has a views and url endpoints that are useful to display the rasters in a web map through a z-x-y tile scheme. The main limitation of the django-raster package at the moment is that it always stores the raster in the Web Mercator projection (srid 3857).

To use django-raster, install the package and then create a RasterLayer object through the admin interface. When creating a raster layer you can upload your raster file in the rasterfile field. Django-raster will then automatically parse the raster and create tiles that are stored in the RasterTile model. On the admin page of the RasterLayer instance, you can consult the parse log to see if the parsing was successful.

Once a layer is parsed, you can directly use the raster layer in a javascript environment (such as openlayers or leaflet) by using the tiles end point.

The parsing of the raster layer can be a long process if the file is large. For larger rasters, the parsing during web request might time out. You can configure your application to use celery for asynchronous parsing (see this section of the installation). Alternatively, you can create your raster layers in the django shell instead of using the admin interface.

Disclaimer: I am the author of the django-raster package, so my recommendation might be biased.