[GH-3111] Fix scanline x-intercepts on rasters with non-square pixels#3113
Merged
jiayuasu merged 5 commits intoJul 19, 2026
Merged
Conversation
james-willis
marked this pull request as ready for review
July 17, 2026 08:12
jiayuasu
approved these changes
Jul 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Did you read the Contributor Guide?
Is this PR related to a ticket?
[GH-XXX] my subject. Closes Rasterization selects wrong pixels on rasters with non-square pixels (pixel/world unit mix in scanline x-intercepts) #3111What changes were proposed in this PR?
Rasterization.computeScanlineIntersectionscomputed edge x-intercepts asp1X + ((p1Y - y) / slope), dividing a pixel-space Δy by a world-space slope. On square north-up pixels the missing factor-scaleY/scaleXequals 1 so the result is coincidentally correct, but on any raster whose pixels are not square in world units the intercepts land in the wrong place and pixels whose centers are inside the polygon are dropped (or near-edge pixels selected asymmetrically). This PR converts the pixel Δy to world units and the resulting world Δx back to pixels, keeping the intercept in pixel space for any pixel aspect ratio.How was this patch tested?
testAsRasterWithNonSquarePixelscovering the centroid rule,allTouched, a polygon with a diagonal-edged interior ring, and a bottom-up grid, all on 2x3-world-unit pixels. Expected matrices are produced by GDAL (rasterio.features.rasterize) on the same grids. The test was written first and fails on master (the dropped center-inside pixels from Rasterization selects wrong pixels on rasters with non-square pixels (pixel/world unit mix in scanline x-intercepts) #3111).commonmodule suite passes (1146 tests, 0 failures): existing square-pixel expectations are bit-identical before and after the fix.RasterConstructors.asRasteragainstrasterio.features.rasterizeover random polygons on random anisotropic north-up and south-up grids: centroid-rule mismatches go from 187/214 cases before the fix to 0/214 after. (TheallTouchedboundary path, which rasterizes ring segments with Bresenham rather than scanlines, retains a small pre-existing divergence from GDAL — 24/86 fuzz cases by 1-2 boundary pixels, down from 32/86 — which is a separate issue.)python/tests/sql/test_rasterize_parity.py, comparingRS_AsRasteragainstrasterio.features.rasterizein a single batched Spark job. The centroid-rule test fails against the released 1.9.0 jars and passes with this fix; the same corpus underallTouched=trueis a strictxfaildocumenting the pre-existing sampling divergence above, and will flip to a visible failure when that is fixed.Did this PR include necessary documentation updates?