Normalize area geometries to two dimensions
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-18 02:01:11 +02:00
parent ec3e7a4fa8
commit 3f7b90f009
4 changed files with 30 additions and 1 deletions
+2
View File
@@ -64,6 +64,8 @@
the full readiness gate, one Alembic head and complete offline migration SQL.
- Fixed fail-closed AdminVector GeoJSON serialization for Pandas timestamp
properties exposed by the live NGI GeoPackage.
- Hardened shared AOI geometry normalization to persist valid 2D polygons when
an authoritative source supplies harmless zero-valued Z coordinates.
## Sprint 240 Operational forest, agriculture, nature and soil themes (2026-07-17)
+2 -1
View File
@@ -3,13 +3,14 @@ from __future__ import annotations
from typing import Any
from pyproj import Transformer
from shapely import force_2d
from shapely.geometry import GeometryCollection, MultiPolygon, Polygon, box, shape
from shapely.ops import transform
from shapely.validation import make_valid
def normalize_to_multipolygon(raw_geometry: dict[str, Any]) -> MultiPolygon:
geom = shape(raw_geometry)
geom = force_2d(shape(raw_geometry))
if geom.is_empty:
raise ValueError("Geometry is empty")
@@ -15,6 +15,7 @@ if str(SCRIPTS) not in sys.path:
sys.path.insert(0, str(SCRIPTS))
import provision_belgium_north_sea_scope as operator # noqa: E402
from app.utils.geometry import normalize_to_multipolygon # noqa: E402
def marine_feature(identifier: str, geometry):
@@ -77,6 +78,26 @@ def test_marine_scope_derivation_fails_when_a_required_unit_is_missing() -> None
)
def test_area_geometry_normalization_drops_source_z_dimension() -> None:
geometry = normalize_to_multipolygon(
{
"type": "Polygon",
"coordinates": [
[
[2.5, 49.5, 0],
[6.4, 49.5, 0],
[6.4, 51.5, 0],
[2.5, 51.5, 0],
[2.5, 49.5, 0],
]
],
}
)
assert geometry.has_z is False
assert geometry.geom_type == "MultiPolygon"
def test_archive_extraction_accepts_one_safe_geopackage_and_rejects_traversal(tmp_path: Path) -> None:
archive = tmp_path / "adminvector.zip"
with zipfile.ZipFile(archive, "w") as handle:
+5
View File
@@ -30,6 +30,11 @@
serialization was corrected to explicit string conversion and guarded by a
regression assertion; downloaded source artifacts remain operator cache
only.
- The corrected Tower fetch-only run validated all seven generated artifacts
and 101 current MSP 2026 features. The first API persistence run then exposed
a separate live-only PostGIS constraint: AdminVector AOI boundaries carry a
zero-valued Z coordinate while `areas.geometry` is intentionally 2D.
Shared AOI normalization now removes Z before validation and persistence.
- Froze the RC geography as all Belgian land plus the separately labelled
territorial sea, EEZ and continental shelf.