Add Belgium and North Sea coverage foundation
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-18 01:45:00 +02:00
parent a8fd6e5e9c
commit 1e527bf810
29 changed files with 2524 additions and 10 deletions
+63
View File
@@ -0,0 +1,63 @@
import { useEffect, useState } from 'react'
import { externalApi } from '../services/api'
import type { CoverageResolveResponse, VectorSelectionBBox } from '../types'
interface CoverageResolverOptions {
projectId: string | null
bbox: VectorSelectionBBox | null
}
export function useCoverageResolver({ projectId, bbox }: CoverageResolverOptions) {
const [coverage, setCoverage] = useState<CoverageResolveResponse | null>(null)
const [loadingCoverage, setLoadingCoverage] = useState(false)
const [coverageError, setCoverageError] = useState<string | null>(null)
useEffect(() => {
if (!projectId || !bbox) {
setCoverage(null)
setCoverageError(null)
setLoadingCoverage(false)
return
}
let cancelled = false
const timer = window.setTimeout(() => {
setLoadingCoverage(true)
setCoverageError(null)
externalApi.resolveCoverage({
projectId,
bbox: {
minx: bbox.min_x,
miny: bbox.min_y,
maxx: bbox.max_x,
maxy: bbox.max_y,
},
})
.then((result) => {
if (!cancelled) {
setCoverage(result)
}
})
.catch((error) => {
if (!cancelled) {
setCoverage(null)
setCoverageError(error instanceof Error ? error.message : 'Dekking kon niet worden bepaald')
}
})
.finally(() => {
if (!cancelled) {
setLoadingCoverage(false)
}
})
}, 250)
return () => {
cancelled = true
window.clearTimeout(timer)
}
}, [projectId, bbox?.min_x, bbox?.min_y, bbox?.max_x, bbox?.max_y])
return {
coverage,
loadingCoverage,
coverageError,
}
}
+16 -2
View File
@@ -3,6 +3,7 @@ import {
PRIMARY_FOCUS_AREA_GEOJSON,
PRIMARY_FOCUS_AREA_NAME,
PRIMARY_FOCUS_REGION,
NATIONAL_WORKSPACE_PROJECT_NAME,
REGIONAL_WORKSPACE_PROJECT_NAME,
isPrimaryFocusMunicipalityBoundaryDataset,
isPrimaryFocusMunicipalityProject,
@@ -81,6 +82,17 @@ export function useProjectWorkspace() {
if (selectedProjectId && items.some((project) => project.id === selectedProjectId)) {
return selectedProjectId
}
const nationalProject = items.find((project) => project.name === NATIONAL_WORKSPACE_PROJECT_NAME)
if (nationalProject) {
try {
const data = await fetchProjectData(nationalProject.id)
if (data.areas.length > 0 && data.datasets.some((dataset) => dataset.status === 'ready')) {
return nationalProject.id
}
} catch {
// Continue with regional and municipality fallbacks while national data is unavailable.
}
}
const regionalProject = items.find((project) => project.name === REGIONAL_WORKSPACE_PROJECT_NAME)
if (regionalProject) {
try {
@@ -145,13 +157,15 @@ export function useProjectWorkspace() {
setLoadingProjects(true)
setErrorMessage(null)
try {
const [response, canonicalResponse] = await Promise.all([
const [response, nationalResponse, canonicalResponse] = await Promise.all([
projectsApi.list(),
projectsApi.list({ name: NATIONAL_WORKSPACE_PROJECT_NAME, limit: 1 }),
projectsApi.list({ name: REGIONAL_WORKSPACE_PROJECT_NAME, limit: 1 }),
])
const regionalItems = [...canonicalResponse.items, ...response.items]
const items = Array.from(
new Map(
[...canonicalResponse.items, ...response.items].map((project) => [project.id, project]),
[...nationalResponse.items, ...regionalItems].map((project) => [project.id, project]),
).values(),
)
setProjects(items)