Add fail-closed source class and SAM fallback filters
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s

This commit is contained in:
Jens
2026-07-30 04:24:35 +02:00
parent 29378bba42
commit 08422ca50c
6 changed files with 74 additions and 4 deletions
@@ -166,6 +166,32 @@ def test_normalizer_rejects_same_year_feature_after_annual_mosaic_start(tmp_path
assert audit["imagery_feature_creation_cutoff"] == "2025-01-01T00:00:00+00:00"
def test_normalizer_applies_provider_native_source_class_allowlist(tmp_path: Path) -> None:
raster_path = tmp_path / "image.tif"
with rasterio.open(
raster_path, "w", driver="GTiff", width=100, height=100, count=3,
dtype="uint8", crs="EPSG:4326", transform=from_origin(4.0, 51.0, 0.001, 0.001),
) as dataset:
dataset.write(np.zeros((3, 100, 100), dtype="uint8"))
def feature(feature_id: str, source_type: int, left: float) -> dict:
return {
"type": "Feature", "id": feature_id, "properties": {"TYPE": source_type},
"geometry": {"type": "Polygon", "coordinates": [[[left, 50.99], [left + .01, 50.99], [left + .01, 50.98], [left, 50.98], [left, 50.99]]]},
}
reference_path = tmp_path / "reference.geojson"
reference_path.write_text(json.dumps({"type": "FeatureCollection", "features": [feature("main", 1, 4.01), feature("annex", 2, 4.03)]}), encoding="utf-8")
normalized, audit = module.normalize(
reference_path=reference_path, raster_path=raster_path, source_name="grb",
min_label_px=3, imagery_observed_at=None, reference_observed_at=None,
allowed_source_classes={"1"},
)
assert [item["id"] for item in normalized["features"]] == ["grb:main"]
assert audit["allowed_source_classes"] == ["1"]
assert audit["decision_counts"] == {"accepted": 1, "source_class_not_allowed": 1}
def test_normalizer_merges_only_touching_visible_roof_instances(tmp_path: Path) -> None:
raster_path = tmp_path / "image.tif"
with rasterio.open(