Complete regional history live validation
This commit is contained in:
@@ -19,6 +19,19 @@
|
|||||||
feature limits and one canonical regional Dataset upload per theme/year.
|
feature limits and one canonical regional Dataset upload per theme/year.
|
||||||
- Extended the regional time-series coordinator and release packaging without
|
- Extended the regional time-series coordinator and release packaging without
|
||||||
changing API contracts, database migrations or frontend architecture.
|
changing API contracts, database migrations or frontend architecture.
|
||||||
|
- Provisioned all nine snapshots on live Tower/PostGIS: 207,717 persisted
|
||||||
|
polygon features across three complete 28-municipality temporal series.
|
||||||
|
Every Dataset is ready, has one immutable DatasetVersion and was reused by
|
||||||
|
the idempotency run without duplicate persistence.
|
||||||
|
- Added the exact-area fast path for these already-clipped regional artifacts,
|
||||||
|
reducing complete-Kempen comparisons from minutes to 0.9-4.1 seconds in the
|
||||||
|
live audit while preserving the calculated values.
|
||||||
|
- Suppressed inapplicable generic line metrics for historical polygon classes;
|
||||||
|
results now show governed hectares plus object counts, never artificial
|
||||||
|
`0 km` road/watercourse measurements.
|
||||||
|
- Kept the top workbench source context synchronized with the selected
|
||||||
|
Evolution series. Browser verification covered complete Kempen, Mol and a
|
||||||
|
3440 x 1440 viewport with no console warnings or errors.
|
||||||
|
|
||||||
## Sprint 208 Governed VMM flood-hazard scenarios (2026-07-15)
|
## Sprint 208 Governed VMM flood-hazard scenarios (2026-07-15)
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ def test_long_context_names_remain_compact_and_inspectable() -> None:
|
|||||||
|
|
||||||
assert "selectedProject?.name === REGIONAL_WORKSPACE_PROJECT_NAME" in app
|
assert "selectedProject?.name === REGIONAL_WORKSPACE_PROJECT_NAME" in app
|
||||||
assert "? REGIONAL_WORKSPACE_LABEL" in app
|
assert "? REGIONAL_WORKSPACE_LABEL" in app
|
||||||
assert "const datasetContextLabel = analysisMapLayerActive && mapFeatureCollection" in app
|
assert "const datasetContextLabel = activeWorkspace === 'map' && mapContextSourceLabel" in app
|
||||||
|
assert ": analysisMapLayerActive && mapFeatureCollection" in app
|
||||||
assert "? getDatasetDisplayName(selectedDataset)" in app
|
assert "? getDatasetDisplayName(selectedDataset)" in app
|
||||||
assert "`${mapLayerLabel} · controle vereist`" in app
|
assert "`${mapLayerLabel} · controle vereist`" in app
|
||||||
assert "<strong title={projectContextLabel}>{projectContextLabel}</strong>" in app
|
assert "<strong title={projectContextLabel}>{projectContextLabel}</strong>" in app
|
||||||
|
|||||||
@@ -239,6 +239,10 @@ def test_upload_contract_is_regional_temporal_and_partition_audited(tmp_path: Pa
|
|||||||
def test_regional_historical_operator_is_packaged_and_release_checked() -> None:
|
def test_regional_historical_operator_is_packaged_and_release_checked() -> None:
|
||||||
dockerfile = (ROOT / "deploy/unraid/Dockerfile.all-in-one").read_text(encoding="utf-8")
|
dockerfile = (ROOT / "deploy/unraid/Dockerfile.all-in-one").read_text(encoding="utf-8")
|
||||||
readiness = (ROOT / "scripts/run_readiness_check.sh").read_text(encoding="utf-8")
|
readiness = (ROOT / "scripts/run_readiness_check.sh").read_text(encoding="utf-8")
|
||||||
|
app = (ROOT / "frontend/src/App.tsx").read_text(encoding="utf-8")
|
||||||
|
workspace = (ROOT / "frontend/src/components/map/MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||||
|
|
||||||
assert "COPY scripts/provision_regional_historical_landuse.py" in dockerfile
|
assert "COPY scripts/provision_regional_historical_landuse.py" in dockerfile
|
||||||
assert "py_compile scripts/provision_regional_historical_landuse.py" in readiness
|
assert "py_compile scripts/provision_regional_historical_landuse.py" in readiness
|
||||||
|
assert "onSetContextSourceLabel={setMapContextSourceLabel}" in app
|
||||||
|
assert "analysisMode === 'evolution' ? activeTemporalSeriesGroup?.label" in workspace
|
||||||
|
|||||||
@@ -8833,12 +8833,39 @@ Implemented:
|
|||||||
- Extended `provision_regional_timeseries.py`, all-in-one packaging, readiness
|
- Extended `provision_regional_timeseries.py`, all-in-one packaging, readiness
|
||||||
compilation and operator/source documentation.
|
compilation and operator/source documentation.
|
||||||
|
|
||||||
Validation evidence before live provisioning:
|
Validation and live evidence:
|
||||||
- Fourteen focused partition, raw-evidence, clipping, assembly, upload,
|
- The final release gate passes with 685 backend tests, frontend typecheck and
|
||||||
coordinator and packaging tests pass.
|
production build, one Alembic head (`202607150001`) and script syntax checks.
|
||||||
- The official source catalog still reports the production WFS and the three
|
- Live Tower/PostGIS provisioning completed all 252 municipality/theme/year
|
||||||
governed historical collections. Live partition provisioning and browser
|
partitions and nine combined snapshots. No snapshot has an empty municipal
|
||||||
Evolution validation follow in this pass.
|
partition. The retained regional historical audit cache is about 518 MB.
|
||||||
|
- Persisted feature counts are: buildings 14,245 / 22,036 / 69,869; water
|
||||||
|
9,010 / 13,571 / 8,188; roads 6,305 / 33,578 / 30,915 for 1778 / 1873 /
|
||||||
|
1969 respectively. Total persisted geometry count is 207,717.
|
||||||
|
- Each of the nine ready Datasets belongs to regional Area
|
||||||
|
`46ab5614-fcf8-4e63-8ea8-6049f34c14fd`, exposes one immutable
|
||||||
|
DatasetVersion/checksum and participates in one of three ordered temporal
|
||||||
|
series. A second complete operator run returned `existing` for all nine with
|
||||||
|
identical audited feature counts.
|
||||||
|
- The live audit found that the full-Area fast path did not yet recognize the
|
||||||
|
new clipped operator. Adding its governed provenance reduced exact complete-
|
||||||
|
Kempen comparisons from multi-minute redundant clipping to 4.0 s for
|
||||||
|
buildings, 0.9 s for water and 1.9 s for roads.
|
||||||
|
- Complete-Kempen 1778 -> 1969 results are 481.62 -> 1,833.23 ha built land,
|
||||||
|
1,546.89 -> 2,198.80 ha mapped water and 4,382.49 -> 6,978.12 ha mapped
|
||||||
|
roads. These are map-class surfaces, not modern footprints, centreline
|
||||||
|
lengths, bathymetry or volume.
|
||||||
|
- Browser validation selected the historical buildings series, analyzed the
|
||||||
|
complete persisted Kempen Area and then municipality Mol. Mol returned
|
||||||
|
24.35 / 32.45 / 120.81 ha for 1778 / 1873 / 1969 and explicitly disclosed
|
||||||
|
the cartographic-method and unstable-object-identity limitations.
|
||||||
|
- The irrelevant generic `0 km` metrics for polygon-only historical water and
|
||||||
|
road classes were removed. The workbench source context now follows the
|
||||||
|
selected Evolution series. Normal and 3440 x 1440 visual checks found no
|
||||||
|
overlap; browser console warnings/errors were empty.
|
||||||
|
- Each deployment passed live PostGIS 3.6 connectivity, required schema/index
|
||||||
|
checks, database collation, Alembic head `202607150001`, frontend/API proxy
|
||||||
|
and icon verification.
|
||||||
|
|
||||||
Known limitations:
|
Known limitations:
|
||||||
- Historical `buildings` are mapped built land-use surfaces, not individual
|
- Historical `buildings` are mapped built land-use surfaces, not individual
|
||||||
@@ -8849,6 +8876,7 @@ Known limitations:
|
|||||||
continuous equivalent to modern GRB or 10 m land-use products.
|
continuous equivalent to modern GRB or 10 m land-use products.
|
||||||
|
|
||||||
Next:
|
Next:
|
||||||
- Run the complete nine-snapshot operator on live Tower/PostGIS, verify all 28
|
- Keep permanent inland bathymetry blocked on a governed depth source. The
|
||||||
partition manifests and then validate regional/municipality Evolution in the
|
next implementation pass can focus on current-only nature/terrain/flood
|
||||||
browser before marking the backlog item complete.
|
regional expansion or on a benchmarked data-refresh scheduler; it must not
|
||||||
|
reinterpret these historical surfaces as modern object lineage.
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@
|
|||||||
- [x] Add bounded historical orthophoto acquisition for official 1971-2025 products with a map overlay and no current-GRB QA on old imagery.
|
- [x] Add bounded historical orthophoto acquisition for official 1971-2025 products with a map overlay and no current-GRB QA on old imagery.
|
||||||
- [x] Add BWK/Natura 2000 through an explicit provider/operator contract.
|
- [x] Add BWK/Natura 2000 through an explicit provider/operator contract.
|
||||||
- [x] Add annual agricultural-use parcels through an explicit provider/operator contract.
|
- [x] Add annual agricultural-use parcels through an explicit provider/operator contract.
|
||||||
- [ ] Extend the official 1778/1873/1969 historical buildings, water and roads series from Mol to the approved regional scope with partitioned source audits.
|
- [x] Extend the official 1778/1873/1969 historical buildings, water and roads series from Mol to the approved regional scope with partitioned source audits.
|
||||||
- [x] Connect a drawn rectangle to bounded official orthophoto acquisition, local configured-YOLO detection and persisted GRB QA.
|
- [x] Connect a drawn rectangle to bounded official orthophoto acquisition, local configured-YOLO detection and persisted GRB QA.
|
||||||
|
|
||||||
## Governed source expansion backlog
|
## Governed source expansion backlog
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ selectable and is never merged into the same trend.
|
|||||||
Regional building, water and road evolution uses the same selector after the
|
Regional building, water and road evolution uses the same selector after the
|
||||||
partition-audited 1778/1873/1969 snapshots are provisioned. Historical built
|
partition-audited 1778/1873/1969 snapshots are provisioned. Historical built
|
||||||
surfaces never replace current GRB building footprints in Latest state.
|
surfaces never replace current GRB building footprints in Latest state.
|
||||||
|
The persistent top context bar follows the selected historical series while
|
||||||
|
Evolution is active, so its source label cannot disagree with the result panel.
|
||||||
|
Because these historical WFS classes are polygonal map surfaces, their metrics
|
||||||
|
are hectares plus a supporting object count; generic live road/water line
|
||||||
|
metrics are deliberately not shown.
|
||||||
|
|
||||||
Selection results use dataset-specific PostGIS summaries with end-user units.
|
Selection results use dataset-specific PostGIS summaries with end-user units.
|
||||||
Building footprints, forest, water surfaces and parcels show intersected
|
Building footprints, forest, water surfaces and parcels show intersected
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ function App(): JSX.Element {
|
|||||||
const [activeWorkspace, setActiveWorkspace] = useState<WorkspaceKey>('map')
|
const [activeWorkspace, setActiveWorkspace] = useState<WorkspaceKey>('map')
|
||||||
const [inspectorOpen, setInspectorOpen] = useState(false)
|
const [inspectorOpen, setInspectorOpen] = useState(false)
|
||||||
const [mapContentMode, setMapContentMode] = useState<'dataset' | 'analysis'>('dataset')
|
const [mapContentMode, setMapContentMode] = useState<'dataset' | 'analysis'>('dataset')
|
||||||
|
const [mapContextSourceLabel, setMapContextSourceLabel] = useState<string | null>(null)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.scrollTo({ top: 0, left: 0 })
|
window.scrollTo({ top: 0, left: 0 })
|
||||||
setInspectorOpen(false)
|
setInspectorOpen(false)
|
||||||
@@ -715,7 +716,9 @@ function App(): JSX.Element {
|
|||||||
? REGIONAL_WORKSPACE_LABEL
|
? REGIONAL_WORKSPACE_LABEL
|
||||||
: selectedProject?.name ?? 'Geen werkruimte'
|
: selectedProject?.name ?? 'Geen werkruimte'
|
||||||
const areaContextLabel = selectedArea?.name ?? (areas.length > 0 ? 'Kies een gebied' : 'Geen gebied')
|
const areaContextLabel = selectedArea?.name ?? (areas.length > 0 ? 'Kies een gebied' : 'Geen gebied')
|
||||||
const datasetContextLabel = analysisMapLayerActive && mapFeatureCollection
|
const datasetContextLabel = activeWorkspace === 'map' && mapContextSourceLabel
|
||||||
|
? mapContextSourceLabel
|
||||||
|
: analysisMapLayerActive && mapFeatureCollection
|
||||||
? `${mapLayerLabel} · controle vereist`
|
? `${mapLayerLabel} · controle vereist`
|
||||||
: selectedDataset
|
: selectedDataset
|
||||||
? getDatasetDisplayName(selectedDataset)
|
? getDatasetDisplayName(selectedDataset)
|
||||||
@@ -1035,6 +1038,7 @@ function App(): JSX.Element {
|
|||||||
selectedMapDatasetId={selectedDataset && availableMapDatasets.some((dataset) => dataset.id === selectedDataset.id) ? selectedDataset.id : ''}
|
selectedMapDatasetId={selectedDataset && availableMapDatasets.some((dataset) => dataset.id === selectedDataset.id) ? selectedDataset.id : ''}
|
||||||
selectedFeature={selectedMapFeature}
|
selectedFeature={selectedMapFeature}
|
||||||
onSelectMapArea={setSelectedMapAreaId}
|
onSelectMapArea={setSelectedMapAreaId}
|
||||||
|
onSetContextSourceLabel={setMapContextSourceLabel}
|
||||||
onOpenDatasetInMap={openDatasetInMap}
|
onOpenDatasetInMap={openDatasetInMap}
|
||||||
onSetAreaLayerVisible={setAreaLayerVisible}
|
onSetAreaLayerVisible={setAreaLayerVisible}
|
||||||
onSetAreaLayerOpacity={setAreaLayerOpacity}
|
onSetAreaLayerOpacity={setAreaLayerOpacity}
|
||||||
|
|||||||
@@ -559,6 +559,7 @@ interface MapWorkspaceProps {
|
|||||||
availableMapDatasets: DatasetCreateResponse[]
|
availableMapDatasets: DatasetCreateResponse[]
|
||||||
selectedMapDatasetId: string
|
selectedMapDatasetId: string
|
||||||
onSelectMapArea: (areaId: string) => void
|
onSelectMapArea: (areaId: string) => void
|
||||||
|
onSetContextSourceLabel: (label: string | null) => void
|
||||||
onOpenDatasetInMap: (dataset: DatasetCreateResponse) => void
|
onOpenDatasetInMap: (dataset: DatasetCreateResponse) => void
|
||||||
onSetAreaLayerVisible: (visible: boolean) => void
|
onSetAreaLayerVisible: (visible: boolean) => void
|
||||||
onSetAreaLayerOpacity: (opacity: number) => void
|
onSetAreaLayerOpacity: (opacity: number) => void
|
||||||
@@ -639,6 +640,7 @@ export function MapWorkspace({
|
|||||||
availableMapDatasets,
|
availableMapDatasets,
|
||||||
selectedMapDatasetId,
|
selectedMapDatasetId,
|
||||||
onSelectMapArea,
|
onSelectMapArea,
|
||||||
|
onSetContextSourceLabel,
|
||||||
onOpenDatasetInMap,
|
onOpenDatasetInMap,
|
||||||
onSetAreaLayerVisible,
|
onSetAreaLayerVisible,
|
||||||
onSetAreaLayerOpacity,
|
onSetAreaLayerOpacity,
|
||||||
@@ -776,6 +778,14 @@ export function MapWorkspace({
|
|||||||
const activeTemporalSeriesGroup = activeTemporalSeriesGroups.find((group) => group.key === selectedTemporalSeriesKey)
|
const activeTemporalSeriesGroup = activeTemporalSeriesGroups.find((group) => group.key === selectedTemporalSeriesKey)
|
||||||
?? activeTemporalSeriesGroups[0]
|
?? activeTemporalSeriesGroups[0]
|
||||||
const activeTemporalSeries = activeTemporalSeriesGroup?.items ?? EMPTY_TEMPORAL_SERIES
|
const activeTemporalSeries = activeTemporalSeriesGroup?.items ?? EMPTY_TEMPORAL_SERIES
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
onSetContextSourceLabel(
|
||||||
|
analysisMode === 'evolution' ? activeTemporalSeriesGroup?.label ?? null : null,
|
||||||
|
)
|
||||||
|
return () => onSetContextSourceLabel(null)
|
||||||
|
}, [activeTemporalSeriesGroup?.label, analysisMode, onSetContextSourceLabel])
|
||||||
|
|
||||||
const themeResults = useMemo(
|
const themeResults = useMemo(
|
||||||
() =>
|
() =>
|
||||||
themeInsights.flatMap((insight) => {
|
themeInsights.flatMap((insight) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user