162 lines
4.7 KiB
TypeScript
162 lines
4.7 KiB
TypeScript
import { useCallback, useEffect, useState } from 'react'
|
|
import { datasetsApi, externalApi } from '../services/api'
|
|
import { formatError } from '../lib/formatError'
|
|
import type {
|
|
BathymetrySourceRead,
|
|
CoverageResolveResponse,
|
|
DhmvProductRead,
|
|
SpwTerrainProductRead,
|
|
FloodHazardProductRead,
|
|
GrbProductRead,
|
|
OfficialVectorProductRead,
|
|
ThematicRasterProductRead,
|
|
VectorSelectionBBox,
|
|
} from '../types'
|
|
|
|
export interface OfficialMapProducts {
|
|
thematic: ThematicRasterProductRead[]
|
|
walous: ThematicRasterProductRead[]
|
|
dhmv: DhmvProductRead[]
|
|
spwTerrain: SpwTerrainProductRead[]
|
|
floodHazard: FloodHazardProductRead[]
|
|
grb: GrbProductRead[]
|
|
officialVector: OfficialVectorProductRead[]
|
|
bathymetry: BathymetrySourceRead[]
|
|
}
|
|
|
|
const EMPTY_PRODUCTS: OfficialMapProducts = {
|
|
thematic: [],
|
|
walous: [],
|
|
dhmv: [],
|
|
spwTerrain: [],
|
|
floodHazard: [],
|
|
grb: [],
|
|
officialVector: [],
|
|
bathymetry: [],
|
|
}
|
|
|
|
export function useOfficialMapProducts(selectedProjectId: string | null) {
|
|
const [products, setProducts] = useState<OfficialMapProducts>(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.listWalousProducts(selectedProjectId),
|
|
datasetsApi.listDhmvProducts(selectedProjectId),
|
|
datasetsApi.listSpwTerrainProducts(selectedProjectId),
|
|
datasetsApi.listFloodHazardProducts(selectedProjectId),
|
|
datasetsApi.listGrbProducts(selectedProjectId),
|
|
datasetsApi.listOfficialVectorProducts(selectedProjectId),
|
|
datasetsApi.listBathymetrySources(selectedProjectId),
|
|
])
|
|
.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,
|
|
bathymetry: bathymetry.items,
|
|
})
|
|
}
|
|
})
|
|
.catch((requestError) => {
|
|
if (!cancelled) {
|
|
setProducts(EMPTY_PRODUCTS)
|
|
setError(formatError(requestError, 'De officiële regionale kaartcatalogi konden niet worden geladen.'))
|
|
}
|
|
})
|
|
.finally(() => {
|
|
if (!cancelled) {
|
|
setLoading(false)
|
|
}
|
|
})
|
|
|
|
return () => {
|
|
cancelled = true
|
|
}
|
|
}, [selectedProjectId])
|
|
|
|
const resolveCoverage = useCallback(
|
|
async (bbox: { minx: number; miny: number; maxx: number; maxy: number }) => {
|
|
if (!selectedProjectId) {
|
|
setError('Selecteer eerst een werkruimte.')
|
|
return null
|
|
}
|
|
try {
|
|
const coverage = await externalApi.resolveCoverage({
|
|
projectId: selectedProjectId,
|
|
bbox,
|
|
})
|
|
setError(null)
|
|
return coverage
|
|
} catch (requestError) {
|
|
setError(formatError(requestError, 'De regionale databronnen konden niet veilig worden bepaald.'))
|
|
return null
|
|
}
|
|
},
|
|
[selectedProjectId],
|
|
)
|
|
|
|
const resolveCoveragePartitions = useCallback(
|
|
async (bboxes: VectorSelectionBBox[]): Promise<Array<{
|
|
bbox: VectorSelectionBBox
|
|
coverage: CoverageResolveResponse
|
|
}> | null> => {
|
|
if (!selectedProjectId) {
|
|
setError('Selecteer eerst een werkruimte.')
|
|
return null
|
|
}
|
|
try {
|
|
const resolved: Array<{
|
|
bbox: VectorSelectionBBox
|
|
coverage: CoverageResolveResponse
|
|
}> = []
|
|
for (let offset = 0; offset < bboxes.length; offset += 4) {
|
|
const batch = bboxes.slice(offset, offset + 4)
|
|
resolved.push(...await Promise.all(batch.map(async (bbox) => ({
|
|
bbox,
|
|
coverage: await externalApi.resolveCoverage({
|
|
projectId: selectedProjectId,
|
|
bbox: {
|
|
minx: bbox.min_x,
|
|
miny: bbox.min_y,
|
|
maxx: bbox.max_x,
|
|
maxy: bbox.max_y,
|
|
},
|
|
}),
|
|
}))))
|
|
}
|
|
setError(null)
|
|
return resolved
|
|
} catch (requestError) {
|
|
setError(formatError(
|
|
requestError,
|
|
'De regionale dekking kon niet voor alle bronpartities worden bepaald.',
|
|
))
|
|
return null
|
|
}
|
|
},
|
|
[selectedProjectId],
|
|
)
|
|
|
|
return { products, loading, error, resolveCoverage, resolveCoveragePartitions }
|
|
}
|