feat: operationalize Flemish land and nature themes
This commit is contained in:
@@ -704,3 +704,12 @@ A regional rectangle or full-Area analysis calls the partitioned backend
|
||||
selection and draws only its bounded GeoJSON result. Switching to a
|
||||
municipality automatically returns to the exact single-Area Dataset. Regional
|
||||
downloads are recomputed server-side through the same manifest-aware path.
|
||||
|
||||
## On-demand forest, agriculture, nature and soil
|
||||
|
||||
In the Flanders workspace, `Bos`, `Landbouw`, `Natuurwaarde` and `Bodem` are
|
||||
discoverable before local provisioning. They remain `Op aanvraag` until the
|
||||
user selects a municipality or draws a bounded rectangle. Forest and
|
||||
agriculture use thematic raster analysis; nature value and soil use the
|
||||
persisted-vector GeoJSON pattern. The browser calls only the GeoIntel API and
|
||||
never contacts WCS, WFS or OGC providers directly.
|
||||
|
||||
@@ -777,6 +777,11 @@ export function MapWorkspace({
|
||||
result[product.key] = null
|
||||
}
|
||||
}
|
||||
if (flandersScopeSelected && officialMapProducts.officialVector.length > 0) {
|
||||
for (const product of officialMapProducts.officialVector) {
|
||||
result[product.theme] = null
|
||||
}
|
||||
}
|
||||
return result
|
||||
}, [
|
||||
availableMapDatasets,
|
||||
@@ -785,6 +790,7 @@ export function MapWorkspace({
|
||||
officialMapProducts.dhmv.length,
|
||||
officialMapProducts.floodHazard.length,
|
||||
officialMapProducts.grb,
|
||||
officialMapProducts.officialVector,
|
||||
regionalScopeSelected,
|
||||
selectedDhmvProductKey,
|
||||
selectedFloodHazardDatasetId,
|
||||
@@ -835,6 +841,17 @@ export function MapWorkspace({
|
||||
limitationMessage: product.limitation_message,
|
||||
})
|
||||
}
|
||||
for (const product of officialMapProducts.officialVector) {
|
||||
result.set(product.theme, {
|
||||
kind: 'official_vector',
|
||||
productKey: product.key,
|
||||
displayName: product.display_name,
|
||||
theme: product.theme,
|
||||
availabilityLabel: `${product.observation_label} · 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', {
|
||||
|
||||
@@ -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' | 'grb'
|
||||
export type MapThemeAcquisitionKind = 'thematic_raster' | 'dhmv' | 'flood_hazard' | 'grb' | 'official_vector'
|
||||
|
||||
export interface MapThemeAcquisition {
|
||||
kind: MapThemeAcquisitionKind
|
||||
@@ -92,10 +92,15 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
|
||||
...commonPayload,
|
||||
product_key: acquisition.productKey,
|
||||
})
|
||||
: await datasetsApi.acquireGrb(selectedProjectId, {
|
||||
...commonPayload,
|
||||
product_key: acquisition.productKey as 'buildings' | 'roads' | 'water' | 'parcels',
|
||||
})
|
||||
: acquisition.kind === 'grb'
|
||||
? await datasetsApi.acquireGrb(selectedProjectId, {
|
||||
...commonPayload,
|
||||
product_key: acquisition.productKey as 'buildings' | 'roads' | 'water' | 'parcels',
|
||||
})
|
||||
: await datasetsApi.acquireOfficialVector(selectedProjectId, {
|
||||
...commonPayload,
|
||||
product_key: acquisition.productKey,
|
||||
})
|
||||
if (acquisitionJob.status !== 'success' || !acquisitionJob.output_dataset_id) {
|
||||
throw new Error(
|
||||
acquisitionJob.error_message
|
||||
|
||||
@@ -5,6 +5,7 @@ import type {
|
||||
DhmvProductRead,
|
||||
FloodHazardProductRead,
|
||||
GrbProductRead,
|
||||
OfficialVectorProductRead,
|
||||
ThematicRasterProductRead,
|
||||
} from '../types'
|
||||
|
||||
@@ -13,6 +14,7 @@ interface OfficialMapProducts {
|
||||
dhmv: DhmvProductRead[]
|
||||
floodHazard: FloodHazardProductRead[]
|
||||
grb: GrbProductRead[]
|
||||
officialVector: OfficialVectorProductRead[]
|
||||
}
|
||||
|
||||
const EMPTY_PRODUCTS: OfficialMapProducts = {
|
||||
@@ -20,6 +22,7 @@ const EMPTY_PRODUCTS: OfficialMapProducts = {
|
||||
dhmv: [],
|
||||
floodHazard: [],
|
||||
grb: [],
|
||||
officialVector: [],
|
||||
}
|
||||
|
||||
export function useOfficialMapProducts(selectedProjectId: string | null) {
|
||||
@@ -45,14 +48,16 @@ export function useOfficialMapProducts(selectedProjectId: string | null) {
|
||||
datasetsApi.listDhmvProducts(selectedProjectId),
|
||||
datasetsApi.listFloodHazardProducts(selectedProjectId),
|
||||
datasetsApi.listGrbProducts(selectedProjectId),
|
||||
datasetsApi.listOfficialVectorProducts(selectedProjectId),
|
||||
])
|
||||
.then(([thematic, dhmv, floodHazard, grb]) => {
|
||||
.then(([thematic, dhmv, floodHazard, grb, officialVector]) => {
|
||||
if (!cancelled) {
|
||||
setProducts({
|
||||
thematic: thematic.items,
|
||||
dhmv: dhmv.items,
|
||||
floodHazard: floodHazard.items,
|
||||
grb: grb.items,
|
||||
officialVector: officialVector.items,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -28,6 +28,8 @@ import type {
|
||||
DhmvProductRead,
|
||||
GrbAcquireRequest,
|
||||
GrbProductRead,
|
||||
OfficialVectorAcquireRequest,
|
||||
OfficialVectorProductRead,
|
||||
TerrainSelectionResponse,
|
||||
ThematicRasterAcquireRequest,
|
||||
ThematicRasterProductRead,
|
||||
@@ -152,6 +154,14 @@ export const datasetsApi = {
|
||||
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`),
|
||||
acquireOfficialVector: (projectId: string, payload: OfficialVectorAcquireRequest): Promise<JobRead> =>
|
||||
apiPost<JobRead>(`/api/v1/projects/${projectId}/datasets/official-vector/acquire`, payload),
|
||||
listOfficialVectorProducts: (
|
||||
projectId: string,
|
||||
): Promise<{ items: OfficialVectorProductRead[]; total: number }> =>
|
||||
apiGet<{ items: OfficialVectorProductRead[]; total: number }>(
|
||||
`/api/v1/projects/${projectId}/datasets/official-vector/products`,
|
||||
),
|
||||
selectTerrain: (
|
||||
projectId: string,
|
||||
datasetId: string,
|
||||
|
||||
+29
-1
@@ -383,6 +383,33 @@ export interface GrbProductRead {
|
||||
limitation_message: string
|
||||
}
|
||||
|
||||
export interface OfficialVectorAcquireRequest {
|
||||
bbox: VectorSelectionBBox
|
||||
area_id?: string | null
|
||||
product_key: string
|
||||
force_refresh?: boolean
|
||||
}
|
||||
|
||||
export interface OfficialVectorProductRead {
|
||||
key: string
|
||||
display_name: string
|
||||
theme: 'nature_value' | 'soil'
|
||||
provider: string
|
||||
source_name: string
|
||||
reference_layer_name: string
|
||||
service_type: 'OGC API Features' | 'WFS 2.0'
|
||||
collection: string
|
||||
geometry_types: string[]
|
||||
source_crs: string
|
||||
source_version: string
|
||||
observation_label: string
|
||||
authority_level: 'authoritative' | 'authoritative_historical_baseline'
|
||||
catalog_url: string
|
||||
attribution: string
|
||||
license_note: string
|
||||
limitation_message: string
|
||||
}
|
||||
|
||||
export interface TerrainSelectionResponse {
|
||||
dataset_id: string
|
||||
dataset_ids: string[]
|
||||
@@ -524,7 +551,7 @@ export interface ThematicRasterAcquireRequest {
|
||||
export interface ThematicRasterProductRead {
|
||||
key: string
|
||||
display_name: string
|
||||
theme: 'space_occupation' | 'open_space' | 'population' | 'accessibility' | 'services'
|
||||
theme: 'space_occupation' | 'open_space' | 'forest' | 'agriculture' | 'population' | 'accessibility' | 'services'
|
||||
metric_kind: 'binary_area' | 'population_density' | 'index_score' | 'normalized_score'
|
||||
coverage_id: string
|
||||
native_resolution_m: number
|
||||
@@ -537,6 +564,7 @@ export interface ThematicRasterProductRead {
|
||||
license_note: string
|
||||
legend_min_label: string
|
||||
legend_max_label: string
|
||||
included_source_values: number[]
|
||||
limitation_message: string
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user