Skip to content

Keep polygons when union_ loses area in combine_polygons_below - #985

Open
geoneutrino wants to merge 1 commit into
systemed:masterfrom
geoneutrino:fix/union-area-check
Open

geoneutrino wants to merge 1 commit into
systemed:masterfrom
geoneutrino:fix/union-area-check

Conversation

@geoneutrino

Copy link
Copy Markdown
Contributor

Boost.Geometry's union_ can drop one of two valid, non-overlapping polygons that share an edge along nearly collinear vertices, or return nothing, depending on the argument order: boostorg/geometry#1506. It happens with Boost 1.83 (the version in current Debian/Ubuntu) and still with 1.92 and develop in one of the two argument orders. The old rescaling, which avoided it, was removed in 1.87.

combine_polygons_below runs every polygon of a tile through union_near(), so a failing union_ removes whole polygons from the tile.

Change: union_near() checks the area of the union. If it is smaller than both inputs together minus their overlap, it retries with the arguments swapped, and if that fails too it keeps the polygons uncombined (exact when they don't overlap, which is the usual case for adjacent polygons). The overlap is only computed when the union is smaller than the sum of the inputs, so the normal path costs two area computations.

Measured (own profile, landuse/landcover combined below z14, --threads 1, geometry compared feature by feature):

master this PR
OSM test data A 2 landuse features lost most of their area (one -94 %) complete, all other geometry identical
OSM test data B – identical
Overture land cover cleaned into a coverage (z8 tile) whole forest polygons missing, 5.5 % of the tile uncovered 0.6 % (0.4 % without combining)
Runtime, one thread +0.9 % user time, wall clock unchanged
Runtime, all threads 50.1 s 50.3 s

New unit test test_union_many with the polygons from the Boost issue; it fails without the change.

Boost.Geometry's union_ can drop one of two valid polygons that share an edge
along nearly collinear vertices, or return nothing, depending on the argument
order (boostorg/geometry#1506; seen with 1.83, 1.87, 1.89, 1.92 and develop).
union_near() now checks the area of the result: if it is smaller than both
inputs together minus their overlap, it retries with the arguments swapped and
otherwise keeps the polygons uncombined. The overlap is only computed when the
union is smaller than the sum of the inputs, so the check is almost free.

On OpenStreetMap test data with a profile that combines landuse and landcover
below z14, two landuse features lost most of their area (one -94 %); they are
now complete, all other geometry is unchanged. On Overture land cover cleaned
into a coverage with many shared edges, whole forest polygons disappeared from
a z8 tile (5.5 % of the tile uncovered, 0.4 % without combining); with this
change 0.6 %.
Runtime with one thread +0.9 % user time, wall clock unchanged.
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.

1 participant