feat: merge multi-feature geometry input into a single polygon - #312
Open
dulcetberg wants to merge 1 commit into
Open
dulcetberg wants to merge 1 commit into
dulcetberg wants to merge 1 commit into
Conversation
Partially addresses hotosm#175. GeometryValidatorMixin.validate_geometry previously rejected any FeatureCollection with more than one feature outright ("Feature collection with multiple features is not supported yet"), forcing every upstream caller to pre-extract/merge geometries themselves before calling raw-data-api. Now, when a FeatureCollection has multiple Polygon/MultiPolygon features (still validated the same as before - non-polygon feature types are still rejected), they're merged via Shapely's unary_union and reduced to their convex hull, returned as a single Polygon. This is a deliberate simplification (per the approach @spwoodcock sketched in the issue thread) rather than generating extracts per-feature - the merged hull can enclose more area than the union of the inputs if features are far apart, which is documented in a code comment. Single-feature FeatureCollection, bare Feature, and bare Polygon/MultiPolygon inputs are all unchanged. Doesn't implement GeometryCollection support or the full geojson-aoi-parser integration also discussed in the issue - geojson-aoi-parser needs a live PostGIS connection internally, which isn't available at this synchronous Pydantic-validation layer without a bigger architectural change (passing DB access into validation, or moving validation later in the request flow). Scoping this PR to the Shapely-only approach that fits the existing validator, and leaving the DB-aware integration as a separate follow-up. Adds shapely as a new dependency (not previously used directly in this repo). Verified end-to-end against the real RawDataCurrentParamsBase model: multi-feature merge produces the expected convex-hull polygon; single-feature FeatureCollection, bare Feature, and bare Polygon inputs are all unchanged; a FeatureCollection containing a non-Polygon/MultiPolygon feature is still rejected. `pytest tests/test_app.py` passes (5 passed). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Brian Bergstrom <dulcetberg@gmail.com>
Member
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.
Summary
Partially addresses #175.
GeometryValidatorMixin.validate_geometrypreviously rejected anyFeatureCollectionwith more than one feature outright ("Feature collection with multiple features is not supported yet"), forcing every upstream caller to pre-extract/merge geometries themselves before callingraw-data-api.Now, when a
FeatureCollectionhas multiplePolygon/MultiPolygonfeatures (still validated the same as before — non-polygon feature types are still rejected), they're merged via Shapely'sunary_unionand reduced to their convex hull, returned as a singlePolygon. This is the approach @spwoodcock sketched in the issue thread — a deliberate simplification rather than generating extracts per-feature. The merged hull can enclose more area than the union of the inputs if features are far apart from each other; that's documented in a code comment at the call site.Single-feature
FeatureCollection, bareFeature, and barePolygon/MultiPolygoninputs are all unchanged.What this doesn't do
Doesn't implement
GeometryCollectionsupport or the fullgeojson-aoi-parserintegration also discussed in the issue.geojson-aoi-parserneeds a live PostGIS connection internally, which isn't available at this synchronous Pydantic-validation layer without a bigger architectural change (passing DB access into validation, or moving validation later in the request flow). Scoping this PR to the Shapely-only approach that fits the existing validator as-is, and leaving the DB-aware integration as a separate follow-up if it's wanted.Adds
shapelyas a new dependency (wasn't previously used directly in this repo).Test plan
RawDataCurrentParamsBasemodel: multi-feature merge produces the expected convex-hull polygon.FeatureCollection, bareFeature, and barePolygoninputs are all unchanged.FeatureCollectioncontaining a non-Polygon/MultiPolygon feature (e.g.LineString) is still rejected.pytest tests/test_app.pypasses (5 passed).🤖 Generated with Claude Code