Convert a GDALRaster into PostGIS Raster format.
(rast)
| 98 | |
| 99 | |
| 100 | def to_pgraster(rast): |
| 101 | """ |
| 102 | Convert a GDALRaster into PostGIS Raster format. |
| 103 | """ |
| 104 | # Prepare the raster header data as a tuple. The first two numbers are |
| 105 | # the endianness and the PostGIS Raster Version, both are fixed by |
| 106 | # PostGIS at the moment. |
| 107 | rasterheader = ( |
| 108 | 1, |
| 109 | 0, |
| 110 | len(rast.bands), |
| 111 | rast.scale.x, |
| 112 | rast.scale.y, |
| 113 | rast.origin.x, |
| 114 | rast.origin.y, |
| 115 | rast.skew.x, |
| 116 | rast.skew.y, |
| 117 | rast.srs.srid, |
| 118 | rast.width, |
| 119 | rast.height, |
| 120 | ) |
| 121 | |
| 122 | # Pack raster header. |
| 123 | result = pack(POSTGIS_HEADER_STRUCTURE, rasterheader) |
| 124 | |
| 125 | for band in rast.bands: |
| 126 | # The PostGIS raster band header has exactly two elements, a 8BUI byte |
| 127 | # and the nodata value. |
| 128 | # |
| 129 | # The 8BUI stores both the PostGIS pixel data type and a nodata flag. |
| 130 | # It is composed as the datatype with BANDTYPE_FLAG_HASNODATA (1 << 6) |
| 131 | # for existing nodata values: |
| 132 | # 8BUI_VALUE = PG_PIXEL_TYPE (0-11) | BANDTYPE_FLAG_HASNODATA |
| 133 | # |
| 134 | # For example, if the byte value is 71, then the datatype is |
| 135 | # 71 & ~BANDTYPE_FLAG_HASNODATA = 7 (32BSI) |
| 136 | # and the nodata value is True. |
| 137 | structure = "B" + GDAL_TO_STRUCT[band.datatype()] |
| 138 | |
| 139 | # Get band pixel type in PostGIS notation |
| 140 | pixeltype = GDAL_TO_POSTGIS[band.datatype()] |
| 141 | |
| 142 | # Set the nodata flag |
| 143 | if band.nodata_value is not None: |
| 144 | pixeltype |= BANDTYPE_FLAG_HASNODATA |
| 145 | |
| 146 | # Pack band header |
| 147 | bandheader = pack(structure, (pixeltype, band.nodata_value or 0)) |
| 148 | |
| 149 | # Add packed header and band data to result |
| 150 | result += bandheader + band.data(as_memoryview=True) |
| 151 | |
| 152 | return result |