You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Fix GPU ceil approximation, half-open fill convention, and all_touched edge pairing (#995)
Three rasterize accuracy fixes:
1. GPU scanline used int(x + 0.999999) as a ceil approximation. This
diverges from CPU's np.ceil for values within 1e-6 of an integer.
Replaced with exact int-based ceil logic.
2. Scanline fill used closed interval [ceil(x_start), floor(x_end)]
for column ranges. This double-counts boundary pixels when adjacent
polygons share an edge, and includes pixels whose centers fall outside
the polygon. Changed to half-open [ceil(x_start), ceil(x_end)-1],
matching GDAL's convention for axis-aligned edges.
3. all_touched mode expanded edge y-ranges, which broke even-odd edge
pairing on rows where the expansion created an odd active edge count.
This caused all_touched=True to fill fewer pixels than all_touched=False.
Fixed by keeping normal scanline fill and drawing polygon boundaries
via Bresenham separately, guaranteeing the result is a superset.
* Add rasterize accuracy test suite with invariant-based checks (#995)
41 tests exercising mathematical properties of correct rasterization:
- Watertight tiling: non-overlapping polygons counted exactly once
- Area conservation: rasterized area converges to analytic area
- Point-in-polygon cross-check: shapely.contains vs rasterized grid
- Annulus: polygon with hole matches pi*(R^2 - r^2)
- Symmetry: axis-aligned shapes perfectly symmetric, others bounded
- Merge mode identities: sum-with-ones equals count, etc.
- all_touched monotonicity: always a superset of normal fill
- rasterio reference: exact match for axis-aligned, <3% diff for slanted
- Edge cases: thin polygons, concave shapes, nearly-degenerate triangles
0 commit comments