Refs #30489 -- Made from_pgraster()/to_pgraster() use BANDTYPE_FLAG_HASNODATA and bitwise operators for nodata flag.

This commit is contained in:
Ivor Bosloper 2020-03-04 13:45:15 +01:00 committed by Mariusz Felisiak
parent 427a7e419b
commit 828e3b1335
2 changed files with 14 additions and 10 deletions

View File

@ -41,3 +41,6 @@ STRUCT_SIZE = {
'f': 4, # Float 'f': 4, # Float
'd': 8, # Double 'd': 8, # Double
} }
# See https://trac.osgeo.org/postgis/wiki/WKTRaster/RFC/RFC1_V0SerialFormat#Pixeltypeandstorageflag
BANDTYPE_FLAG_HASNODATA = 1 << 6

View File

@ -3,8 +3,8 @@ import struct
from django.forms import ValidationError from django.forms import ValidationError
from .const import ( from .const import (
GDAL_TO_POSTGIS, GDAL_TO_STRUCT, POSTGIS_HEADER_STRUCTURE, POSTGIS_TO_GDAL, BANDTYPE_FLAG_HASNODATA, GDAL_TO_POSTGIS, GDAL_TO_STRUCT,
STRUCT_SIZE, POSTGIS_HEADER_STRUCTURE, POSTGIS_TO_GDAL, STRUCT_SIZE,
) )
@ -48,10 +48,10 @@ def from_pgraster(data):
pixeltype, data = chunk(data, 2) pixeltype, data = chunk(data, 2)
pixeltype = unpack('B', pixeltype)[0] pixeltype = unpack('B', pixeltype)[0]
# Subtract nodata byte from band nodata value if it exists # Remove nodata byte from band nodata value if it exists.
has_nodata = pixeltype >= 64 has_nodata = pixeltype & BANDTYPE_FLAG_HASNODATA
if has_nodata: if has_nodata:
pixeltype -= 64 pixeltype &= ~BANDTYPE_FLAG_HASNODATA
# Convert datatype from PostGIS to GDAL & get pack type and size # Convert datatype from PostGIS to GDAL & get pack type and size
pixeltype = POSTGIS_TO_GDAL[pixeltype] pixeltype = POSTGIS_TO_GDAL[pixeltype]
@ -116,12 +116,13 @@ def to_pgraster(rast):
# and the nodata value. # and the nodata value.
# #
# The 8BUI stores both the PostGIS pixel data type and a nodata flag. # The 8BUI stores both the PostGIS pixel data type and a nodata flag.
# It is composed as the datatype integer plus 64 as a flag for existing # It is composed as the datatype with BANDTYPE_FLAG_HASNODATA (1 << 6)
# nodata values: # for existing nodata values:
# 8BUI_VALUE = PG_PIXEL_TYPE (0-11) + FLAG (0 or 64) # 8BUI_VALUE = PG_PIXEL_TYPE (0-11) | BANDTYPE_FLAG_HASNODATA
# #
# For example, if the byte value is 71, then the datatype is # For example, if the byte value is 71, then the datatype is
# 71-64 = 7 (32BSI) and the nodata value is True. # 71 & ~BANDTYPE_FLAG_HASNODATA = 7 (32BSI)
# and the nodata value is True.
structure = 'B' + GDAL_TO_STRUCT[band.datatype()] structure = 'B' + GDAL_TO_STRUCT[band.datatype()]
# Get band pixel type in PostGIS notation # Get band pixel type in PostGIS notation
@ -129,7 +130,7 @@ def to_pgraster(rast):
# Set the nodata flag # Set the nodata flag
if band.nodata_value is not None: if band.nodata_value is not None:
pixeltype += 64 pixeltype |= BANDTYPE_FLAG_HASNODATA
# Pack band header # Pack band header
bandheader = pack(structure, (pixeltype, band.nodata_value or 0)) bandheader = pack(structure, (pixeltype, band.nodata_value or 0))