Add bounded Flanders thematic analysis
This commit is contained in:
@@ -8,16 +8,22 @@ import { thematicRasterSelectionToMapSelection } from '../lib/thematicRaster'
|
||||
|
||||
export interface MapThemeQuery<TThemeId extends string> {
|
||||
themeId: TThemeId
|
||||
dataset: DatasetCreateResponse
|
||||
dataset?: DatasetCreateResponse
|
||||
partitioned?: boolean
|
||||
thematicProductKey?: string
|
||||
}
|
||||
|
||||
export interface MapThemeInsight<TThemeId extends string> extends MapThemeQuery<TThemeId> {
|
||||
export interface MapThemeInsight<TThemeId extends string> {
|
||||
themeId: TThemeId
|
||||
dataset: DatasetCreateResponse
|
||||
partitioned?: boolean
|
||||
thematicProductKey?: string
|
||||
result: VectorSelectionResponse
|
||||
}
|
||||
|
||||
export function useMapThemeSelectionInsights<TThemeId extends string>(
|
||||
selectedProjectId: string | null,
|
||||
onDatasetsChanged?: () => Promise<unknown>,
|
||||
) {
|
||||
const [themeInsights, setThemeInsights] = useState<Array<MapThemeInsight<TThemeId>>>([])
|
||||
const [themeInsightsLoading, setThemeInsightsLoading] = useState(false)
|
||||
@@ -55,10 +61,32 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
|
||||
setThemeInsightsError(null)
|
||||
try {
|
||||
const settled = await Promise.allSettled(
|
||||
queries.map(async ({ themeId, dataset, partitioned }) => ({
|
||||
themeId,
|
||||
dataset,
|
||||
result: dataset.dataset_type === 'raster' && dataset.source_name === 'digitaal_vlaanderen_dhmv'
|
||||
queries.map(async ({ themeId, dataset: existingDataset, partitioned, thematicProductKey }) => {
|
||||
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) {
|
||||
throw new Error(
|
||||
acquisition.error_message
|
||||
|| `De officiële rasterbron ${thematicProductKey} kon niet worden ingeladen.`,
|
||||
)
|
||||
}
|
||||
dataset = await datasetsApi.get(selectedProjectId, acquisition.output_dataset_id)
|
||||
}
|
||||
if (!dataset) {
|
||||
throw new Error(`Geen persistente databron beschikbaar voor thema ${themeId}.`)
|
||||
}
|
||||
return {
|
||||
themeId,
|
||||
dataset,
|
||||
partitioned,
|
||||
thematicProductKey,
|
||||
result: dataset.dataset_type === 'raster' && dataset.source_name === 'digitaal_vlaanderen_dhmv'
|
||||
? terrainSelectionToMapSelection(
|
||||
partitioned
|
||||
? await datasetsApi.selectTerrainPartitions(selectedProjectId, {
|
||||
@@ -100,13 +128,18 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
|
||||
area_id: areaId,
|
||||
limit: 1000,
|
||||
}),
|
||||
})),
|
||||
}
|
||||
}),
|
||||
)
|
||||
const successful = settled.flatMap((item) => (item.status === 'fulfilled' ? [item.value] : []))
|
||||
const failures = settled.flatMap((item, index) => (
|
||||
item.status === 'rejected'
|
||||
? [{
|
||||
dataset: queries[index]?.dataset.name ?? queries[index]?.themeId ?? 'Onbekende bron',
|
||||
dataset:
|
||||
queries[index]?.dataset?.name
|
||||
?? queries[index]?.thematicProductKey
|
||||
?? queries[index]?.themeId
|
||||
?? 'Onbekende bron',
|
||||
reason: formatError(item.reason, 'Bron kon niet worden bevraagd.'),
|
||||
}]
|
||||
: []
|
||||
@@ -116,6 +149,14 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
|
||||
return []
|
||||
}
|
||||
setThemeInsights(successful)
|
||||
let refreshFailure: string | null = null
|
||||
if (successful.some((item) => item.thematicProductKey) && onDatasetsChanged) {
|
||||
try {
|
||||
await onDatasetsChanged()
|
||||
} catch (error) {
|
||||
refreshFailure = formatError(error, 'De datasetlijst kon na de analyse niet worden vernieuwd.')
|
||||
}
|
||||
}
|
||||
if (failureCount > 0) {
|
||||
const details = failures
|
||||
.slice(0, 4)
|
||||
@@ -125,6 +166,8 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
|
||||
setThemeInsightsError(
|
||||
`${failureCount} beschikbare databron${failureCount === 1 ? '' : 'nen'} kon niet worden bevraagd. ${details}${remainder}`,
|
||||
)
|
||||
} else if (refreshFailure) {
|
||||
setThemeInsightsError(refreshFailure)
|
||||
}
|
||||
return successful
|
||||
} catch (error) {
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
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