feat: complete Wallonia land cover and terrain sources
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-22 06:28:46 +02:00
parent d45d34186d
commit cee6cd05ae
46 changed files with 2542 additions and 276 deletions
+10 -4
View File
@@ -766,16 +766,22 @@ never contacts WCS, WFS or OGC providers directly.
## Walloon current and historical land cover
For a bounded Walloon selection, `Landbedekking` resolves the newest configured
WALOUS product and automatically persists the other configured comparable
edition for the same rectangle. Current analysis shows semantic hectare
WALOUS product and automatically persists the other configured governed
editions for the same rectangle. Current analysis shows semantic hectare
metrics and an 11-class MapLibre image overlay. After dataset refresh,
`Evolutie` offers 2020 versus 2023 through the same period selector and trend
chart used by other temporal sources. Individual object-change counts remain
`Evolutie` offers 2018, 2020 and 2023 through the same period selector and
trend chart used by other temporal sources, with the 2018 visible-class
crosswalk and methodology warning retained. Individual object-change counts remain
unavailable for categorical rasters and are not simulated.
The source card remains `Op aanvraag` when the official source files are not
provisioned and never contacts SPW directly from the browser.
For Walloon elevation, the same regional resolution selects the configured
SPW MNT 2021-2022 product, persists only the bounded derivative and labels
height in `m DNG`. Flemish DHMV stays in `m TAW`; the UI never merges those
vertical references.
## Belgium and Belgian North Sea coverage
When `Belgium and North Sea Workbench` exists with ready reference data, it is
+1 -1
View File
@@ -216,7 +216,7 @@ function App(): JSX.Element {
() => {
const vectors = datasets.filter((dataset) => isVectorDatasetType(dataset.dataset_type) && dataset.status === 'ready')
const terrain = datasets.filter(
(dataset) => dataset.dataset_type === 'raster' && dataset.source_name === 'digitaal_vlaanderen_dhmv' && dataset.status === 'ready',
(dataset) => dataset.dataset_type === 'raster' && ['digitaal_vlaanderen_dhmv', 'spw_terrain'].includes(dataset.source_name ?? '') && dataset.status === 'ready',
)
const floodHazards = datasets.filter(
(dataset) => dataset.dataset_type === 'raster' && dataset.source_name === 'vmm_flood_hazard' && dataset.status === 'ready',
@@ -45,6 +45,7 @@ const ANALYTICAL_SOURCE_NAMES = new Set([
'agentschap_landbouw_zeevisserij_agricultural_parcels',
'dov_soil_map',
'digitaal_vlaanderen_dhmv',
'spw_terrain',
'vmm_flood_hazard',
'vmm_vha_bathymetry_profiles',
])
@@ -100,7 +100,7 @@ export function SourceCatalogPanel({
const buildingsRegisterDatasets = ready.filter(
(dataset) => dataset.source_name === 'digitaal_vlaanderen_buildings_addresses_register',
)
const dhmvDatasets = ready.filter((dataset) => dataset.source_name === 'digitaal_vlaanderen_dhmv')
const dhmvDatasets = ready.filter((dataset) => ['digitaal_vlaanderen_dhmv', 'spw_terrain'].includes(dataset.source_name ?? ''))
const floodHazardDatasets = ready.filter((dataset) => dataset.source_name === 'vmm_flood_hazard')
const bathymetryProfileDatasets = ready.filter(
(dataset) => dataset.source_name === 'vmm_vha_bathymetry_profiles',
@@ -310,11 +310,11 @@ export function DetectionLab({
<p className="ai-quality-guidance">
{detectionQualityInterpretation(selectedOperatorProfile?.f1)}
</p>
{selectedOperatorProfile && !selectedOperatorProfile.nationallyValidated ? (
{selectedOperatorProfile && selectedDetectionModel?.nationally_validated !== true ? (
<div className="result-state result-state-warning" role="status">
<strong>Nog niet nationaal gevalideerd</strong>
<p>
Dit model is operationeel voor gecontroleerde beeldanalyse, maar de gemeten kwaliteit geldt alleen voor {selectedOperatorProfile.validationScope}.
Dit model is operationeel voor gecontroleerde beeldanalyse, maar de gemeten kwaliteit geldt alleen voor {selectedDetectionModel?.validation_scope ?? selectedOperatorProfile.validationScope}.
Resultaten elders in Belgie of op zee vereisen lokale referentiedata en QA voordat ze als betrouwbaar kunnen worden vrijgegeven.
</p>
</div>
@@ -11,7 +11,6 @@ export interface DetectionOperatorProfile {
positiveSampleCount: number
maxBackgroundDetections: number
validationScope: string
nationallyValidated: boolean
description: string
limitationMessage: string
}
@@ -30,7 +29,6 @@ export const DETECTION_OPERATOR_PROFILES: DetectionOperatorProfile[] = [
positiveSampleCount: 7,
maxBackgroundDetections: 0,
validationScope: '7 onafhankelijke testgebieden in Mol en de Kempen',
nationallyValidated: false,
description:
'Aanbevolen profiel met een evenwicht tussen gevonden en gemiste kleine gebouwen, opnieuw gemeten over zeven onafhankelijke testgebieden in Mol en de Kempen.',
limitationMessage:
@@ -49,7 +47,6 @@ export const DETECTION_OPERATOR_PROFILES: DetectionOperatorProfile[] = [
positiveSampleCount: 7,
maxBackgroundDetections: 0,
validationScope: '7 onafhankelijke testgebieden in Mol en de Kempen',
nationallyValidated: false,
description: 'Voorgaand profiel voor controles waarbij minder foutieve vondsten belangrijker zijn dan maximale dekking.',
limitationMessage:
'De lege-achtergrondtest is geslaagd. Dit profiel vindt minder onterechte objecten, maar mist meer kleine gebouwen dan het aanbevolen profiel.',
@@ -67,7 +64,6 @@ export const DETECTION_OPERATOR_PROFILES: DetectionOperatorProfile[] = [
positiveSampleCount: 7,
maxBackgroundDetections: 0,
validationScope: '7 onafhankelijke testgebieden in Mol en de Kempen',
nationallyValidated: false,
description: 'Profiel met hoge precisie voor controles waarbij zo weinig mogelijk foutieve vondsten zwaarder wegen dan volledige dekking.',
limitationMessage:
'Goedgekeurd na de lege-achtergrondtest. Resultaten in dun bebouwde context blijven altijd controlebewijs en geen automatische waarheid.',
+39 -8
View File
@@ -108,7 +108,7 @@ function productSupportsSelection(product: OnDemandMapProduct, bbox: VectorSelec
const scale = selectionAnalysisScale(bbox)
if (scale === 'overview') return false
const dimensions = selectionDimensions(bbox)
if (product.kind === 'dhmv' || product.kind === 'flood_hazard') {
if (product.kind === 'dhmv' || product.kind === 'spw_terrain' || product.kind === 'flood_hazard') {
return dimensions.areaSquareMetres <= 280_000_000
}
if (product.kind === 'thematic_raster' || product.kind === 'walous') {
@@ -338,7 +338,7 @@ function datasetAvailabilityLabel(
): string {
const partitionCount = partitions.length
const regionalSuffix = partitionCount > 1 ? ` · ${partitionCount} gemeenten` : ''
if (dataset.dataset_type === 'raster' && dataset.source_name === 'digitaal_vlaanderen_dhmv') {
if (dataset.dataset_type === 'raster' && ['digitaal_vlaanderen_dhmv', 'spw_terrain'].includes(dataset.source_name ?? '')) {
const resolution = Number(dataset.source_metadata?.['analysis_resolution_m'])
return `${Number.isFinite(resolution) ? `${resolution.toLocaleString('nl-BE')} m` : 'Raster'} hoogtegrid${regionalSuffix}`
}
@@ -416,7 +416,7 @@ function datasetMatchesTheme(dataset: DatasetCreateResponse, theme: DataTheme):
if (dataset.source_name === 'spw_bathymetry') {
return theme.id === 'bathymetry'
}
if (dataset.source_name === 'digitaal_vlaanderen_dhmv') {
if (['digitaal_vlaanderen_dhmv', 'spw_terrain'].includes(dataset.source_name ?? '')) {
return theme.id === 'elevation'
}
if (dataset.source_name === 'department_omgeving_thematic_raster') {
@@ -444,7 +444,7 @@ function datasetMatchesTheme(dataset: DatasetCreateResponse, theme: DataTheme):
function isPartitionedRaster(dataset: DatasetCreateResponse | null | undefined): boolean {
return Boolean(
dataset?.dataset_type === 'raster'
&& ['digitaal_vlaanderen_dhmv', 'vmm_flood_hazard'].includes(dataset.source_name ?? ''),
&& ['digitaal_vlaanderen_dhmv', 'spw_terrain', 'vmm_flood_hazard'].includes(dataset.source_name ?? ''),
)
}
@@ -544,6 +544,7 @@ function pickThemeDataset(
(dataset.source_name === 'spw_walous_land_cover' ? 5_000_000 : 0) +
(dataset.source_name === 'digitaal_vlaanderen_buildings_addresses_register' ? 5_000_000 : 0) +
(dataset.source_name === 'digitaal_vlaanderen_dhmv' ? 5_000_000 : 0) +
(dataset.source_name === 'spw_terrain' ? 5_000_000 : 0) +
(dataset.source_name === 'vmm_flood_hazard' ? 5_000_000 : 0) +
(dataset.source_name === 'vmm_vha_bathymetry_profiles' ? 5_000_000 : 0) +
(dataset.source_name === 'spw_bathymetry' ? 5_100_000 : 0) +
@@ -873,6 +874,7 @@ export function MapWorkspace({
selectedCoverageZones?.includes('flanders')
|| (!selectedCoverageZones && activeScopeProject?.name === FLANDERS_WORKSPACE_PROJECT_NAME),
)
const walloniaScopeSelected = Boolean(selectedCoverageZones?.includes('wallonia'))
const {
themeInsights,
themeInsightsLoading: themeResultsLoading,
@@ -992,6 +994,14 @@ export function MapWorkspace({
&& datasetCoversSelectedArea(dataset, selectedMapAreaId, selectedMapArea?.name, regionalScopeSelected),
) ?? null
}
if (walloniaScopeSelected && officialMapProducts.spwTerrain.some((product) => product.configured)) {
result.elevation = availableMapDatasets.find(
(dataset) =>
dataset.source_name === 'spw_terrain'
&& datasetProductKey(dataset) === 'spw_mnt_1m_2021_2022'
&& datasetCoversSelectedArea(dataset, selectedMapAreaId, selectedMapArea?.name, regionalScopeSelected),
) ?? null
}
if (flandersScopeSelected && officialMapProducts.thematic.length > 0) {
for (const product of officialMapProducts.thematic) {
if (!result[product.theme]) {
@@ -1021,6 +1031,7 @@ export function MapWorkspace({
flandersScopeSelected,
floodHazardDatasets,
officialMapProducts.dhmv.length,
officialMapProducts.spwTerrain,
officialMapProducts.floodHazard.length,
officialMapProducts.grb,
officialMapProducts.officialVector,
@@ -1032,6 +1043,7 @@ export function MapWorkspace({
selectedMapArea?.name,
selectedMapAreaId,
selectedCoverageZones,
walloniaScopeSelected,
])
const themePartitionMap = useMemo(
() =>
@@ -1066,6 +1078,7 @@ export function MapWorkspace({
effectiveZones?.includes('flanders')
|| (!effectiveZones && activeScopeProject?.name === FLANDERS_WORKSPACE_PROJECT_NAME),
)
const includesWallonia = Boolean(effectiveZones?.includes('wallonia'))
if (includesFlanders) {
for (const product of officialMapProducts.thematic) {
result.push({
@@ -1161,6 +1174,21 @@ export function MapWorkspace({
coverageZones: ['flanders'],
})
}
const spwTerrainProduct = includesWallonia
? officialMapProducts.spwTerrain.find((product) => product.configured)
: null
if (spwTerrainProduct) {
result.push({
kind: 'spw_terrain',
productKey: spwTerrainProduct.key,
displayName: spwTerrainProduct.display_name,
theme: 'elevation',
availabilityLabel: `${spwTerrainProduct.analysis_resolution_m} m analyse · ${spwTerrainProduct.acquisition_period} · automatisch bij selectie`,
attribution: spwTerrainProduct.attribution,
limitationMessage: spwTerrainProduct.limitation_message,
coverageZones: spwTerrainProduct.coverage_zones,
})
}
const floodProduct = includesFlanders
? officialMapProducts.floodHazard.find(
(product) => product.key === selectedFloodHazardProductKey,
@@ -1319,7 +1347,7 @@ export function MapWorkspace({
activeTheme.id === 'elevation' && selectedProjectId
? activeThemePartitions.flatMap((dataset) => {
const bounds = dataset.source_metadata?.['bbox_epsg4326']
return dataset.source_name === 'digitaal_vlaanderen_dhmv'
return ['digitaal_vlaanderen_dhmv', 'spw_terrain'].includes(dataset.source_name ?? '')
&& Array.isArray(bounds)
&& bounds.length === 4
? [{
@@ -1530,7 +1558,7 @@ export function MapWorkspace({
const terrainReliefMetric = activeSupportingMetrics.find((metric) => metric.metric_key === 'relief_m')
const populationDensityMetric = activeSupportingMetrics.find((metric) => metric.metric_key === 'population_density_mean_per_ha')
const scoreMedianMetric = activeSupportingMetrics.find((metric) => metric.metric_key.endsWith('_median'))
const activeSecondaryMetric = activeMetricUnit === 'm TAW'
const activeSecondaryMetric = activeMetricUnit === 'm TAW' || activeMetricUnit === 'm DNG'
? terrainReliefMetric ? `${terrainReliefMetric.metric_value.toLocaleString('nl-BE', { maximumFractionDigits: 2 })} m reliëf` : null
: activeMetricUnit === 'inwoners'
? populationDensityMetric ? selectionMetricLabel(populationDensityMetric) : null
@@ -1543,7 +1571,7 @@ export function MapWorkspace({
: null
const activeSecondaryLabel = activeMetricUnit === 'ha'
? 'Aandeel selectie'
: activeMetricUnit === 'm TAW'
: activeMetricUnit === 'm TAW' || activeMetricUnit === 'm DNG'
? 'Reliëf'
: activeMetricUnit === 'inwoners'
? 'Gemiddelde dichtheid'
@@ -2301,7 +2329,7 @@ export function MapWorkspace({
<p className="error">{officialMapProductsError}</p>
) : null}
{analysisMode === 'current' && activeTheme.id === 'elevation' && officialMapProducts.dhmv.length > 0 ? (
{analysisMode === 'current' && activeTheme.id === 'elevation' && flandersScopeSelected && officialMapProducts.dhmv.length > 0 ? (
<label className="geo-scope-select">
Hoogtemodel
<select
@@ -2334,6 +2362,9 @@ export function MapWorkspace({
<small>DTM meet het maaiveld; DSM bevat ook gebouwen en vegetatie.</small>
</label>
) : null}
{analysisMode === 'current' && activeTheme.id === 'elevation' && walloniaScopeSelected && officialMapProducts.spwTerrain.some((product) => product.configured) ? (
<p className="geo-data-notice">SPW MNT 2021-2022 · 1 m bron · 5 m begrensde analyse · hoogte in m DNG.</p>
) : null}
{analysisMode === 'current' && activeTheme.id === 'flood_hazard' && officialMapProducts.floodHazard.length > 0 ? (
<label className="geo-scope-select">
@@ -108,7 +108,7 @@ export function persistedDatasetSupportsSelection(
const scale = selectionAnalysisScale(bbox)
if (scale === 'overview') return false
const dimensions = selectionDimensions(bbox)
if (dataset.source_name === 'digitaal_vlaanderen_dhmv' || dataset.source_name === 'vmm_flood_hazard') {
if (dataset.source_name === 'digitaal_vlaanderen_dhmv' || dataset.source_name === 'spw_terrain' || dataset.source_name === 'vmm_flood_hazard') {
return dimensions.areaSquareMetres <= 280_000_000
}
if (dataset.source_name === 'department_omgeving_thematic_raster') {
+1 -1
View File
@@ -42,7 +42,7 @@ export function useMapSelectionExtract({
setMapSelectionError('Open a vector dataset before extracting a map area.')
return null
}
const terrainDataset = selectedDataset.dataset_type === 'raster' && selectedDataset.source_name === 'digitaal_vlaanderen_dhmv'
const terrainDataset = selectedDataset.dataset_type === 'raster' && ['digitaal_vlaanderen_dhmv', 'spw_terrain'].includes(selectedDataset.source_name ?? '')
const floodHazardDataset = selectedDataset.dataset_type === 'raster' && selectedDataset.source_name === 'vmm_flood_hazard'
const thematicRasterDataset = selectedDataset.dataset_type === 'raster' && selectedDataset.source_name === 'department_omgeving_thematic_raster'
const bathymetryRasterDataset = selectedDataset.dataset_type === 'raster' && selectedDataset.source_name === 'spw_bathymetry'
@@ -11,6 +11,7 @@ export type MapThemeAcquisitionKind =
| 'thematic_raster'
| 'walous'
| 'dhmv'
| 'spw_terrain'
| 'flood_hazard'
| 'grb'
| 'official_vector'
@@ -136,6 +137,11 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
...commonPayload,
product_key: acquisition.productKey as 'dtm_1m' | 'dsm_1m',
})
: acquisition.kind === 'spw_terrain'
? await datasetsApi.acquireSpwTerrain(selectedProjectId, {
...commonPayload,
product_key: 'spw_mnt_1m_2021_2022',
})
: acquisition.kind === 'flood_hazard'
? await datasetsApi.acquireFloodHazard(selectedProjectId, {
...commonPayload,
@@ -198,9 +204,9 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
const acquiredDatasetIds = acquiredDatasets.map((item) => item.id)
const selectedDatasetIds = acquiredDatasetIds.length > 0 ? acquiredDatasetIds : datasetIds ?? []
const acquiredAsPartitions = acquiredDatasetIds.length > 1
const result = dataset.dataset_type === 'raster' && dataset.source_name === 'digitaal_vlaanderen_dhmv'
const result = dataset.dataset_type === 'raster' && ['digitaal_vlaanderen_dhmv', 'spw_terrain'].includes(dataset.source_name ?? '')
? terrainSelectionToMapSelection(
partitioned || acquiredAsPartitions
dataset.source_name === 'digitaal_vlaanderen_dhmv' && (partitioned || acquiredAsPartitions)
? await datasetsApi.selectTerrainPartitions(selectedProjectId, {
bbox,
area_id: areaId,
+7 -2
View File
@@ -5,6 +5,7 @@ import type {
BathymetrySourceRead,
CoverageResolveResponse,
DhmvProductRead,
SpwTerrainProductRead,
FloodHazardProductRead,
GrbProductRead,
OfficialVectorProductRead,
@@ -16,6 +17,7 @@ export interface OfficialMapProducts {
thematic: ThematicRasterProductRead[]
walous: ThematicRasterProductRead[]
dhmv: DhmvProductRead[]
spwTerrain: SpwTerrainProductRead[]
floodHazard: FloodHazardProductRead[]
grb: GrbProductRead[]
officialVector: OfficialVectorProductRead[]
@@ -26,6 +28,7 @@ const EMPTY_PRODUCTS: OfficialMapProducts = {
thematic: [],
walous: [],
dhmv: [],
spwTerrain: [],
floodHazard: [],
grb: [],
officialVector: [],
@@ -54,17 +57,19 @@ export function useOfficialMapProducts(selectedProjectId: string | null) {
datasetsApi.listThematicRasterProducts(selectedProjectId),
datasetsApi.listWalousProducts(selectedProjectId),
datasetsApi.listDhmvProducts(selectedProjectId),
datasetsApi.listSpwTerrainProducts(selectedProjectId),
datasetsApi.listFloodHazardProducts(selectedProjectId),
datasetsApi.listGrbProducts(selectedProjectId),
datasetsApi.listOfficialVectorProducts(selectedProjectId),
datasetsApi.listBathymetrySources(selectedProjectId),
])
.then(([thematic, walous, dhmv, floodHazard, grb, officialVector, bathymetry]) => {
.then(([thematic, walous, dhmv, spwTerrain, floodHazard, grb, officialVector, bathymetry]) => {
if (!cancelled) {
setProducts({
thematic: thematic.items,
walous: walous.items,
dhmv: dhmv.items,
spwTerrain: spwTerrain.items,
floodHazard: floodHazard.items,
grb: grb.items,
officialVector: officialVector.items,
@@ -75,7 +80,7 @@ export function useOfficialMapProducts(selectedProjectId: string | null) {
.catch((requestError) => {
if (!cancelled) {
setProducts(EMPTY_PRODUCTS)
setError(formatError(requestError, 'De officiële Vlaamse kaartcatalogi konden niet worden geladen.'))
setError(formatError(requestError, 'De officiële regionale kaartcatalogi konden niet worden geladen.'))
}
})
.finally(() => {
+1
View File
@@ -3,6 +3,7 @@ import type { DatasetCreateResponse } from '../types'
const NON_IMAGERY_RASTER_SOURCES = new Set([
'department_omgeving_thematic_raster',
'digitaal_vlaanderen_dhmv',
'spw_terrain',
'vmm_flood_hazard',
'spw_bathymetry',
'spw_walous_land_cover',
+5
View File
@@ -29,6 +29,7 @@ const DATASET_SOURCE_LABELS: Record<string, string> = {
digitaal_vlaanderen_orthophoto: 'Digitaal Vlaanderen',
digitaal_vlaanderen_buildings_addresses_register: 'Digitaal Vlaanderen',
digitaal_vlaanderen_dhmv: 'Digitaal Vlaanderen',
spw_terrain: 'Service public de Wallonie',
grb: 'GRB',
historical_landuse: 'Digitaal Vlaanderen',
inbo_bwk_natura2000: 'INBO',
@@ -54,6 +55,10 @@ export function getDatasetDisplayName(dataset: DatasetCreateResponse): string {
const productName = dataset.source_metadata?.['product_display_name']
return typeof productName === 'string' && productName.trim() ? productName : 'DHMV II hoogtemodel'
}
if (dataset.source_name === 'spw_terrain') {
const productName = dataset.source_metadata?.['product_display_name']
return typeof productName === 'string' && productName.trim() ? productName : 'SPW terreinmodel 2021-2022'
}
if (dataset.source_name === 'vmm_flood_hazard') {
const productName = dataset.source_metadata?.['product_display_name']
return typeof productName === 'string' && productName.trim() ? productName : 'VMM-overstromingsscenario'
+2 -2
View File
@@ -199,10 +199,10 @@ export const OFFICIAL_SOURCE_PORTFOLIO: OfficialSourceDefinition[] = [
owner: 'Digitaal Vlaanderen',
coverage: 'DTM/DSM, opname 2013-2015',
value: 'Hoogte, reliëf en helling als gemeten terreinbasis.',
metricExamples: 'hoogte m TAW, reliëf en helling in graden',
metricExamples: 'hoogte in de regionale verticale referentie, reliëf en helling in graden',
priority: 'next',
url: 'https://www.vlaanderen.be/digitaal-vlaanderen/onze-diensten-en-platformen/earth-observation-data-science-eodas/het-digitaal-hoogtemodel/digitaal-hoogtemodel-vlaanderen-ii',
matches: (dataset) => sourceNameIs(dataset, 'digitaal_vlaanderen_dhmv'),
matches: (dataset) => sourceNameIs(dataset, 'digitaal_vlaanderen_dhmv') || sourceNameIs(dataset, 'spw_terrain'),
},
{
key: 'soil_map',
+6
View File
@@ -27,6 +27,8 @@ import type {
BathymetrySourceProbeRead,
BathymetrySourceRead,
DhmvProductRead,
SpwTerrainAcquireRequest,
SpwTerrainProductRead,
GrbAcquireRequest,
GrbProductRead,
OfficialVectorAcquireRequest,
@@ -151,6 +153,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`),
acquireSpwTerrain: (projectId: string, payload: SpwTerrainAcquireRequest): Promise<JobRead> =>
apiPost<JobRead>(`/api/v1/projects/${projectId}/datasets/spw-terrain/acquire`, payload),
listSpwTerrainProducts: (projectId: string): Promise<{ items: SpwTerrainProductRead[]; total: number }> =>
apiGet<{ items: SpwTerrainProductRead[]; total: number }>(`/api/v1/projects/${projectId}/datasets/spw-terrain/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 }> =>
+32
View File
@@ -362,6 +362,33 @@ export interface DhmvProductRead {
limitation_message: string
}
export interface SpwTerrainAcquireRequest {
bbox: VectorSelectionBBox
area_id?: string | null
product_key?: 'spw_mnt_1m_2021_2022'
resolution_m?: number | null
force_refresh?: boolean
}
export interface SpwTerrainProductRead {
key: 'spw_mnt_1m_2021_2022'
display_name: string
surface_model: 'terrain'
source_filename: string
native_resolution_m: number
analysis_resolution_m: number
source_crs: 'EPSG:3812'
vertical_reference: string
acquisition_period: string
catalog_url: string
attribution: string
license_note: string
limitation_message: string
coverage_zones: string[]
configured: boolean
status: string
}
export interface GrbAcquireRequest {
bbox: VectorSelectionBBox
area_id?: string | null
@@ -1156,6 +1183,11 @@ export interface DetectionModelCapability {
status: string
limitation_message: string
version?: string | null
training_scope?: string | null
validation_scope?: string | null
validated_regions: string[]
nationally_validated: boolean
operator_review_required: boolean
}
export interface DetectionModelsResponse {