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
+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 {