Skip to content

[GH-3469] Rasterize each polygon ring separately in the viz utilities - #3485

Open
Mayukh-D wants to merge 3 commits into
apache:masterfrom
Mayukh-D:GH-3469-viz-polygon-rings
Open

Mayukh-D wants to merge 3 commits into
apache:masterfrom
Mayukh-D:GH-3469-viz-polygon-rings

Conversation

@Mayukh-D

@Mayukh-D Mayukh-D commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Did you read the Contributor Guide?

Is this PR related to a ticket?

What changes were proposed in this PR?

Both polygon paths in RasterizationUtils.FindPixelCoordinates used Polygon.getCoordinates(), which joins the exterior ring and the holes into one list. So the outline path drew an extra segment from the end of one ring to the start of the next, and the fill path treated everything as one self-crossing ring, losing the interior pixels along that segment.

The outline path now traces each ring on its own, and the fill path keeps holes as holes. Polygons without holes rasterize exactly as before. An empty polygon now returns no pixels instead of throwing IndexOutOfBoundsException.

The fill path now checks each pixel with SimplePointInAreaLocator instead of Polygon.contains. Snapping a hole to pixels can put its edge on the exterior ring or on another hole, and Polygon.contains throws a TopologyException on such rings, even for valid input polygons.

How was this patch tested?

New RasterizationUtilsTest: no holes, one hole, several holes, holes that snap onto the exterior ring or onto each other, and empty polygons, for both outline and fill. Compared old and new output on 5,000 random hole-free polygons (identical), and the 18 existing Java and 8 Scala viz tests pass along with the 9 new ones.

Did this PR include necessary documentation updates?

  • No, this PR does not affect any public API so no need to change the documentation.

Assisted by Claude Code
Generated-by: Claude Code (Claude Opus 5.5)

…lities

Both polygon paths in RasterizationUtils.FindPixelCoordinates read
Polygon.getCoordinates(), which concatenates the exterior ring and the
holes. The outline path therefore also traced a segment from the end of
one ring to the start of the next, adding pixels to ST_Pixelize and the
RDD outline renderer. The fill path turned the concatenated coordinates
into a single self-crossing ring, dropping the interior pixels along that
segment.

The outline path now traces each ring on its own, and the fill path
converts each ring to pixel space and keeps the holes as holes. Polygons
without holes rasterize exactly as before. An empty polygon now has no
pixels instead of failing with an IndexOutOfBoundsException in the fill
path.

Generated-by: Claude Code (Claude Opus 5.5)
@Mayukh-D
Mayukh-D requested a review from jiayuasu as a code owner October 19, 2026 14:21
@Mayukh-D

Copy link
Copy Markdown
Contributor Author

Hi @jiayuasu, gentle ping on this one too. The CI workflows need maintainer approval before they can run. Once they're green I'm happy to make any changes. Thanks for reviewing #3483 so quickly!

Mayukh-D and others added 2 commits October 23, 2026 06:10
…ontains

Once the rings are snapped to pixels, a hole can share an edge with the
exterior ring or with another hole, for example a hole 0.5 units from
the shell on a 1-unit grid. Polygon.contains then throws a
TopologyException ("side location conflict") for valid input polygons.
Locating each pixel point with SimplePointInAreaLocator gives the same
pixels without building a topology graph, so it does not throw.

Generated-by: Claude Code (Claude Opus 5.5)
@Mayukh-D

Copy link
Copy Markdown
Contributor Author

Pushed one more commit: while fuzzing the fill path I found that snapping a hole to pixels can put its edge on the exterior ring or on another hole, and Polygon.contains then throws a TopologyException (even for valid input polygons). The fill now uses SimplePointInAreaLocator, which gives the same pixels otherwise and does not throw. Added two regression tests for those cases and updated the description.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Viz rasterization joins polygon rings: a spurious segment in ST_Pixelize and the outline renderer, and a gap in the filled polygon

4 participants