Optimize regional BWK municipality selection
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-16 00:44:28 +02:00
parent 6cb880c76e
commit bcbdaa10fc
3 changed files with 79 additions and 3 deletions
+8
View File
@@ -331,12 +331,19 @@ def select_vector_features(
"limit": payload.limit, "limit": payload.limit,
} }
full_dataset_area = False full_dataset_area = False
preclipped_partition_filter = None
if selection_area is not None: if selection_area is not None:
full_dataset_area = VectorFeatureService.can_use_full_area_fast_path(dataset, selection_area.id) full_dataset_area = VectorFeatureService.can_use_full_area_fast_path(dataset, selection_area.id)
if not full_dataset_area:
preclipped_partition_filter = VectorFeatureService.preclipped_partition_filter(
dataset,
getattr(selection_area, "name", None),
)
selection_kwargs.update( selection_kwargs.update(
selection_geometry=selection_area.geometry, selection_geometry=selection_area.geometry,
selection_area_id=selection_area.id, selection_area_id=selection_area.id,
full_dataset_area=full_dataset_area, full_dataset_area=full_dataset_area,
preclipped_partition_filter=preclipped_partition_filter,
) )
result = VectorFeatureService.select_features_by_bbox(db, **selection_kwargs) result = VectorFeatureService.select_features_by_bbox(db, **selection_kwargs)
if VectorFeatureService.supports_selection_summary(dataset): if VectorFeatureService.supports_selection_summary(dataset):
@@ -348,6 +355,7 @@ def select_vector_features(
if selection_area is not None: if selection_area is not None:
summary_kwargs["selection_geometry"] = selection_area.geometry summary_kwargs["selection_geometry"] = selection_area.geometry
summary_kwargs["full_dataset_area"] = full_dataset_area summary_kwargs["full_dataset_area"] = full_dataset_area
summary_kwargs["preclipped_partition_filter"] = preclipped_partition_filter
result["summary"] = VectorFeatureService.summarize_features_by_bbox(db, **summary_kwargs) result["summary"] = VectorFeatureService.summarize_features_by_bbox(db, **summary_kwargs)
return envelope(VectorSelectionResponse(**result).model_dump(exclude_none=True)) return envelope(VectorSelectionResponse(**result).model_dump(exclude_none=True))
+43 -3
View File
@@ -37,6 +37,10 @@ SEMANTIC_METRICS_DISABLED_OPERATOR_TOOLS = {
"provision_regional_historical_landuse.py", "provision_regional_historical_landuse.py",
} }
PRECLIPPED_MUNICIPALITY_PARTITION_OPERATOR_TOOLS = {
"provision_regional_bwk_natura2000.py",
}
SEMANTIC_SELECTION_METRICS: dict[str, tuple[dict[str, Any], ...]] = { SEMANTIC_SELECTION_METRICS: dict[str, tuple[dict[str, Any], ...]] = {
"buildings": ( "buildings": (
@@ -181,6 +185,30 @@ class VectorFeatureService:
provenance = dataset.provenance_metadata if isinstance(dataset.provenance_metadata, dict) else {} provenance = dataset.provenance_metadata if isinstance(dataset.provenance_metadata, dict) else {}
return provenance.get("operator_tool") in FULL_AREA_CLIPPED_OPERATOR_TOOLS return provenance.get("operator_tool") in FULL_AREA_CLIPPED_OPERATOR_TOOLS
@staticmethod
def preclipped_partition_filter(dataset: Dataset, selection_area_name: str | None) -> tuple[str, str] | None:
provenance = dataset.provenance_metadata if isinstance(dataset.provenance_metadata, dict) else {}
if provenance.get("operator_tool") not in PRECLIPPED_MUNICIPALITY_PARTITION_OPERATOR_TOOLS:
return None
source_metadata = dataset.source_metadata if isinstance(dataset.source_metadata, dict) else {}
if (
source_metadata.get("partitioned_source_audit") is not True
or source_metadata.get("geometry_clipped_to_area") is not True
):
return None
normalized_name = str(selection_area_name or "").strip()
prefix = "Gemeente "
suffixes = (" - officiële grens", " - officiele grens")
if not normalized_name.startswith(prefix):
return None
municipality = normalized_name[len(prefix):]
for suffix in suffixes:
if municipality.endswith(suffix):
municipality = municipality[: -len(suffix)]
break
municipality = municipality.strip()
return ("municipality", municipality) if municipality else None
@staticmethod @staticmethod
def _feature_row(dataset_id: UUID, feature: dict[str, Any], index: int, feature_class: str | None) -> VectorFeature | None: def _feature_row(dataset_id: UUID, feature: dict[str, Any], index: int, feature_class: str | None) -> VectorFeature | None:
geometry_payload = feature.get("geometry") geometry_payload = feature.get("geometry")
@@ -289,6 +317,7 @@ class VectorFeatureService:
selection_geometry: Any | None = None, selection_geometry: Any | None = None,
selection_area_id: UUID | None = None, selection_area_id: UUID | None = None,
full_dataset_area: bool = False, full_dataset_area: bool = False,
preclipped_partition_filter: tuple[str, str] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
normalized_bbox = VectorFeatureService._normalize_selection_bbox(bbox) normalized_bbox = VectorFeatureService._normalize_selection_bbox(bbox)
safe_limit = max(1, min(int(limit), 1000)) safe_limit = max(1, min(int(limit), 1000))
@@ -303,7 +332,10 @@ class VectorFeatureService:
) )
query = db.query(VectorFeature).filter(VectorFeature.dataset_id == dataset_id) query = db.query(VectorFeature).filter(VectorFeature.dataset_id == dataset_id)
if not full_dataset_area: if preclipped_partition_filter is not None:
partition_property, partition_value = preclipped_partition_filter
query = query.filter(VectorFeature.properties_json.op("->>")(partition_property) == partition_value)
elif not full_dataset_area:
query = query.filter(ST_Intersects(VectorFeature.geometry, selection_shape)) query = query.filter(ST_Intersects(VectorFeature.geometry, selection_shape))
if hasattr(query, "count"): if hasattr(query, "count"):
total_feature_count = int(query.count()) total_feature_count = int(query.count())
@@ -327,6 +359,7 @@ class VectorFeatureService:
total_feature_count=total_feature_count, total_feature_count=total_feature_count,
selection_geometry=selection_geometry, selection_geometry=selection_geometry,
full_dataset_area=full_dataset_area, full_dataset_area=full_dataset_area,
preclipped_partition_filter=preclipped_partition_filter,
) )
result = { result = {
@@ -354,6 +387,7 @@ class VectorFeatureService:
total_feature_count: int | None = None, total_feature_count: int | None = None,
selection_geometry: Any | None = None, selection_geometry: Any | None = None,
full_dataset_area: bool = False, full_dataset_area: bool = False,
preclipped_partition_filter: tuple[str, str] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
normalized_bbox = VectorFeatureService._normalize_selection_bbox(bbox) normalized_bbox = VectorFeatureService._normalize_selection_bbox(bbox)
selection_shape = selection_geometry selection_shape = selection_geometry
@@ -366,8 +400,14 @@ class VectorFeatureService:
4326, 4326,
) )
selection_filter = (VectorFeature.dataset_id == dataset.id,) selection_filter = (VectorFeature.dataset_id == dataset.id,)
if not full_dataset_area: if preclipped_partition_filter is not None:
partition_property, partition_value = preclipped_partition_filter
selection_filter += (
VectorFeature.properties_json.op("->>")(partition_property) == partition_value,
)
elif not full_dataset_area:
selection_filter += (ST_Intersects(VectorFeature.geometry, selection_shape),) selection_filter += (ST_Intersects(VectorFeature.geometry, selection_shape),)
selection_is_preclipped = full_dataset_area or preclipped_partition_filter is not None
feature_count = total_feature_count feature_count = total_feature_count
if feature_count is None: if feature_count is None:
feature_count = int(db.query(func.count(VectorFeature.id)).filter(*selection_filter).scalar() or 0) feature_count = int(db.query(func.count(VectorFeature.id)).filter(*selection_filter).scalar() or 0)
@@ -438,7 +478,7 @@ class VectorFeatureService:
selection_filter=selection_filter, selection_filter=selection_filter,
selection_shape=selection_shape, selection_shape=selection_shape,
feature_count=feature_count, feature_count=feature_count,
full_dataset_area=full_dataset_area, full_dataset_area=selection_is_preclipped,
) )
for metric_config in metric_configs for metric_config in metric_configs
] ]
@@ -9,6 +9,9 @@ import sys
import pytest import pytest
from shapely.geometry import box, mapping, shape from shapely.geometry import box, mapping, shape
from app.models import Dataset
from app.services.vector_feature_service import VectorFeatureService
ROOT = Path(__file__).resolve().parents[2] ROOT = Path(__file__).resolve().parents[2]
SCRIPTS = ROOT / "scripts" SCRIPTS = ROOT / "scripts"
@@ -240,3 +243,28 @@ def test_regional_operator_is_packaged_release_checked_and_exact_area_is_preferr
assert '"provision_regional_bwk_natura2000.py"' in service assert '"provision_regional_bwk_natura2000.py"' in service
assert "dataset.area_id === selectedAreaId ? 10_000_000" in workspace assert "dataset.area_id === selectedAreaId ? 10_000_000" in workspace
assert "largestBwkSnapshot" in catalog assert "largestBwkSnapshot" in catalog
def test_regional_bwk_uses_only_canonical_preclipped_municipality_partitions() -> None:
dataset = Dataset(
name="regional-bwk.geojson",
dataset_type="vector",
status="ready",
source_metadata={
"partitioned_source_audit": True,
"geometry_clipped_to_area": True,
},
provenance_metadata={"operator_tool": "provision_regional_bwk_natura2000.py"},
)
assert VectorFeatureService.preclipped_partition_filter(
dataset, "Gemeente Mol - officiële grens"
) == ("municipality", "Mol")
assert VectorFeatureService.preclipped_partition_filter(
dataset, "Vervoerregio Kempen - officiële operationele grens"
) is None
dataset.provenance_metadata = {"operator_tool": "unrelated_operator.py"}
assert VectorFeatureService.preclipped_partition_filter(
dataset, "Gemeente Mol - officiële grens"
) is None