129 lines
4.4 KiB
Python
129 lines
4.4 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from uuid import uuid4
|
|
|
|
from app.models import Dataset
|
|
from app.schemas.operations import VectorSelectionSummary
|
|
from app.services.vector_feature_service import VectorFeatureService
|
|
|
|
|
|
ROOT = Path(__file__).parents[2]
|
|
BBOX = {"min_x": 5.0, "min_y": 51.1, "max_x": 5.2, "max_y": 51.3, "crs": "EPSG:4326"}
|
|
|
|
|
|
class ScalarQuery:
|
|
def __init__(self, value: float):
|
|
self.value = value
|
|
|
|
def filter(self, *args): # noqa: ANN002, ARG002
|
|
return self
|
|
|
|
def scalar(self):
|
|
return self.value
|
|
|
|
|
|
class SequenceScalarSession:
|
|
def __init__(self, values: list[float]):
|
|
self.values = iter(values)
|
|
|
|
def query(self, *args): # noqa: ANN002, ARG002
|
|
return ScalarQuery(next(self.values))
|
|
|
|
|
|
def themed_dataset(theme: str, *, method: str = "feature_count") -> Dataset:
|
|
return Dataset(
|
|
id=uuid4(),
|
|
project_id=uuid4(),
|
|
name=f"regional-{theme}.geojson",
|
|
dataset_type="vector",
|
|
dataset_role="reference",
|
|
source_name="grb",
|
|
reference_layer_name=theme,
|
|
source_metadata={
|
|
"theme": theme,
|
|
"selection_aggregation": {
|
|
"method": method,
|
|
"label": theme.title(),
|
|
"unit": "objecten",
|
|
},
|
|
},
|
|
)
|
|
|
|
|
|
def test_building_selection_promotes_footprint_area_and_retains_object_count() -> None:
|
|
result = VectorFeatureService.summarize_features_by_bbox(
|
|
SequenceScalarSession([125_000.0]),
|
|
dataset=themed_dataset("buildings"),
|
|
bbox=BBOX,
|
|
total_feature_count=40,
|
|
)
|
|
|
|
assert result["primary_metric_key"] == "footprint_area"
|
|
assert result["metric_label"] == "Bebouwde grondoppervlakte"
|
|
assert result["metric_value"] == 12.5
|
|
assert result["metric_unit"] == "ha"
|
|
assert [(item["metric_key"], item["metric_value"]) for item in result["metrics"]] == [
|
|
("footprint_area", 12.5),
|
|
("feature_count", 40.0),
|
|
]
|
|
assert "niet de totale vloeroppervlakte" in result["warning"]
|
|
VectorSelectionSummary(**result)
|
|
|
|
|
|
def test_water_selection_reports_surface_length_and_honest_volume_limitation() -> None:
|
|
result = VectorFeatureService.summarize_features_by_bbox(
|
|
SequenceScalarSession([52_500.0, 12_750.0]),
|
|
dataset=themed_dataset("water"),
|
|
bbox=BBOX,
|
|
total_feature_count=23,
|
|
)
|
|
|
|
assert result["metric_value"] == 5.25
|
|
assert result["metric_unit"] == "ha"
|
|
assert [(item["metric_key"], item["metric_value"], item["metric_unit"]) for item in result["metrics"]] == [
|
|
("water_area", 5.25, "ha"),
|
|
("watercourse_length", 12.75, "km"),
|
|
("feature_count", 23.0, "objecten"),
|
|
]
|
|
assert "Watervolume is niet berekenbaar" in result["warning"]
|
|
|
|
|
|
def test_population_keeps_configured_metric_and_adds_sector_count() -> None:
|
|
dataset = themed_dataset("population", method="sum")
|
|
dataset.source_metadata["selection_aggregation"].update(
|
|
{"metric_key": "population", "property": "population_total", "label": "Inwoners", "unit": "inwoners"}
|
|
)
|
|
result = VectorFeatureService.summarize_features_by_bbox(
|
|
SequenceScalarSession([86_458.0]),
|
|
dataset=dataset,
|
|
bbox=BBOX,
|
|
total_feature_count=733,
|
|
)
|
|
|
|
assert result["primary_metric_key"] == "population"
|
|
assert result["metric_value"] == 86_458.0
|
|
assert result["metrics"][1] == {
|
|
"metric_key": "feature_count",
|
|
"metric_label": "Statistische sectoren",
|
|
"metric_value": 733.0,
|
|
"metric_unit": "objecten",
|
|
"aggregation_method": "feature_count",
|
|
"is_estimate": False,
|
|
"warning": None,
|
|
}
|
|
|
|
|
|
def test_future_regional_imports_persist_semantic_aggregation_configuration() -> None:
|
|
buildings = (ROOT / "scripts/provision_regional_grb_buildings.py").read_text(encoding="utf-8")
|
|
context = (ROOT / "scripts/provision_regional_grb_context.py").read_text(encoding="utf-8")
|
|
frontend = (ROOT / "frontend/src/components/map/MapWorkspace.tsx").read_text(encoding="utf-8")
|
|
|
|
assert '"method": "intersection_area"' in buildings
|
|
assert '"label": "Bebouwde grondoppervlakte"' in buildings
|
|
assert 'metric_method="intersection_length"' in context
|
|
assert 'metric_label="Wateroppervlakte"' in context
|
|
assert 'metric_label="Perceeloppervlakte"' in context
|
|
assert 'aria-label="Aanvullende gebiedsmetingen"' in frontend
|
|
assert "activeSelectionResult.summary.warning" in frontend
|