james-willis opened a new issue, #3112:
URL: https://github.com/apache/sedona/issues/3112

   ## Expected behavior
   
   When `RS_AsRaster` is called with a `noDataValue`, pixels not covered by the 
geometry should be set to that value, so the output distinguishes "burned" from 
"background". This is what PostGIS `ST_AsRaster` does (`nodataval` is assigned 
to cells not touched by the geometry), and the GDAL equivalent (`gdal_rasterize 
-init <nodata> -a_nodata <nodata>`, or 
`rasterio.features.rasterize(fill=nodata)`).
   
   ## Actual behavior
   
   The `noDataValue` is only attached as band metadata. Background pixels keep 
Java's zero-initialized default, so they come out as `0` — a perfectly valid 
pixel value — while the band claims its nodata is something else.
   
   A polygon with a hole makes the consequence concrete. Repro on a 7x6 grid 
(Sedona 1.9.0, Spark 4.0), burning 1 with nodata 9:
   
   ```sql
   SELECT RS_BandAsArray(RS_AsRaster(
     ST_GeomFromWKT('POLYGON ((100.2 499.5, 113.8 499.5, 113.8 482.4, 100.2 
482.4, 100.2 499.5),
                              (104.1 496.9, 110.2 496.9, 110.2 487.8, 104.1 
487.8, 104.1 496.9))'),
     RS_MakeEmptyRaster(1, 'B', 7, 6, 100.0, 500.0, 2.0, -3.0, 0.0, 0.0, 0),
     'B', false, 1.0, 9.0, false), 1)
   ```
   
   Sedona returns (reshaped to 6x7, `RS_BandNoDataValue` reports 9.0):
   
   ```
   1 1 1 1 1 1 1
   1 1 0 0 0 1 1
   1 1 0 0 0 1 1
   1 1 0 0 0 1 1
   1 1 1 1 1 1 1
   1 1 1 1 1 1 1
   ```
   
   PostGIS and GDAL/rasterio return:
   
   ```
   1 1 1 1 1 1 1
   1 1 9 9 9 1 1
   1 1 9 9 9 1 1
   1 1 9 9 9 1 1
   1 1 1 1 1 1 1
   1 1 1 1 1 1 1
   ```
   
   The pixel selection itself is identical across engines here (all rings are 
axis-aligned), so the divergence is purely the background fill. The hole shows 
why this can't be worked around by choosing a tighter extent: the uncovered 
region is interior to the geometry, and it reads back as valid data `0` rather 
than nodata.
   
   ## Root cause
   
   `RasterConstructors.asRaster` burns the geometry into the `WritableRaster` 
returned by `Rasterization.rasterize` (whose backing Java array is 
zero-initialized), then only records the nodata as metadata via 
`setBandNoDataValue` — nothing ever writes the background 
([RasterConstructors.java#L133-L149 @ 
0299fa8](https://github.com/apache/sedona/blob/0299fa8a380a/common/src/main/java/org/apache/sedona/common/raster/RasterConstructors.java#L133-L149)):
   
   ```java
   List<Object> objects =
       Rasterization.rasterize(geom, raster, pixelType, value, 
useGeometryExtent, allTouched);
   
   WritableRaster writableRaster = (WritableRaster) objects.get(0);
   ...
   if (noDataValue != null) {
     resultRaster = RasterBandEditors.setBandNoDataValue(resultRaster, 1, 
noDataValue);
   }
   ```
   
   This is entirely Sedona-side (no geotools constraint): the fix is to 
initialize the raster's pixels to `noDataValue` before burning whenever one is 
provided.
   
   ## Impact
   
   Any downstream consumer that respects nodata (stats, map algebra, export to 
GeoTIFF and reading in other tools) treats the entire background as valid 
zeros. When 0 is a legitimate data value there is no way to tell background 
from data, despite the caller having explicitly declared a nodata value.
   
   Affected versions: reproduced on 1.9.0 (released jars); the same code is 
present on current master (`0299fa8`).
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to