Add governed buildings register snapshot
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-15 16:56:08 +02:00
parent 48c0d21fed
commit 553e457b26
16 changed files with 1779 additions and 20 deletions
@@ -108,6 +108,12 @@ export function SourceCatalogPanel({ datasets }: SourceCatalogPanelProps): JSX.E
)
const bwkDatasets = ready.filter((dataset) => dataset.source_name === 'inbo_bwk_natura2000')
const agricultureDatasets = ready.filter((dataset) => dataset.source_name === 'agentschap_landbouw_zeevisserij_agricultural_parcels')
const buildingsRegisterDatasets = ready.filter(
(dataset) => dataset.source_name === 'digitaal_vlaanderen_buildings_addresses_register',
)
const latestBuildingsRegister = [...buildingsRegisterDatasets].sort(
(left, right) => new Date(right.observed_at ?? 0).getTime() - new Date(left.observed_at ?? 0).getTime(),
)[0]
const agricultureYears = agricultureDatasets
.flatMap((dataset) => dataset.observed_at ? [new Date(dataset.observed_at).getUTCFullYear()] : [])
const pendingSources = AVAILABLE_SOURCES.filter((source) => {
@@ -115,6 +121,7 @@ export function SourceCatalogPanel({ datasets }: SourceCatalogPanelProps): JSX.E
if (source.key === 'historical_orthophoto') return historicalOrthophotos.length === 0
if (source.key === 'bwk') return bwkDatasets.length === 0
if (source.key === 'agriculture') return agricultureDatasets.length === 0
if (source.key === 'buildings_register') return buildingsRegisterDatasets.length === 0
return true
})
const themes = Object.keys(THEME_LABELS).map((theme) => {
@@ -174,7 +181,7 @@ export function SourceCatalogPanel({ datasets }: SourceCatalogPanelProps): JSX.E
))}
</div>
{waterinfoDatasets.length > 0 || historicalOrthophotos.length > 0 || bwkDatasets.length > 0 || agricultureDatasets.length > 0 ? (
{waterinfoDatasets.length > 0 || historicalOrthophotos.length > 0 || bwkDatasets.length > 0 || agricultureDatasets.length > 0 || buildingsRegisterDatasets.length > 0 ? (
<div className="source-catalog-loaded" aria-label="Aanvullende ingeladen bronnen">
{waterinfoDatasets.length > 0 ? (
<article>
@@ -204,6 +211,17 @@ export function SourceCatalogPanel({ datasets }: SourceCatalogPanelProps): JSX.E
<p>Oppervlakte en officiële hoofdteeltgroepen zijn historisch vergelijkbaar; perceelidentiteiten blijven bewust niet gekoppeld tussen jaren.</p>
</article>
) : null}
{latestBuildingsRegister ? (
<article>
<strong>Gebouwen- en Adressenregister</strong>
<span>
{(latestBuildingsRegister.feature_count ?? 0).toLocaleString('nl-BE')} gebouwen · {' '}
{Number(latestBuildingsRegister.source_metadata?.['building_unit_count'] ?? 0).toLocaleString('nl-BE')} eenheden · {' '}
{Number(latestBuildingsRegister.source_metadata?.['linked_address_count'] ?? 0).toLocaleString('nl-BE')} gekoppelde adressen
</span>
<p>Registerstatus en geaggregeerde koppelingen voor Mol; adreslabels en persoonsgegevens worden niet in de kaartlaag getoond.</p>
</article>
) : null}
</div>
) : null}
+20 -5
View File
@@ -120,8 +120,22 @@ function datasetMatchesTheme(dataset: DatasetCreateResponse, theme: DataTheme):
return theme.tokens.some((token) => searchText.includes(token))
}
function pickThemeDataset(datasets: DatasetCreateResponse[], theme: DataTheme): DatasetCreateResponse | null {
const candidates = datasets.filter((dataset) => datasetMatchesTheme(dataset, theme))
function datasetCoversSelectedArea(dataset: DatasetCreateResponse, selectedAreaId: string | null): boolean {
const coverageScope = String(dataset.source_metadata?.['coverage_scope'] ?? '')
if (coverageScope !== 'municipality' || !dataset.area_id) {
return true
}
return Boolean(selectedAreaId) && dataset.area_id === selectedAreaId
}
function pickThemeDataset(
datasets: DatasetCreateResponse[],
theme: DataTheme,
selectedAreaId: string | null,
): DatasetCreateResponse | null {
const candidates = datasets.filter(
(dataset) => datasetMatchesTheme(dataset, theme) && datasetCoversSelectedArea(dataset, selectedAreaId),
)
candidates.sort((left, right) => {
const score = (dataset: DatasetCreateResponse) =>
(dataset.reference_layer_name && theme.tokens.includes(dataset.reference_layer_name.toLowerCase()) ? 1_000_000 : 0) +
@@ -129,6 +143,7 @@ function pickThemeDataset(datasets: DatasetCreateResponse[], theme: DataTheme):
(dataset.source_name === 'department_omgeving_land_use' ? 90_000 : 0) +
(dataset.source_name === 'inbo_bwk_natura2000' ? 95_000 : 0) +
(dataset.source_name === 'agentschap_landbouw_zeevisserij_agricultural_parcels' ? 98_000 : 0) +
(dataset.source_name === 'digitaal_vlaanderen_buildings_addresses_register' ? 120_000 : 0) +
(dataset.dataset_role === 'reference' ? 10_000 : 0) +
(dataset.observed_at ? new Date(dataset.observed_at).getTime() / 100_000_000 : 0) +
(dataset.feature_count ?? dataset.vector_summary?.feature_count ?? 0)
@@ -636,9 +651,9 @@ export function MapWorkspace({
const themeDatasetMap = useMemo(
() =>
Object.fromEntries(
DATA_THEMES.map((theme) => [theme.id, pickThemeDataset(availableMapDatasets, theme)]),
DATA_THEMES.map((theme) => [theme.id, pickThemeDataset(availableMapDatasets, theme, selectedMapAreaId)]),
) as Record<DataThemeId, DatasetCreateResponse | null>,
[availableMapDatasets],
[availableMapDatasets, selectedMapAreaId],
)
const activeTheme = DATA_THEMES.find((theme) => theme.id === activeThemeId) ?? DATA_THEMES[0]
const activeThemeMapStyle = DATA_THEME_MAP_STYLES[activeTheme.id]
@@ -740,7 +755,7 @@ export function MapWorkspace({
}, [activeTemporalSeries])
useEffect(() => {
if (advancedMode || !activeThemeDataset || (selectedMapDataset && datasetMatchesTheme(selectedMapDataset, activeTheme))) {
if (advancedMode || !activeThemeDataset || selectedMapDataset?.id === activeThemeDataset.id) {
return
}
onOpenDatasetInMap(activeThemeDataset)
+2
View File
@@ -9,6 +9,7 @@ const DATASET_LABEL_BY_LAYER: Record<string, string> = {
forest: 'Bos en groen',
nature_value: 'Natuurwaarde',
agriculture: 'Landbouwgebruikspercelen',
building_registry: 'Gebouwenregister',
regional_boundary: 'Grens vervoerregio Kempen',
municipality_boundaries: 'Gemeentegrenzen Kempen',
}
@@ -17,6 +18,7 @@ const DATASET_SOURCE_LABELS: Record<string, string> = {
department_omgeving_land_use: 'Departement Omgeving',
agentschap_landbouw_zeevisserij_agricultural_parcels: 'Agentschap Landbouw en Zeevisserij',
digitaal_vlaanderen_orthophoto: 'Digitaal Vlaanderen',
digitaal_vlaanderen_buildings_addresses_register: 'Digitaal Vlaanderen',
grb: 'GRB',
historical_landuse: 'Digitaal Vlaanderen',
inbo_bwk_natura2000: 'INBO',