Opened 6 years ago
Last modified 6 years ago
#30489 closed Bug
Django RasterField deserialization bug with pixeltype flags — at Initial Version
| Reported by: | Ivor Bosloper | Owned by: | nobody |
|---|---|---|---|
| Component: | GIS | Version: | dev |
| Severity: | Normal | Keywords: | RasterField |
| Cc: | Hasan Ramezani | Triage Stage: | Ready for checkin |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
After inserting some raster data with raster2pgsql into a Django model table with a RasterField column, I get a list index out of range when querying the table with a Django Queryset.
... File "django/contrib/gis/db/models/fields.py" in from_db_value 360. return connection.ops.parse_raster(value) File "django/contrib/gis/db/backends/postgis/operations.py" in parse_raster 369. return from_pgraster(value) File "django/contrib/gis/db/backends/postgis/pgraster.py" in from_pgraster 57. pixeltype = POSTGIS_TO_GDAL[pixeltype]
It turns out the pixeltype value used is 39 while the POSTGIS_TO_GDAL list is only 16 elements long. The database field contains valid data but can not be deserialized with Django.
Steps for reproduction:
# Django model
class RasterModel(models.Model):
rast = models.RasterField(srid=4326)
# raw sql, single pixel raster with nodata bit set
insert into app_rastermodel values(1, REPLACE('01 0000 0100 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 E6100000 0100 0100 6 2 03 03', ' ', '')::raster);
# query generating Exception
RasterModel.objects.get(pk=1)
Analysis: if we look at the Raster specification, the pixeltype is a byte of which the 4 highest bits are flags and the lowest 4 bits are the real pixeltype, but the Django deserialization code only considers one bit-flag:
# django/contrib/gis/db/backends/postgis/pgraster.py
def from_pgraster(data):
...
# Subtract nodata byte from band nodata value if it exists
has_nodata = pixeltype >= 64
if has_nodata:
pixeltype -= 64
...
I have created (my first django) patch and hope somebody can assist me in getting it correct and merged.