Fix "Hole lies outside shell" for reversed islands - #53
Open
wangi wants to merge 1 commit into
Open
Conversation
organizePolygons() decides which rings are holes based on their direction only and uses just a bounding box test when assigning a hole to a polygon. An island whose coastline was mapped the wrong way round can therefore end up as a hole of a polygon it is not inside of. GEOS then reports "Hole lies outside shell" and the whole polygon, possibly a whole continent, is invalid and ends up in the error_lines table. The existing direction fix runs after the polygons have been created and only looks at exterior rings, so it never caught this case. Interior rings that are outside their shell are now taken out of the polygon, turned around into land polygons of their own and reported in the error_lines table with the error "direction". While at it, invalid polygons that are not part of a multipolygon are now repaired in the same way as those that are, instead of being dropped. Fixes osmcode#41 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Author
|
I have also tested this against the files referenced on #41, which now gives following output: Also tested as part of the complete OpenGeofiction coastline process. |
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.
Fixes #41.
The problem
create_polygons()callsorganizePolygons()withMETHOD=ONLY_CCW, so ring direction alone decides shell vs. hole, and a hole is assigned to a shell using only a bounding box test. An island whose coastline was mapped the wrong way round becomes a hole candidate, and if it happens to lie inside the bounding box of a larger landmass (but outside the landmass itself) it is attached to it as a hole. GEOS then reportsand the whole polygon — possibly a whole continent — is invalid and ends up in the
error_linestable, or is dropped entirely.The existing "Fixing coastlines going the wrong way" step runs after the polygons have been created and only looks at exterior rings, so it never caught this case and reported "Turned 0 polygons around".
The fix
When a polygon is invalid, each interior ring is checked against the exterior ring. The check tests the first point of the interior ring with
OGRLinearRing::isPointInRing()rather than a GEOS operation, because it has to work on invalid geometries too. Rings that are outside their shell are taken out of the polygon, turned around into land polygons of their own, and reported in theerror_linestable with the errordirection(the same error the existing direction fix uses). They are counted innum_rings_turned_around.While at it, invalid polygons that are not part of a multipolygon are now repaired in the same way as those that are (report an
invaliderror line and tryBuffer(0)), instead of just being dropped.Tests
invalid-direction-island-in-bbox— reversed island inside the bounding box of an L-shaped landmass (single polygon code path).invalid-direction-island-in-bbox-of-many— the same with a second, correctly mapped island, soorganizePolygons()returns a multipolygon (the code path hit by the case in Reversed coastline results in "Hole lies outside shell" output #41).valid-inland-sea-with-islandneeded updating: the island in the inland sea is mapped hole-style and so ends up nested inside the hole formed by the sea ("Holes are nested"). That polygon is now repaired instead of discarded, so the land polygon survives and the result is a warning rather than an error. The island itself is still dropped and reported asquestionable; that nested-hole limitation is unchanged.