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]