Add bounded terrain and flood analysis
This commit is contained in:
@@ -6,18 +6,26 @@ import { terrainSelectionToMapSelection } from '../lib/terrainSelection'
|
||||
import { floodHazardSelectionToMapSelection } from '../lib/floodHazardSelection'
|
||||
import { thematicRasterSelectionToMapSelection } from '../lib/thematicRaster'
|
||||
|
||||
export type MapThemeAcquisitionKind = 'thematic_raster' | 'dhmv' | 'flood_hazard'
|
||||
|
||||
export interface MapThemeAcquisition {
|
||||
kind: MapThemeAcquisitionKind
|
||||
productKey: string
|
||||
displayName: string
|
||||
}
|
||||
|
||||
export interface MapThemeQuery<TThemeId extends string> {
|
||||
themeId: TThemeId
|
||||
dataset?: DatasetCreateResponse
|
||||
partitioned?: boolean
|
||||
thematicProductKey?: string
|
||||
acquisition?: MapThemeAcquisition
|
||||
}
|
||||
|
||||
export interface MapThemeInsight<TThemeId extends string> {
|
||||
themeId: TThemeId
|
||||
dataset: DatasetCreateResponse
|
||||
partitioned?: boolean
|
||||
thematicProductKey?: string
|
||||
acquisition?: MapThemeAcquisition
|
||||
result: VectorSelectionResponse
|
||||
}
|
||||
|
||||
@@ -61,22 +69,36 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
|
||||
setThemeInsightsError(null)
|
||||
try {
|
||||
const settled = await Promise.allSettled(
|
||||
queries.map(async ({ themeId, dataset: existingDataset, partitioned, thematicProductKey }) => {
|
||||
queries.map(async ({ themeId, dataset: existingDataset, partitioned, acquisition }) => {
|
||||
let dataset = existingDataset
|
||||
if (thematicProductKey) {
|
||||
const acquisition = await datasetsApi.acquireThematicRaster(selectedProjectId, {
|
||||
bbox,
|
||||
area_id: areaId,
|
||||
product_key: thematicProductKey,
|
||||
force_refresh: false,
|
||||
})
|
||||
if (acquisition.status !== 'success' || !acquisition.output_dataset_id) {
|
||||
if (acquisition) {
|
||||
const acquisitionJob = acquisition.kind === 'thematic_raster'
|
||||
? await datasetsApi.acquireThematicRaster(selectedProjectId, {
|
||||
bbox,
|
||||
area_id: areaId,
|
||||
product_key: acquisition.productKey,
|
||||
force_refresh: false,
|
||||
})
|
||||
: acquisition.kind === 'dhmv'
|
||||
? await datasetsApi.acquireDhmv(selectedProjectId, {
|
||||
bbox,
|
||||
area_id: areaId,
|
||||
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,
|
||||
})
|
||||
if (acquisitionJob.status !== 'success' || !acquisitionJob.output_dataset_id) {
|
||||
throw new Error(
|
||||
acquisition.error_message
|
||||
|| `De officiële rasterbron ${thematicProductKey} kon niet worden ingeladen.`,
|
||||
acquisitionJob.error_message
|
||||
|| `De officiële rasterbron ${acquisition.displayName} kon niet worden ingeladen.`,
|
||||
)
|
||||
}
|
||||
dataset = await datasetsApi.get(selectedProjectId, acquisition.output_dataset_id)
|
||||
dataset = await datasetsApi.get(selectedProjectId, acquisitionJob.output_dataset_id)
|
||||
}
|
||||
if (!dataset) {
|
||||
throw new Error(`Geen persistente databron beschikbaar voor thema ${themeId}.`)
|
||||
@@ -85,7 +107,7 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
|
||||
themeId,
|
||||
dataset,
|
||||
partitioned,
|
||||
thematicProductKey,
|
||||
acquisition,
|
||||
result: dataset.dataset_type === 'raster' && dataset.source_name === 'digitaal_vlaanderen_dhmv'
|
||||
? terrainSelectionToMapSelection(
|
||||
partitioned
|
||||
@@ -137,7 +159,7 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
|
||||
? [{
|
||||
dataset:
|
||||
queries[index]?.dataset?.name
|
||||
?? queries[index]?.thematicProductKey
|
||||
?? queries[index]?.acquisition?.displayName
|
||||
?? queries[index]?.themeId
|
||||
?? 'Onbekende bron',
|
||||
reason: formatError(item.reason, 'Bron kon niet worden bevraagd.'),
|
||||
@@ -150,7 +172,7 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
|
||||
}
|
||||
setThemeInsights(successful)
|
||||
let refreshFailure: string | null = null
|
||||
if (successful.some((item) => item.thematicProductKey) && onDatasetsChanged) {
|
||||
if (successful.some((item) => item.acquisition) && onDatasetsChanged) {
|
||||
try {
|
||||
await onDatasetsChanged()
|
||||
} catch (error) {
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { datasetsApi } from '../services/api'
|
||||
import { formatError } from '../lib/formatError'
|
||||
import type {
|
||||
DhmvProductRead,
|
||||
FloodHazardProductRead,
|
||||
ThematicRasterProductRead,
|
||||
} from '../types'
|
||||
|
||||
interface OfficialRasterProducts {
|
||||
thematic: ThematicRasterProductRead[]
|
||||
dhmv: DhmvProductRead[]
|
||||
floodHazard: FloodHazardProductRead[]
|
||||
}
|
||||
|
||||
const EMPTY_PRODUCTS: OfficialRasterProducts = {
|
||||
thematic: [],
|
||||
dhmv: [],
|
||||
floodHazard: [],
|
||||
}
|
||||
|
||||
export function useOfficialRasterProducts(selectedProjectId: string | null) {
|
||||
const [products, setProducts] = useState<OfficialRasterProducts>(EMPTY_PRODUCTS)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
if (!selectedProjectId) {
|
||||
setProducts(EMPTY_PRODUCTS)
|
||||
setLoading(false)
|
||||
setError(null)
|
||||
return () => {
|
||||
cancelled = true
|
||||
}
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
void Promise.all([
|
||||
datasetsApi.listThematicRasterProducts(selectedProjectId),
|
||||
datasetsApi.listDhmvProducts(selectedProjectId),
|
||||
datasetsApi.listFloodHazardProducts(selectedProjectId),
|
||||
])
|
||||
.then(([thematic, dhmv, floodHazard]) => {
|
||||
if (!cancelled) {
|
||||
setProducts({
|
||||
thematic: thematic.items,
|
||||
dhmv: dhmv.items,
|
||||
floodHazard: floodHazard.items,
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((requestError) => {
|
||||
if (!cancelled) {
|
||||
setProducts(EMPTY_PRODUCTS)
|
||||
setError(formatError(requestError, 'De officiële Vlaamse rastercatalogi konden niet worden geladen.'))
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
if (!cancelled) {
|
||||
setLoading(false)
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
cancelled = true
|
||||
}
|
||||
}, [selectedProjectId])
|
||||
|
||||
return { products, loading, error }
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { datasetsApi } from '../services/api'
|
||||
import { formatError } from '../lib/formatError'
|
||||
import type { ThematicRasterProductRead } from '../types'
|
||||
|
||||
export function useThematicRasterProducts(selectedProjectId: string | null) {
|
||||
const [products, setProducts] = useState<ThematicRasterProductRead[]>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
if (!selectedProjectId) {
|
||||
setProducts([])
|
||||
setLoading(false)
|
||||
setError(null)
|
||||
return () => {
|
||||
cancelled = true
|
||||
}
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
void datasetsApi.listThematicRasterProducts(selectedProjectId)
|
||||
.then((response) => {
|
||||
if (!cancelled) {
|
||||
setProducts(response.items)
|
||||
}
|
||||
})
|
||||
.catch((requestError) => {
|
||||
if (!cancelled) {
|
||||
setProducts([])
|
||||
setError(formatError(requestError, 'De Vlaamse beleidsrasters konden niet worden geladen.'))
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
if (!cancelled) {
|
||||
setLoading(false)
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
cancelled = true
|
||||
}
|
||||
}, [selectedProjectId])
|
||||
|
||||
return { products, loading, error }
|
||||
}
|
||||
Reference in New Issue
Block a user