Add Belgium and North Sea coverage foundation
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import GeoMap from '../GeoMap'
|
||||
import type { AreaRead, DatasetCreateResponse, DetectionQaResult, MapResultExportRequest, MapViewportState, OrthophotoAcquisitionResult, OrthophotoProductRead, ProjectRead, QaComparisonResult, VectorSelectionBBox, VectorSelectionMetric, VectorSelectionResponse } from '../../types'
|
||||
import type { AreaRead, CoverageResolveResponse, CoverageStatus, DatasetCreateResponse, DetectionQaResult, MapResultExportRequest, MapViewportState, OrthophotoAcquisitionResult, OrthophotoProductRead, ProjectRead, QaComparisonResult, VectorSelectionBBox, VectorSelectionMetric, VectorSelectionResponse } from '../../types'
|
||||
import { useMapThemeSelectionInsights, type MapThemeAcquisition, type MapThemeQuery } from '../../hooks/useMapThemeSelectionInsights'
|
||||
import { useOfficialMapProducts } from '../../hooks/useOfficialMapProducts'
|
||||
import { useTemporalComparison } from '../../hooks/useTemporalComparison'
|
||||
@@ -176,6 +176,49 @@ const DATA_THEMES: DataTheme[] = [
|
||||
},
|
||||
]
|
||||
|
||||
const COVERAGE_THEME_BY_MAP_THEME: Record<DataThemeId, string> = {
|
||||
buildings: 'buildings',
|
||||
space_occupation: 'land_cover_use',
|
||||
open_space: 'land_cover_use',
|
||||
population: 'population',
|
||||
forest: 'land_cover_use',
|
||||
nature_value: 'nature',
|
||||
agriculture: 'land_cover_use',
|
||||
soil: 'soil',
|
||||
water: 'surface_water',
|
||||
bathymetry: 'bathymetry',
|
||||
flood_hazard: 'flood_climate',
|
||||
elevation: 'elevation',
|
||||
accessibility: 'roads',
|
||||
services: 'population',
|
||||
roads: 'roads',
|
||||
parcels: 'parcels',
|
||||
}
|
||||
|
||||
function coverageStatusLabel(status: CoverageStatus): string {
|
||||
const labels: Record<CoverageStatus, string> = {
|
||||
operational: 'Beschikbaar',
|
||||
partial: 'Gedeeltelijk',
|
||||
not_configured: 'Niet gekoppeld',
|
||||
unsupported: 'Niet ondersteund',
|
||||
}
|
||||
return labels[status]
|
||||
}
|
||||
|
||||
function coverageZoneLabel(zone: string): string {
|
||||
const labels: Record<string, string> = {
|
||||
belgium: 'Belgie',
|
||||
flanders: 'Vlaanderen',
|
||||
wallonia: 'Wallonie',
|
||||
brussels: 'Brussel',
|
||||
belgian_north_sea: 'Belgische Noordzee',
|
||||
territorial_sea: 'Territoriale zee',
|
||||
exclusive_economic_zone: 'EEZ',
|
||||
continental_shelf: 'Continentaal plat',
|
||||
}
|
||||
return labels[zone] ?? zone
|
||||
}
|
||||
|
||||
const DATA_THEME_MAP_STYLES: Record<DataThemeId, { fill: string; line: string }> = {
|
||||
buildings: { fill: '#d45f3d', line: '#9f3e24' },
|
||||
space_occupation: { fill: '#be3e33', line: '#8f2c24' },
|
||||
@@ -516,6 +559,9 @@ interface MapWorkspaceProps {
|
||||
mapSelectionResult: VectorSelectionResponse | null
|
||||
mapSelectionLoading: boolean
|
||||
mapSelectionError: string | null
|
||||
coverage: CoverageResolveResponse | null
|
||||
coverageLoading: boolean
|
||||
coverageError: string | null
|
||||
selectionExporting: boolean
|
||||
selectionExportError: string | null
|
||||
latestSelectionExportPath: string | null
|
||||
@@ -602,6 +648,9 @@ export function MapWorkspace({
|
||||
mapSelectionResult,
|
||||
mapSelectionLoading,
|
||||
mapSelectionError,
|
||||
coverage,
|
||||
coverageLoading,
|
||||
coverageError,
|
||||
selectionExporting,
|
||||
selectionExportError,
|
||||
latestSelectionExportPath,
|
||||
@@ -819,6 +868,15 @@ export function MapWorkspace({
|
||||
[availableMapDatasets, regionalScopeSelected, selectedMapAreaId, themeDatasetMap],
|
||||
)
|
||||
const activeTheme = DATA_THEMES.find((theme) => theme.id === activeThemeId) ?? DATA_THEMES[0]
|
||||
const activeCoverageTheme = COVERAGE_THEME_BY_MAP_THEME[activeTheme.id]
|
||||
const activeCoverageItems = coverage?.items.filter((item) => item.theme === activeCoverageTheme) ?? []
|
||||
const coverageCounts = useMemo(
|
||||
() => coverage?.items.reduce<Record<CoverageStatus, number>>(
|
||||
(counts, item) => ({ ...counts, [item.status]: counts[item.status] + 1 }),
|
||||
{ operational: 0, partial: 0, not_configured: 0, unsupported: 0 },
|
||||
) ?? { operational: 0, partial: 0, not_configured: 0, unsupported: 0 },
|
||||
[coverage],
|
||||
)
|
||||
const onDemandProductMap = useMemo(
|
||||
() => {
|
||||
const result = new Map<DataThemeId, OnDemandMapProduct>()
|
||||
@@ -2527,6 +2585,50 @@ export function MapWorkspace({
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{mapSelectionBbox ? (
|
||||
<section className="coverage-resolution-surface" aria-label="Datadekking van de kaartselectie">
|
||||
<div className="panel-title-row">
|
||||
<div>
|
||||
<p className="eyebrow">Dekking van deze selectie</p>
|
||||
<h3>{activeTheme.label}</h3>
|
||||
</div>
|
||||
{coverageLoading ? <span className="count-pill">controleren</span> : null}
|
||||
</div>
|
||||
{coverageError ? <p className="error">{coverageError}</p> : null}
|
||||
{coverage ? (
|
||||
<>
|
||||
<div className="coverage-zone-row">
|
||||
{coverage.intersected_zones.map((zone) => (
|
||||
<span key={zone}>{coverageZoneLabel(zone)}</span>
|
||||
))}
|
||||
{coverage.outside_supported_scope ? <span className="coverage-zone-warning">deels buiten scope</span> : null}
|
||||
</div>
|
||||
<div className="coverage-active-theme-grid">
|
||||
{activeCoverageItems.map((item) => (
|
||||
<div className={`coverage-status-item coverage-status-${item.status}`} key={`${item.zone}:${item.theme}`}>
|
||||
<span>{coverageZoneLabel(item.zone)}</span>
|
||||
<strong>{coverageStatusLabel(item.status)}</strong>
|
||||
<small>{item.source_names.join(', ') || 'Geen broncontract'}</small>
|
||||
</div>
|
||||
))}
|
||||
{activeCoverageItems.length === 0 ? (
|
||||
<p className="muted">Deze selectie raakt geen bewaarde Belgische land- of zeezone.</p>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="coverage-summary-row" aria-label="Samenvatting van alle themas">
|
||||
<span>{coverageCounts.operational} beschikbaar</span>
|
||||
<span>{coverageCounts.partial} gedeeltelijk</span>
|
||||
<span>{coverageCounts.not_configured} niet gekoppeld</span>
|
||||
<span>{coverageCounts.unsupported} niet ondersteund</span>
|
||||
</div>
|
||||
{coverage.warnings.map((warning) => <p className="muted" key={warning}>{warning}</p>)}
|
||||
</>
|
||||
) : !coverageLoading && !coverageError ? (
|
||||
<p className="muted">De dekkingsmatrix wordt bepaald zodra de selectie volledig is.</p>
|
||||
) : null}
|
||||
</section>
|
||||
) : null}
|
||||
|
||||
<div className="map-inspection-surface">
|
||||
<div className="gis-test-run-surface" aria-label="Operationele GIS-controle">
|
||||
<div className="panel-title-row">
|
||||
|
||||
Reference in New Issue
Block a user