feat: synchronize regional official time series
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-14 22:19:30 +02:00
parent cfd13307e4
commit a5b4bbdf8f
14 changed files with 609 additions and 51 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
React + TypeScript + MapLibre workbench for regional geographic analysis.
The persisted `Kempen Regional Workbench` is the automatic operational data context. Its current GRB layers are loaded once for the complete official 28-municipality Vlaamse vervoerregio; the operator chooses Mol, another municipality or the complete region as a spatial work-area filter. The primary map no longer asks the user to choose a technical project or region before data becomes usable. Mol remains the primary validation and historical-data focus, while explicit project selection stays available under advanced management.
The persisted `Kempen Regional Workbench` is the automatic operational data context. Its datasets are loaded once for the complete official 28-municipality Vlaamse vervoerregio; the operator chooses Mol, another municipality or the complete region as a spatial work-area filter. The primary map no longer asks the user to choose a technical project or region before data becomes usable. Regional population and modern forest snapshots use the same current/evolution flow as Mol, while explicit project selection stays available under advanced management.
The user-facing shell is task based: `Kaart`, `Bronnen`, `Kwaliteit`, `Beeldanalyse`, `Downloads`, `Status` and `Beheer`. Internal benchmark projects, raw dataset metadata, provider capabilities, model registry details and QA evidence remain accessible through labelled advanced disclosures instead of competing with the normal workflow.
+3 -3
View File
@@ -4,7 +4,7 @@ import type { AreaRead, DatasetCreateResponse, MapViewportState, ProjectRead, Qa
import { featureCollectionBounds } from '../../lib/geojsonBounds'
import { useMapThemeSelectionInsights } from '../../hooks/useMapThemeSelectionInsights'
import { useTemporalComparison } from '../../hooks/useTemporalComparison'
import { getDatasetDisplayName } from '../../lib/datasetDisplay'
import { getDatasetDisplayName, getDatasetSourceDisplayName } from '../../lib/datasetDisplay'
const DEFAULT_SELECTED_FEATURE_FILENAME = 'selected-feature.geojson'
const DEFAULT_AREA_SELECTION_FILENAME = 'area-selection.geojson'
@@ -998,7 +998,7 @@ export function MapWorkspace({
? `${activeTemporalSeries.length} officiële meetmomenten · ${formatObservationDate(activeTemporalSeries[0].observed_at)} tot ${formatObservationDate(activeTemporalSeries[activeTemporalSeries.length - 1].observed_at)}`
: 'Minstens twee expliciet gedateerde snapshots zijn vereist.'
: activeThemeDataset
? `${activeThemeDataset.source_name ?? activeThemeDataset.source} · ${activeThemeDataset.dataset_role ?? 'source'} · ${formatObservationDate(activeThemeDataset.observed_at)}`
? `${getDatasetSourceDisplayName(activeThemeDataset)} · ${formatObservationDate(activeThemeDataset.observed_at)}`
: activeTheme.description}
</small>
</div>
@@ -1247,7 +1247,7 @@ export function MapWorkspace({
<span className={`geo-theme-symbol geo-theme-symbol-${theme.id}`} aria-hidden="true" />
<span>
<strong>{theme.label}</strong>
<small>{dataset?.source_name ?? dataset?.source ?? 'Geen bron gekoppeld'}</small>
<small>{dataset ? getDatasetSourceDisplayName(dataset) : 'Geen bron gekoppeld'}</small>
</span>
<b>{item ? resultMetricLabel(item.result) : dataset ? 'Niet bevraagd' : 'Bron ontbreekt'}</b>
</div>
+13 -1
View File
@@ -11,6 +11,18 @@ const DATASET_LABEL_BY_LAYER: Record<string, string> = {
municipality_boundaries: 'Gemeentegrenzen Kempen',
}
const DATASET_SOURCE_LABELS: Record<string, string> = {
department_omgeving_land_use: 'Departement Omgeving',
grb: 'GRB',
statbel: 'Statbel',
vrbg: 'Digitaal Vlaanderen',
}
export function getDatasetSourceDisplayName(dataset: DatasetCreateResponse): string {
const source = (dataset.source_name ?? dataset.source).toLowerCase()
return DATASET_SOURCE_LABELS[source] ?? dataset.source_name ?? dataset.source
}
export function getDatasetDisplayName(dataset: DatasetCreateResponse): string {
const layer = (dataset.reference_layer_name ?? dataset.source_metadata?.layer_name ?? dataset.source_metadata?.layer_type ?? '')
.toString()
@@ -19,6 +31,6 @@ export function getDatasetDisplayName(dataset: DatasetCreateResponse): string {
if (!label) {
return dataset.name
}
const source = (dataset.source_name ?? dataset.source).toUpperCase()
const source = getDatasetSourceDisplayName(dataset)
return `${label} · ${source}`
}