|
|
|
@@ -186,7 +186,11 @@ const DATA_THEME_MAP_STYLES: Record<DataThemeId, { fill: string; line: string }>
|
|
|
|
|
parcels: { fill: '#a7792f', line: '#7d571f' },
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function datasetAvailabilityLabel(dataset: DatasetCreateResponse, partitionCount = 1): string {
|
|
|
|
|
function datasetAvailabilityLabel(
|
|
|
|
|
dataset: DatasetCreateResponse,
|
|
|
|
|
partitions: DatasetCreateResponse[] = [dataset],
|
|
|
|
|
): string {
|
|
|
|
|
const partitionCount = partitions.length
|
|
|
|
|
const regionalSuffix = partitionCount > 1 ? ` · ${partitionCount} gemeenten` : ''
|
|
|
|
|
if (dataset.dataset_type === 'raster' && dataset.source_name === 'digitaal_vlaanderen_dhmv') {
|
|
|
|
|
const resolution = Number(dataset.source_metadata?.['analysis_resolution_m'])
|
|
|
|
@@ -197,9 +201,15 @@ function datasetAvailabilityLabel(dataset: DatasetCreateResponse, partitionCount
|
|
|
|
|
return `${Number.isFinite(resolution) ? `${resolution.toLocaleString('nl-BE')} m` : 'Raster'} overstromingsscenario${regionalSuffix}`
|
|
|
|
|
}
|
|
|
|
|
if (dataset.source_name === 'vmm_vha_bathymetry_profiles') {
|
|
|
|
|
const profiles = dataset.feature_count ?? dataset.vector_summary?.feature_count ?? 0
|
|
|
|
|
const documents = Number(dataset.source_metadata?.['document_count'] ?? 0)
|
|
|
|
|
return `${profiles.toLocaleString('nl-BE')} profielen · ${documents.toLocaleString('nl-BE')} bronbladen`
|
|
|
|
|
const profiles = partitions.reduce(
|
|
|
|
|
(total, item) => total + (item.feature_count ?? item.vector_summary?.feature_count ?? 0),
|
|
|
|
|
0,
|
|
|
|
|
)
|
|
|
|
|
const documents = partitions.reduce(
|
|
|
|
|
(total, item) => total + Number(item.source_metadata?.['document_count'] ?? 0),
|
|
|
|
|
0,
|
|
|
|
|
)
|
|
|
|
|
return `${profiles.toLocaleString('nl-BE')} profielen · ${documents.toLocaleString('nl-BE')} bronbladen${regionalSuffix}`
|
|
|
|
|
}
|
|
|
|
|
if (dataset.dataset_type === 'raster' && dataset.source_name === 'department_omgeving_thematic_raster') {
|
|
|
|
|
const resolution = Number(dataset.source_metadata?.['analysis_resolution_m'])
|
|
|
|
@@ -261,6 +271,13 @@ function isPartitionedRaster(dataset: DatasetCreateResponse | null | undefined):
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isPartitionedBathymetry(dataset: DatasetCreateResponse | null | undefined): boolean {
|
|
|
|
|
return Boolean(
|
|
|
|
|
dataset?.source_name === 'vmm_vha_bathymetry_profiles'
|
|
|
|
|
&& dataset.source_metadata?.['regional_partitions_complete'] === true,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function datasetProductKey(dataset: DatasetCreateResponse): string {
|
|
|
|
|
return String(dataset.source_metadata?.['product_key'] ?? '')
|
|
|
|
|
}
|
|
|
|
@@ -271,12 +288,14 @@ function datasetCoversSelectedArea(
|
|
|
|
|
regionalScope = false,
|
|
|
|
|
): boolean {
|
|
|
|
|
const coverageScope = String(dataset.source_metadata?.['coverage_scope'] ?? '')
|
|
|
|
|
if (isPartitionedBathymetry(dataset)) {
|
|
|
|
|
return regionalScope
|
|
|
|
|
? true
|
|
|
|
|
: Boolean(selectedAreaId) && dataset.area_id === selectedAreaId
|
|
|
|
|
}
|
|
|
|
|
if (coverageScope !== 'municipality' || !dataset.area_id) {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
if (regionalScope && dataset.source_name === 'vmm_vha_bathymetry_profiles') {
|
|
|
|
|
return dataset.source_metadata?.['regional_partitions_complete'] === true
|
|
|
|
|
}
|
|
|
|
|
if (regionalScope) {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
@@ -292,15 +311,20 @@ function rasterPartitionsForDataset(
|
|
|
|
|
if (!representative) {
|
|
|
|
|
return []
|
|
|
|
|
}
|
|
|
|
|
if (!regionalScope || !isPartitionedRaster(representative)) {
|
|
|
|
|
if (!regionalScope || (!isPartitionedRaster(representative) && !isPartitionedBathymetry(representative))) {
|
|
|
|
|
return [representative]
|
|
|
|
|
}
|
|
|
|
|
const productKey = datasetProductKey(representative)
|
|
|
|
|
const manifestSha256 = String(representative.source_metadata?.['partition_manifest_sha256'] ?? '')
|
|
|
|
|
return datasets
|
|
|
|
|
.filter(
|
|
|
|
|
(dataset) =>
|
|
|
|
|
dataset.source_name === representative.source_name
|
|
|
|
|
&& datasetProductKey(dataset) === productKey
|
|
|
|
|
&& (
|
|
|
|
|
isPartitionedBathymetry(representative)
|
|
|
|
|
? String(dataset.source_metadata?.['partition_manifest_sha256'] ?? '') === manifestSha256
|
|
|
|
|
: datasetProductKey(dataset) === productKey
|
|
|
|
|
)
|
|
|
|
|
&& datasetCoversSelectedArea(dataset, selectedAreaId, true),
|
|
|
|
|
)
|
|
|
|
|
.sort((left, right) => String(left.area_id ?? '').localeCompare(String(right.area_id ?? '')))
|
|
|
|
@@ -740,6 +764,8 @@ export function MapWorkspace({
|
|
|
|
|
const activeThemeDataset = themeDatasetMap[activeTheme.id]
|
|
|
|
|
const activeThemePartitions = themePartitionMap[activeTheme.id]
|
|
|
|
|
const regionalRasterThemeActive = regionalScopeSelected && isPartitionedRaster(activeThemeDataset)
|
|
|
|
|
const regionalBathymetryThemeActive = regionalScopeSelected && isPartitionedBathymetry(activeThemeDataset)
|
|
|
|
|
const regionalPartitionedThemeActive = regionalRasterThemeActive || regionalBathymetryThemeActive
|
|
|
|
|
const terrainImageOverlays = useMemo(
|
|
|
|
|
() =>
|
|
|
|
|
activeTheme.id === 'elevation' && selectedProjectId
|
|
|
|
@@ -842,7 +868,15 @@ export function MapWorkspace({
|
|
|
|
|
[themeInsights],
|
|
|
|
|
)
|
|
|
|
|
const activeSelectionResult = themeResults.find((item) => item.theme.id === activeThemeId)?.result
|
|
|
|
|
?? (!regionalRasterThemeActive && selectedMapDataset?.id === activeThemeDataset?.id ? mapSelectionResult : null)
|
|
|
|
|
?? (!regionalPartitionedThemeActive && selectedMapDataset?.id === activeThemeDataset?.id ? mapSelectionResult : null)
|
|
|
|
|
const explorerMapFeatureCollection = regionalBathymetryThemeActive
|
|
|
|
|
? null
|
|
|
|
|
: analysisMode === 'evolution' && temporalComparison?.geojson.features.length
|
|
|
|
|
? temporalComparison.geojson
|
|
|
|
|
: mapFeatureCollection
|
|
|
|
|
const explorerSelectionFeatureCollection = analysisMode === 'current'
|
|
|
|
|
? activeSelectionResult?.geojson ?? null
|
|
|
|
|
: null
|
|
|
|
|
const selectedAreaSquareMetres = useMemo(
|
|
|
|
|
() =>
|
|
|
|
|
bboxesEqual(mapSelectionBbox, selectedAreaBbox) && selectedMapArea?.area_m2
|
|
|
|
@@ -1083,8 +1117,13 @@ export function MapWorkspace({
|
|
|
|
|
bbox: { ...mapSelectionBbox, crs: 'EPSG:4326' },
|
|
|
|
|
dataset_id: activeThemeDataset.id,
|
|
|
|
|
area_id: areaId,
|
|
|
|
|
partitioned: regionalRasterThemeActive,
|
|
|
|
|
product_key: String(activeThemeDataset.source_metadata?.['product_key'] ?? '') || undefined,
|
|
|
|
|
partitioned: regionalPartitionedThemeActive,
|
|
|
|
|
product_key: regionalRasterThemeActive
|
|
|
|
|
? String(activeThemeDataset.source_metadata?.['product_key'] ?? '') || undefined
|
|
|
|
|
: undefined,
|
|
|
|
|
partition_scope_key: regionalBathymetryThemeActive
|
|
|
|
|
? String(activeThemeDataset.source_metadata?.['partition_scope_key'] ?? 'flanders')
|
|
|
|
|
: undefined,
|
|
|
|
|
theme_id: activeTheme.id,
|
|
|
|
|
name: `${activeTheme.id}-analysis`,
|
|
|
|
|
}
|
|
|
|
@@ -1157,7 +1196,8 @@ export function MapWorkspace({
|
|
|
|
|
? [{
|
|
|
|
|
themeId: theme.id,
|
|
|
|
|
dataset,
|
|
|
|
|
partitioned: regionalScopeSelected && isPartitionedRaster(dataset),
|
|
|
|
|
partitioned: regionalScopeSelected
|
|
|
|
|
&& (isPartitionedRaster(dataset) || isPartitionedBathymetry(dataset)),
|
|
|
|
|
}]
|
|
|
|
|
: []
|
|
|
|
|
})
|
|
|
|
@@ -1167,7 +1207,7 @@ export function MapWorkspace({
|
|
|
|
|
const analyzeSelection = async (bbox: VectorSelectionBBox, areaId?: string) => {
|
|
|
|
|
setSelectionBbox(bbox)
|
|
|
|
|
const tasks: Array<Promise<unknown>> = [loadAllThemeResults(bbox, areaId)]
|
|
|
|
|
if (!regionalRasterThemeActive) {
|
|
|
|
|
if (!regionalPartitionedThemeActive) {
|
|
|
|
|
tasks.push(onRunMapSelectionExtract(bbox, areaId))
|
|
|
|
|
}
|
|
|
|
|
if (analysisMode === 'evolution' && earlierDatasetId && laterDatasetId) {
|
|
|
|
@@ -1328,7 +1368,7 @@ export function MapWorkspace({
|
|
|
|
|
<div className="geo-theme-list">
|
|
|
|
|
{DATA_THEMES.map((theme) => {
|
|
|
|
|
const dataset = themeDatasetMap[theme.id]
|
|
|
|
|
const partitionCount = themePartitionMap[theme.id].length
|
|
|
|
|
const partitions = themePartitionMap[theme.id]
|
|
|
|
|
const temporalGroups = themeTemporalSeriesMap[theme.id]
|
|
|
|
|
const temporalGroup = temporalGroups[0]
|
|
|
|
|
const evolutionAvailable = temporalGroups.some((group) => group.items.length >= 2)
|
|
|
|
@@ -1355,7 +1395,7 @@ export function MapWorkspace({
|
|
|
|
|
? 'Alleen huidige toestand'
|
|
|
|
|
: 'Bron nog niet ingeladen'
|
|
|
|
|
: dataset
|
|
|
|
|
? datasetAvailabilityLabel(dataset, partitionCount)
|
|
|
|
|
? datasetAvailabilityLabel(dataset, partitions)
|
|
|
|
|
: 'Bron nog niet ingeladen'}
|
|
|
|
|
</small>
|
|
|
|
|
</span>
|
|
|
|
@@ -1376,7 +1416,9 @@ export function MapWorkspace({
|
|
|
|
|
? mapLayerLabel
|
|
|
|
|
: analysisMode === 'evolution'
|
|
|
|
|
? activeTemporalSeriesGroup?.label ?? 'Nog geen historische reeks ingeladen'
|
|
|
|
|
: activeThemeDataset ? getDatasetDisplayName(activeThemeDataset) : 'Geen databron beschikbaar'}
|
|
|
|
|
: regionalBathymetryThemeActive
|
|
|
|
|
? 'VHA-dwarsprofielen Vlaanderen'
|
|
|
|
|
: activeThemeDataset ? getDatasetDisplayName(activeThemeDataset) : 'Geen databron beschikbaar'}
|
|
|
|
|
</strong>
|
|
|
|
|
<small>
|
|
|
|
|
{analysisOverlayActive
|
|
|
|
@@ -1385,6 +1427,8 @@ export function MapWorkspace({
|
|
|
|
|
? activeTemporalSeries.length >= 2
|
|
|
|
|
? `${activeTemporalSeries.length} officiële meetmomenten · ${formatObservationDate(activeTemporalSeries[0].observed_at)} tot ${formatObservationDate(activeTemporalSeries[activeTemporalSeries.length - 1].observed_at)}`
|
|
|
|
|
: 'Voor dit thema is nog geen tweede officieel meetmoment beschikbaar.'
|
|
|
|
|
: regionalBathymetryThemeActive
|
|
|
|
|
? `${activeThemePartitions.length} gecontroleerde gemeentepartities · selectie wordt ruimtelijk samengevoegd`
|
|
|
|
|
: activeThemeDataset
|
|
|
|
|
? `${getDatasetSourceDisplayName(activeThemeDataset)} · ${formatDatasetObservation(activeThemeDataset)}`
|
|
|
|
|
: activeTheme.description}
|
|
|
|
@@ -1487,6 +1531,8 @@ export function MapWorkspace({
|
|
|
|
|
? 'Sleep nu een rechthoek op de kaart.'
|
|
|
|
|
: regionalRasterThemeActive
|
|
|
|
|
? 'Teken een rechthoek; de juiste gemeentelijke rasters worden automatisch gecombineerd.'
|
|
|
|
|
: regionalBathymetryThemeActive
|
|
|
|
|
? 'Teken een rechthoek of analyseer Vlaanderen; alleen overlappende VHA-partities worden samengevoegd.'
|
|
|
|
|
: 'Sleep een rechthoek of analyseer het volledige werkgebied.'}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
@@ -1517,12 +1563,12 @@ export function MapWorkspace({
|
|
|
|
|
|
|
|
|
|
<div className={bboxSelectionMode ? 'geo-map-canvas geo-map-canvas-drawing' : 'geo-map-canvas'}>
|
|
|
|
|
<GeoMap
|
|
|
|
|
data={analysisMode === 'evolution' && temporalComparison?.geojson.features.length ? temporalComparison.geojson : mapFeatureCollection}
|
|
|
|
|
data={explorerMapFeatureCollection}
|
|
|
|
|
dataFillColor={activeThemeMapStyle.fill}
|
|
|
|
|
dataLineColor={activeThemeMapStyle.line}
|
|
|
|
|
areaData={areaFeatureCollection}
|
|
|
|
|
selectedFeature={selectedFeature}
|
|
|
|
|
selectionData={analysisMode === 'current' ? mapSelectionResult?.geojson ?? null : null}
|
|
|
|
|
selectionData={explorerSelectionFeatureCollection}
|
|
|
|
|
imageOverlays={activeImageOverlays}
|
|
|
|
|
selectionBbox={mapSelectionBbox}
|
|
|
|
|
bboxSelectionMode={bboxSelectionMode}
|
|
|
|
@@ -1872,6 +1918,8 @@ export function MapWorkspace({
|
|
|
|
|
? `${mapLayerLabel} · ${mapLayerSourceLabel}`
|
|
|
|
|
: analysisMode === 'evolution'
|
|
|
|
|
? activeTemporalSeriesGroup?.label ?? 'geen vergelijkbare tijdreeks'
|
|
|
|
|
: regionalBathymetryThemeActive
|
|
|
|
|
? `VHA-dwarsprofielen Vlaanderen · ${activeThemePartitions.length} gemeentepartities`
|
|
|
|
|
: activeThemeDataset
|
|
|
|
|
? getDatasetDisplayName(activeThemeDataset)
|
|
|
|
|
: 'niet beschikbaar'}
|
|
|
|
|