Repository navigation
Description
Before you start
- I searched the existing issues and the roadmap and did not find a duplicate request.
What problem does this solve?
Repair Geometry (#1443) has one way to fix a polygon: each part is its shell minus its holes, and
overlapping parts merge. That's right most of the time, but not always. Sometimes the
data means something else, and the valid result isn't the one the user wanted:
- A shapefile hole listed under the wrong part is treated as a separate part and filled, so the
hole is lost. - Overlapping parts are merged, but in some data an overlap should be cut out, which is what
other tools call "linework" repair.
Right now there's no way to choose, or to see which features would come out differently.
Proposed solution
Three small PRs, each useful on its own:
- Groundwork, no change in behavior. Add Check Geometry and Repair Geometry to the cancel
test (long_commands_stop_when_cancelled_while_they_run; they're missing), and add tests that
pin today's output. - A
ruleparameter on Repair Geometry: "Shells Minus Holes" (today's, the default, same
output byte for byte) or "Even-Odd".- Even-Odd runs on the overlay
repair.rsalready uses (FillRule::EvenOdd), within the same
work and memory limits. - Duplicate rings are removed first, within the same role. Otherwise a duplicated part cancels
out and disappears. - A ring that Even-Odd would cancel completely falls back to the default rule.
- Each change gets a notice with a count, and
repairsgets aneven_oddcode on those runs. - The user guide explains both rules with an example.
- Even-Odd runs on the overlay
- A Compare Repairs tool (read-only, Data Management › Features). It writes one row per
invalid feature: the area under each rule, the area added or removed in m², parts, holes, and
whether the rules disagree. The AI Assistant can then read that table, suggest a rule for the
layer and say what it will change, and run Repair Geometry once the user agrees.
No new button; no new dependency. Crates: rustgis-analysis, plus tests in rustgis-engine and
the docs. Both tools run in the background with progress and Cancel, checking Cancel per feature.
Tests cover bowties, overlapping parts, holes outside or crossing their shell, a hole listed under
the wrong part, duplicates, spikes, the two ST_MakeValid examples in the PostGIS manual, hostile
parameters, lossy and clean notices, and the wasm build.
One question first: gp.run and saved models ignore a parameter they don't know, without a
notice. So an older RustGIS would run a saved "rule": "Even-Odd" with the default rule and say
nothing. I'd like to send a small PR before this one so unknown parameters get a notice. Is that
OK, or would you rather handle it another way?
Estimated scope
Medium: a broader feature that is feasible in a reasonable timeframe
Alternatives considered
- geo 0.33's
MakeValid. I tested it in lon/lat and can't use it yet. It snaps within a fixed
0.0001 units, which is about 11 m in degrees (MakeValid snaps within an absolute 1e-4, emptying small valid polygons in geographic coordinates georust/geo#1640, fix in feat(plugins): a panel pick asks for a point or a box on the map (#1623) #1643). It also sometimes
puts a hole in the wrong part, so the result isn't valid. - Non-zero winding over every ring, and an "intersection" rule. I left both out: non-zero depends
on ring direction, which differs between Shapefile and GeoJSON, and intersection empties every
valid multipart feature. - A new repair engine of our own. Not needed for this; the existing overlay does it.
Activity