Add bounded GRB map acquisition
This commit is contained in:
@@ -607,6 +607,16 @@ browser never contacts WCS directly. An exact repeat reuses the persisted
|
||||
request. A complete-Flanders raster request remains disabled by the regional
|
||||
size guard, while a complete municipality remains a valid bounded analysis.
|
||||
|
||||
The same explicit-selection workflow exposes GRB buildings, roads, water and
|
||||
parcels. These are vector products rather than rasters: selecting a
|
||||
municipality or drawing a rectangle starts a bounded backend OGC API request,
|
||||
persists the complete clipped result and analyzes the persisted
|
||||
`vector_features`. Cards show `Op aanvraag` before first use and measured
|
||||
hectares or kilometres afterwards. Full-Flanders acquisition remains disabled
|
||||
by the 20 km side limit; users select a municipality or smaller rectangle.
|
||||
The map never calls Digitaal Vlaanderen directly and never displays a
|
||||
silently truncated reference layer.
|
||||
|
||||
Selecting `Hoogte & reliëf` shows the source distinction before analysis:
|
||||
DTM represents terrain after removal of buildings and other objects; DSM
|
||||
represents the visible surface including buildings and vegetation. Selecting
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from 'react'
|
||||
import GeoMap from '../GeoMap'
|
||||
import type { AreaRead, DatasetCreateResponse, DetectionQaResult, MapResultExportRequest, MapViewportState, OrthophotoAcquisitionResult, OrthophotoProductRead, ProjectRead, QaComparisonResult, VectorSelectionBBox, VectorSelectionMetric, VectorSelectionResponse } from '../../types'
|
||||
import { useMapThemeSelectionInsights, type MapThemeAcquisition, type MapThemeQuery } from '../../hooks/useMapThemeSelectionInsights'
|
||||
import { useOfficialRasterProducts } from '../../hooks/useOfficialRasterProducts'
|
||||
import { useOfficialMapProducts } from '../../hooks/useOfficialMapProducts'
|
||||
import { useTemporalComparison } from '../../hooks/useTemporalComparison'
|
||||
import { getDatasetDisplayName, getDatasetSourceDisplayName } from '../../lib/datasetDisplay'
|
||||
import { TemporalTrendChart } from './TemporalTrendChart'
|
||||
@@ -54,10 +54,9 @@ interface TemporalSeriesGroup {
|
||||
items: DatasetCreateResponse[]
|
||||
}
|
||||
|
||||
interface OnDemandRasterProduct extends MapThemeAcquisition {
|
||||
interface OnDemandMapProduct extends MapThemeAcquisition {
|
||||
theme: DataThemeId
|
||||
nativeResolutionM: number
|
||||
referenceLabel: string
|
||||
availabilityLabel: string
|
||||
attribution: string
|
||||
limitationMessage: string
|
||||
}
|
||||
@@ -669,10 +668,10 @@ export function MapWorkspace({
|
||||
clearThemeInsights,
|
||||
} = useMapThemeSelectionInsights<DataThemeId>(selectedProjectId, onRefreshProjectData)
|
||||
const {
|
||||
products: officialRasterProducts,
|
||||
loading: officialRasterProductsLoading,
|
||||
error: officialRasterProductsError,
|
||||
} = useOfficialRasterProducts(flandersScopeSelected ? selectedProjectId : null)
|
||||
products: officialMapProducts,
|
||||
loading: officialMapProductsLoading,
|
||||
error: officialMapProductsError,
|
||||
} = useOfficialMapProducts(flandersScopeSelected ? selectedProjectId : null)
|
||||
const {
|
||||
temporalComparison,
|
||||
temporalComparisonLoading,
|
||||
@@ -760,10 +759,10 @@ export function MapWorkspace({
|
||||
)
|
||||
if (selectedFloodHazard) {
|
||||
result.flood_hazard = selectedFloodHazard
|
||||
} else if (flandersScopeSelected && officialRasterProducts.floodHazard.length > 0) {
|
||||
} else if (flandersScopeSelected && officialMapProducts.floodHazard.length > 0) {
|
||||
result.flood_hazard = null
|
||||
}
|
||||
if (flandersScopeSelected && officialRasterProducts.dhmv.length > 0) {
|
||||
if (flandersScopeSelected && officialMapProducts.dhmv.length > 0) {
|
||||
result.elevation = availableMapDatasets.find(
|
||||
(dataset) =>
|
||||
dataset.source_name === 'digitaal_vlaanderen_dhmv'
|
||||
@@ -776,8 +775,8 @@ export function MapWorkspace({
|
||||
availableMapDatasets,
|
||||
flandersScopeSelected,
|
||||
floodHazardDatasets,
|
||||
officialRasterProducts.dhmv.length,
|
||||
officialRasterProducts.floodHazard.length,
|
||||
officialMapProducts.dhmv.length,
|
||||
officialMapProducts.floodHazard.length,
|
||||
regionalScopeSelected,
|
||||
selectedDhmvProductKey,
|
||||
selectedFloodHazardDatasetId,
|
||||
@@ -800,38 +799,47 @@ export function MapWorkspace({
|
||||
[availableMapDatasets, regionalScopeSelected, selectedMapAreaId, themeDatasetMap],
|
||||
)
|
||||
const activeTheme = DATA_THEMES.find((theme) => theme.id === activeThemeId) ?? DATA_THEMES[0]
|
||||
const onDemandRasterProductMap = useMemo(
|
||||
const onDemandProductMap = useMemo(
|
||||
() => {
|
||||
const result = new Map<DataThemeId, OnDemandRasterProduct>()
|
||||
const result = new Map<DataThemeId, OnDemandMapProduct>()
|
||||
if (!flandersScopeSelected) {
|
||||
return result
|
||||
}
|
||||
for (const product of officialRasterProducts.thematic) {
|
||||
for (const product of officialMapProducts.thematic) {
|
||||
result.set(product.theme, {
|
||||
kind: 'thematic_raster',
|
||||
productKey: product.key,
|
||||
displayName: product.display_name,
|
||||
theme: product.theme,
|
||||
nativeResolutionM: product.native_resolution_m,
|
||||
referenceLabel: String(product.observation_year),
|
||||
availabilityLabel: `${product.native_resolution_m} m · ${product.observation_year} · laad bij selectie`,
|
||||
attribution: product.attribution,
|
||||
limitationMessage: product.limitation_message,
|
||||
})
|
||||
}
|
||||
const dhmvProduct = officialRasterProducts.dhmv.find((product) => product.key === selectedDhmvProductKey)
|
||||
for (const product of officialMapProducts.grb) {
|
||||
result.set(product.key, {
|
||||
kind: 'grb',
|
||||
productKey: product.key,
|
||||
displayName: product.display_name,
|
||||
theme: product.key,
|
||||
availabilityLabel: 'officiële vectorbron · laad bij selectie',
|
||||
attribution: product.attribution,
|
||||
limitationMessage: product.limitation_message,
|
||||
})
|
||||
}
|
||||
const dhmvProduct = officialMapProducts.dhmv.find((product) => product.key === selectedDhmvProductKey)
|
||||
if (dhmvProduct) {
|
||||
result.set('elevation', {
|
||||
kind: 'dhmv',
|
||||
productKey: dhmvProduct.key,
|
||||
displayName: dhmvProduct.display_name,
|
||||
theme: 'elevation',
|
||||
nativeResolutionM: dhmvProduct.native_resolution_m,
|
||||
referenceLabel: dhmvProduct.acquisition_period,
|
||||
availabilityLabel: `${dhmvProduct.native_resolution_m} m · ${dhmvProduct.acquisition_period} · laad bij selectie`,
|
||||
attribution: dhmvProduct.attribution,
|
||||
limitationMessage: dhmvProduct.limitation_message,
|
||||
})
|
||||
}
|
||||
const floodProduct = officialRasterProducts.floodHazard.find(
|
||||
const floodProduct = officialMapProducts.floodHazard.find(
|
||||
(product) => product.key === selectedFloodHazardProductKey,
|
||||
)
|
||||
if (floodProduct) {
|
||||
@@ -840,8 +848,7 @@ export function MapWorkspace({
|
||||
productKey: floodProduct.key,
|
||||
displayName: floodProduct.display_name,
|
||||
theme: 'flood_hazard',
|
||||
nativeResolutionM: floodProduct.native_resolution_m,
|
||||
referenceLabel: `${floodProduct.climate_context} · T${floodProduct.return_period_years}`,
|
||||
availabilityLabel: `${floodProduct.native_resolution_m} m · ${floodProduct.climate_context} · T${floodProduct.return_period_years} · laad bij selectie`,
|
||||
attribution: floodProduct.attribution,
|
||||
limitationMessage: floodProduct.limitation_message,
|
||||
})
|
||||
@@ -850,12 +857,12 @@ export function MapWorkspace({
|
||||
},
|
||||
[
|
||||
flandersScopeSelected,
|
||||
officialRasterProducts,
|
||||
officialMapProducts,
|
||||
selectedDhmvProductKey,
|
||||
selectedFloodHazardProductKey,
|
||||
],
|
||||
)
|
||||
const activeOnDemandRasterProduct = onDemandRasterProductMap.get(activeTheme.id) ?? null
|
||||
const activeOnDemandMapProduct = onDemandProductMap.get(activeTheme.id) ?? null
|
||||
const activeThemeMapStyle = DATA_THEME_MAP_STYLES[activeTheme.id]
|
||||
const analysisOverlayActive = mapContentMode === 'analysis' && analysisLayerAvailable && Boolean(mapFeatureCollection)
|
||||
const selectedOrthophotoProduct = orthophotoProducts.find((item) => item.key === selectedOrthophotoProductKey) ?? null
|
||||
@@ -875,24 +882,24 @@ export function MapWorkspace({
|
||||
const regionalRasterThemeActive = regionalScopeSelected && isPartitionedRaster(activeThemeDataset)
|
||||
const regionalBathymetryThemeActive = regionalScopeSelected && isPartitionedBathymetry(activeThemeDataset)
|
||||
const regionalPartitionedThemeActive = regionalRasterThemeActive || regionalBathymetryThemeActive
|
||||
const onDemandRasterThemeActive = analysisMode === 'current' && Boolean(activeOnDemandRasterProduct)
|
||||
const regionalOnDemandRasterThemeActive = regionalScopeSelected && onDemandRasterThemeActive
|
||||
const activeThemeAvailable = Boolean(activeThemeDataset) || onDemandRasterThemeActive
|
||||
const onDemandThemeActive = analysisMode === 'current' && Boolean(activeOnDemandMapProduct)
|
||||
const regionalOnDemandThemeActive = regionalScopeSelected && onDemandThemeActive
|
||||
const activeThemeAvailable = Boolean(activeThemeDataset) || onDemandThemeActive
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!flandersScopeSelected
|
||||
|| analysisMode !== 'current'
|
||||
|| activeThemeAvailable
|
||||
|| (onDemandRasterProductMap.size === 0 && !officialRasterProductsError)
|
||||
|| (onDemandProductMap.size === 0 && !officialMapProductsError)
|
||||
) {
|
||||
return
|
||||
}
|
||||
const fallbackTheme = DATA_THEMES.find((theme) =>
|
||||
theme.id === 'space_occupation'
|
||||
&& Boolean(themeDatasetMap[theme.id] || onDemandRasterProductMap.get(theme.id)),
|
||||
&& Boolean(themeDatasetMap[theme.id] || onDemandProductMap.get(theme.id)),
|
||||
) ?? DATA_THEMES.find((theme) =>
|
||||
Boolean(themeDatasetMap[theme.id] || onDemandRasterProductMap.get(theme.id)),
|
||||
Boolean(themeDatasetMap[theme.id] || onDemandProductMap.get(theme.id)),
|
||||
)
|
||||
if (!fallbackTheme) {
|
||||
return
|
||||
@@ -906,8 +913,8 @@ export function MapWorkspace({
|
||||
activeThemeAvailable,
|
||||
analysisMode,
|
||||
flandersScopeSelected,
|
||||
officialRasterProductsError,
|
||||
onDemandRasterProductMap,
|
||||
officialMapProductsError,
|
||||
onDemandProductMap,
|
||||
onOpenDatasetInMap,
|
||||
themeDatasetMap,
|
||||
])
|
||||
@@ -999,12 +1006,12 @@ export function MapWorkspace({
|
||||
useEffect(() => {
|
||||
const contextSourceLabel = analysisMode === 'evolution' ? activeTemporalSeriesGroup?.label ?? null
|
||||
: regionalBathymetryThemeActive ? 'VHA-dwarsprofielen Vlaanderen'
|
||||
: activeOnDemandRasterProduct?.displayName ?? null
|
||||
: activeOnDemandMapProduct?.displayName ?? null
|
||||
onSetContextSourceLabel(contextSourceLabel)
|
||||
return () => onSetContextSourceLabel(null)
|
||||
}, [
|
||||
activeTemporalSeriesGroup?.label,
|
||||
activeOnDemandRasterProduct?.displayName,
|
||||
activeOnDemandMapProduct?.displayName,
|
||||
analysisMode,
|
||||
onSetContextSourceLabel,
|
||||
regionalBathymetryThemeActive,
|
||||
@@ -1112,7 +1119,7 @@ export function MapWorkspace({
|
||||
}
|
||||
return
|
||||
}
|
||||
if (flandersScopeSelected && officialRasterProducts.floodHazard.length > 0) {
|
||||
if (flandersScopeSelected && officialMapProducts.floodHazard.length > 0) {
|
||||
setSelectedFloodHazardDatasetId('')
|
||||
return
|
||||
}
|
||||
@@ -1126,7 +1133,7 @@ export function MapWorkspace({
|
||||
}, [
|
||||
flandersScopeSelected,
|
||||
floodHazardDatasets,
|
||||
officialRasterProducts.floodHazard.length,
|
||||
officialMapProducts.floodHazard.length,
|
||||
selectedFloodHazardDatasetId,
|
||||
selectedFloodHazardProductKey,
|
||||
])
|
||||
@@ -1350,7 +1357,7 @@ export function MapWorkspace({
|
||||
? temporalGroup?.items[temporalGroup.items.length - 1] ?? null
|
||||
: themeDatasetMap[theme.id]
|
||||
const onDemandProduct = analysisMode === 'current'
|
||||
? onDemandRasterProductMap.get(theme.id)
|
||||
? onDemandProductMap.get(theme.id)
|
||||
: null
|
||||
if (!dataset && !onDemandProduct) {
|
||||
return
|
||||
@@ -1381,7 +1388,7 @@ export function MapWorkspace({
|
||||
const availableThemes: Array<MapThemeQuery<DataThemeId>> = []
|
||||
for (const theme of DATA_THEMES) {
|
||||
const onDemandProduct = analysisMode === 'current'
|
||||
? onDemandRasterProductMap.get(theme.id)
|
||||
? onDemandProductMap.get(theme.id)
|
||||
: null
|
||||
if (onDemandProduct) {
|
||||
availableThemes.push({
|
||||
@@ -1410,7 +1417,7 @@ export function MapWorkspace({
|
||||
const analyzeSelection = async (bbox: VectorSelectionBBox, areaId?: string) => {
|
||||
setSelectionBbox(bbox)
|
||||
const tasks: Array<Promise<unknown>> = [loadAllThemeResults(bbox, areaId)]
|
||||
if (!regionalPartitionedThemeActive && !onDemandRasterThemeActive) {
|
||||
if (!regionalPartitionedThemeActive && !onDemandThemeActive) {
|
||||
tasks.push(onRunMapSelectionExtract(bbox, areaId))
|
||||
}
|
||||
if (analysisMode === 'evolution' && earlierDatasetId && laterDatasetId) {
|
||||
@@ -1571,7 +1578,7 @@ export function MapWorkspace({
|
||||
<div className="geo-theme-list">
|
||||
{DATA_THEMES.map((theme) => {
|
||||
const dataset = themeDatasetMap[theme.id]
|
||||
const onDemandProduct = onDemandRasterProductMap.get(theme.id)
|
||||
const onDemandProduct = onDemandProductMap.get(theme.id)
|
||||
const partitions = themePartitionMap[theme.id]
|
||||
const temporalGroups = themeTemporalSeriesMap[theme.id]
|
||||
const temporalGroup = temporalGroups[0]
|
||||
@@ -1603,7 +1610,7 @@ export function MapWorkspace({
|
||||
: dataset
|
||||
? datasetAvailabilityLabel(dataset, partitions)
|
||||
: onDemandProduct
|
||||
? `${onDemandProduct.nativeResolutionM} m · ${onDemandProduct.referenceLabel} · laad bij selectie`
|
||||
? onDemandProduct.availabilityLabel
|
||||
: 'Bron nog niet ingeladen'}
|
||||
</small>
|
||||
</span>
|
||||
@@ -1628,7 +1635,7 @@ export function MapWorkspace({
|
||||
? 'VHA-dwarsprofielen Vlaanderen'
|
||||
: activeThemeDataset
|
||||
? getDatasetDisplayName(activeThemeDataset)
|
||||
: activeOnDemandRasterProduct?.displayName ?? 'Geen databron beschikbaar'}
|
||||
: activeOnDemandMapProduct?.displayName ?? 'Geen databron beschikbaar'}
|
||||
</strong>
|
||||
<small>
|
||||
{analysisOverlayActive
|
||||
@@ -1641,19 +1648,19 @@ export function MapWorkspace({
|
||||
? `${activeThemePartitions.length} gecontroleerde gemeentepartities · selectie wordt ruimtelijk samengevoegd`
|
||||
: activeThemeDataset
|
||||
? `${getDatasetSourceDisplayName(activeThemeDataset)} · ${formatDatasetObservation(activeThemeDataset)}`
|
||||
: activeOnDemandRasterProduct
|
||||
? `${activeOnDemandRasterProduct.attribution} · wordt alleen voor de gekozen selectie ingeladen`
|
||||
: activeOnDemandMapProduct
|
||||
? `${activeOnDemandMapProduct.attribution} · wordt alleen voor de gekozen selectie ingeladen`
|
||||
: activeTheme.description}
|
||||
</small>
|
||||
</div>
|
||||
{officialRasterProductsLoading && flandersScopeSelected ? (
|
||||
<p className="geo-data-notice">Beschikbare Vlaamse rasterbronnen worden gecontroleerd…</p>
|
||||
{officialMapProductsLoading && flandersScopeSelected ? (
|
||||
<p className="geo-data-notice">Beschikbare Vlaamse kaartbronnen worden gecontroleerd…</p>
|
||||
) : null}
|
||||
{officialRasterProductsError && flandersScopeSelected ? (
|
||||
<p className="error">{officialRasterProductsError}</p>
|
||||
{officialMapProductsError && flandersScopeSelected ? (
|
||||
<p className="error">{officialMapProductsError}</p>
|
||||
) : null}
|
||||
|
||||
{analysisMode === 'current' && activeTheme.id === 'elevation' && officialRasterProducts.dhmv.length > 0 ? (
|
||||
{analysisMode === 'current' && activeTheme.id === 'elevation' && officialMapProducts.dhmv.length > 0 ? (
|
||||
<label className="geo-scope-select">
|
||||
Hoogtemodel
|
||||
<select
|
||||
@@ -1674,7 +1681,7 @@ export function MapWorkspace({
|
||||
}
|
||||
}}
|
||||
>
|
||||
{officialRasterProducts.dhmv.map((product) => (
|
||||
{officialMapProducts.dhmv.map((product) => (
|
||||
<option key={product.key} value={product.key}>{product.display_name}</option>
|
||||
))}
|
||||
</select>
|
||||
@@ -1682,7 +1689,7 @@ export function MapWorkspace({
|
||||
</label>
|
||||
) : null}
|
||||
|
||||
{analysisMode === 'current' && activeTheme.id === 'flood_hazard' && officialRasterProducts.floodHazard.length > 0 ? (
|
||||
{analysisMode === 'current' && activeTheme.id === 'flood_hazard' && officialMapProducts.floodHazard.length > 0 ? (
|
||||
<label className="geo-scope-select">
|
||||
Overstromingsscenario
|
||||
<select
|
||||
@@ -1699,7 +1706,7 @@ export function MapWorkspace({
|
||||
}
|
||||
}}
|
||||
>
|
||||
{officialRasterProducts.floodHazard.map((product) => (
|
||||
{officialMapProducts.floodHazard.map((product) => (
|
||||
<option key={product.key} value={product.key}>{product.display_name}</option>
|
||||
))}
|
||||
</select>
|
||||
@@ -1801,8 +1808,8 @@ export function MapWorkspace({
|
||||
? 'Sleep nu een rechthoek op de kaart.'
|
||||
: regionalRasterThemeActive
|
||||
? 'Teken een rechthoek; de juiste gemeentelijke rasters worden automatisch gecombineerd.'
|
||||
: onDemandRasterThemeActive
|
||||
? 'Teken een rechthoek; officiële Vlaamse rasters worden begrensd opgehaald, bewaard en hergebruikt.'
|
||||
: onDemandThemeActive
|
||||
? 'Teken een rechthoek; officiële Vlaamse kaartbronnen worden begrensd opgehaald, bewaard en hergebruikt.'
|
||||
: regionalBathymetryThemeActive
|
||||
? 'Teken een rechthoek of analyseer Vlaanderen; alleen overlappende VHA-partities worden samengevoegd.'
|
||||
: 'Sleep een rechthoek of analyseer het volledige werkgebied.'}
|
||||
@@ -1820,16 +1827,16 @@ export function MapWorkspace({
|
||||
</button>
|
||||
<button
|
||||
className="secondary-action"
|
||||
disabled={!activeThemeAvailable || regionalRasterThemeActive || regionalOnDemandRasterThemeActive || (analysisMode === 'evolution' && activeTemporalSeries.length < 2) || !selectedAreaBbox || mapSelectionLoading || themeResultsLoading}
|
||||
disabled={!activeThemeAvailable || regionalRasterThemeActive || regionalOnDemandThemeActive || (analysisMode === 'evolution' && activeTemporalSeries.length < 2) || !selectedAreaBbox || mapSelectionLoading || themeResultsLoading}
|
||||
type="button"
|
||||
title={
|
||||
regionalRasterThemeActive || regionalOnDemandRasterThemeActive
|
||||
? 'Teken een begrensde rechthoek voor een regionale rasteranalyse.'
|
||||
regionalRasterThemeActive || regionalOnDemandThemeActive
|
||||
? 'Teken een begrensde rechthoek voor deze regionale analyse.'
|
||||
: undefined
|
||||
}
|
||||
onClick={() => selectedAreaBbox && void analyzeSelection(selectedAreaBbox, selectedMapArea?.id)}
|
||||
>
|
||||
{regionalRasterThemeActive || regionalOnDemandRasterThemeActive ? 'Selecteer een deelgebied' : 'Volledig werkgebied'}
|
||||
{regionalRasterThemeActive || regionalOnDemandThemeActive ? 'Selecteer een deelgebied' : 'Volledig werkgebied'}
|
||||
</button>
|
||||
<button className="secondary-action" disabled={!mapSelectionBbox} type="button" onClick={clearAreaSelection}>
|
||||
Wis selectie
|
||||
@@ -2198,7 +2205,7 @@ export function MapWorkspace({
|
||||
? `VHA-dwarsprofielen Vlaanderen · ${activeThemePartitions.length} gemeentepartities`
|
||||
: activeThemeDataset
|
||||
? getDatasetDisplayName(activeThemeDataset)
|
||||
: activeOnDemandRasterProduct?.displayName
|
||||
: activeOnDemandMapProduct?.displayName
|
||||
?? 'niet beschikbaar'}
|
||||
</span>
|
||||
{usesDefaultOsmBasemap ? <span><strong>Ondergrond:</strong> OpenStreetMap</span> : null}
|
||||
|
||||
@@ -80,7 +80,8 @@ export function ProviderPanel({
|
||||
<div className="provider-detail-stack">
|
||||
<strong>Officiële referentiebronnen</strong>
|
||||
<div>
|
||||
Reeds ingeladen GRB-lagen blijven lokaal beschikbaar. De live GRB- en OSM-koppelingen staan uit en halen dus niet ongemerkt externe gegevens op.
|
||||
GRB is beschikbaar voor expliciet begrensde kaartselecties en wordt daarna lokaal bewaard.
|
||||
OSM blijft uitgeschakeld; geen enkele bron haalt ongemerkt gegevens op.
|
||||
</div>
|
||||
</div>
|
||||
<ul className="system-provider-list">
|
||||
|
||||
@@ -6,7 +6,7 @@ import { terrainSelectionToMapSelection } from '../lib/terrainSelection'
|
||||
import { floodHazardSelectionToMapSelection } from '../lib/floodHazardSelection'
|
||||
import { thematicRasterSelectionToMapSelection } from '../lib/thematicRaster'
|
||||
|
||||
export type MapThemeAcquisitionKind = 'thematic_raster' | 'dhmv' | 'flood_hazard'
|
||||
export type MapThemeAcquisitionKind = 'thematic_raster' | 'dhmv' | 'flood_hazard' | 'grb'
|
||||
|
||||
export interface MapThemeAcquisition {
|
||||
kind: MapThemeAcquisitionKind
|
||||
@@ -72,30 +72,34 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
|
||||
queries.map(async ({ themeId, dataset: existingDataset, partitioned, acquisition }) => {
|
||||
let dataset = existingDataset
|
||||
if (acquisition) {
|
||||
const commonPayload = {
|
||||
bbox,
|
||||
area_id: areaId,
|
||||
force_refresh: false,
|
||||
}
|
||||
const acquisitionJob = acquisition.kind === 'thematic_raster'
|
||||
? await datasetsApi.acquireThematicRaster(selectedProjectId, {
|
||||
bbox,
|
||||
area_id: areaId,
|
||||
...commonPayload,
|
||||
product_key: acquisition.productKey,
|
||||
force_refresh: false,
|
||||
})
|
||||
: acquisition.kind === 'dhmv'
|
||||
? await datasetsApi.acquireDhmv(selectedProjectId, {
|
||||
bbox,
|
||||
area_id: areaId,
|
||||
...commonPayload,
|
||||
product_key: acquisition.productKey as 'dtm_1m' | 'dsm_1m',
|
||||
force_refresh: false,
|
||||
})
|
||||
: await datasetsApi.acquireFloodHazard(selectedProjectId, {
|
||||
bbox,
|
||||
area_id: areaId,
|
||||
product_key: acquisition.productKey,
|
||||
force_refresh: false,
|
||||
})
|
||||
: acquisition.kind === 'flood_hazard'
|
||||
? await datasetsApi.acquireFloodHazard(selectedProjectId, {
|
||||
...commonPayload,
|
||||
product_key: acquisition.productKey,
|
||||
})
|
||||
: await datasetsApi.acquireGrb(selectedProjectId, {
|
||||
...commonPayload,
|
||||
product_key: acquisition.productKey as 'buildings' | 'roads' | 'water' | 'parcels',
|
||||
})
|
||||
if (acquisitionJob.status !== 'success' || !acquisitionJob.output_dataset_id) {
|
||||
throw new Error(
|
||||
acquisitionJob.error_message
|
||||
|| `De officiële rasterbron ${acquisition.displayName} kon niet worden ingeladen.`,
|
||||
|| `De officiële kaartbron ${acquisition.displayName} kon niet worden ingeladen.`,
|
||||
)
|
||||
}
|
||||
dataset = await datasetsApi.get(selectedProjectId, acquisitionJob.output_dataset_id)
|
||||
|
||||
+11
-6
@@ -4,23 +4,26 @@ import { formatError } from '../lib/formatError'
|
||||
import type {
|
||||
DhmvProductRead,
|
||||
FloodHazardProductRead,
|
||||
GrbProductRead,
|
||||
ThematicRasterProductRead,
|
||||
} from '../types'
|
||||
|
||||
interface OfficialRasterProducts {
|
||||
interface OfficialMapProducts {
|
||||
thematic: ThematicRasterProductRead[]
|
||||
dhmv: DhmvProductRead[]
|
||||
floodHazard: FloodHazardProductRead[]
|
||||
grb: GrbProductRead[]
|
||||
}
|
||||
|
||||
const EMPTY_PRODUCTS: OfficialRasterProducts = {
|
||||
const EMPTY_PRODUCTS: OfficialMapProducts = {
|
||||
thematic: [],
|
||||
dhmv: [],
|
||||
floodHazard: [],
|
||||
grb: [],
|
||||
}
|
||||
|
||||
export function useOfficialRasterProducts(selectedProjectId: string | null) {
|
||||
const [products, setProducts] = useState<OfficialRasterProducts>(EMPTY_PRODUCTS)
|
||||
export function useOfficialMapProducts(selectedProjectId: string | null) {
|
||||
const [products, setProducts] = useState<OfficialMapProducts>(EMPTY_PRODUCTS)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
@@ -41,20 +44,22 @@ export function useOfficialRasterProducts(selectedProjectId: string | null) {
|
||||
datasetsApi.listThematicRasterProducts(selectedProjectId),
|
||||
datasetsApi.listDhmvProducts(selectedProjectId),
|
||||
datasetsApi.listFloodHazardProducts(selectedProjectId),
|
||||
datasetsApi.listGrbProducts(selectedProjectId),
|
||||
])
|
||||
.then(([thematic, dhmv, floodHazard]) => {
|
||||
.then(([thematic, dhmv, floodHazard, grb]) => {
|
||||
if (!cancelled) {
|
||||
setProducts({
|
||||
thematic: thematic.items,
|
||||
dhmv: dhmv.items,
|
||||
floodHazard: floodHazard.items,
|
||||
grb: grb.items,
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((requestError) => {
|
||||
if (!cancelled) {
|
||||
setProducts(EMPTY_PRODUCTS)
|
||||
setError(formatError(requestError, 'De officiële Vlaamse rastercatalogi konden niet worden geladen.'))
|
||||
setError(formatError(requestError, 'De officiële Vlaamse kaartcatalogi konden niet worden geladen.'))
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -26,6 +26,8 @@ import type {
|
||||
BathymetrySourceProbeRead,
|
||||
BathymetrySourceRead,
|
||||
DhmvProductRead,
|
||||
GrbAcquireRequest,
|
||||
GrbProductRead,
|
||||
TerrainSelectionResponse,
|
||||
ThematicRasterAcquireRequest,
|
||||
ThematicRasterProductRead,
|
||||
@@ -146,6 +148,10 @@ export const datasetsApi = {
|
||||
apiPost<JobRead>(`/api/v1/projects/${projectId}/datasets/dhmv/acquire`, payload),
|
||||
listDhmvProducts: (projectId: string): Promise<{ items: DhmvProductRead[]; total: number }> =>
|
||||
apiGet<{ items: DhmvProductRead[]; total: number }>(`/api/v1/projects/${projectId}/datasets/dhmv/products`),
|
||||
acquireGrb: (projectId: string, payload: GrbAcquireRequest): Promise<JobRead> =>
|
||||
apiPost<JobRead>(`/api/v1/projects/${projectId}/datasets/grb/acquire`, payload),
|
||||
listGrbProducts: (projectId: string): Promise<{ items: GrbProductRead[]; total: number }> =>
|
||||
apiGet<{ items: GrbProductRead[]; total: number }>(`/api/v1/projects/${projectId}/datasets/grb/products`),
|
||||
selectTerrain: (
|
||||
projectId: string,
|
||||
datasetId: string,
|
||||
|
||||
@@ -362,6 +362,27 @@ export interface DhmvProductRead {
|
||||
limitation_message: string
|
||||
}
|
||||
|
||||
export interface GrbAcquireRequest {
|
||||
bbox: VectorSelectionBBox
|
||||
area_id?: string | null
|
||||
product_key: 'buildings' | 'roads' | 'water' | 'parcels'
|
||||
force_refresh?: boolean
|
||||
}
|
||||
|
||||
export interface GrbProductRead {
|
||||
key: 'buildings' | 'roads' | 'water' | 'parcels'
|
||||
display_name: string
|
||||
reference_layer_name: string
|
||||
collections: string[]
|
||||
geometry_types: string[]
|
||||
source_crs: 'EPSG:4326'
|
||||
authority_level: 'authoritative'
|
||||
catalog_url: string
|
||||
attribution: string
|
||||
license_note: string
|
||||
limitation_message: string
|
||||
}
|
||||
|
||||
export interface TerrainSelectionResponse {
|
||||
dataset_id: string
|
||||
dataset_ids: string[]
|
||||
|
||||
Reference in New Issue
Block a user