fix(map): exclude high-resolution rasters from overview
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-21 22:56:39 +02:00
parent 20829f1a24
commit 20ec8ad6b2
4 changed files with 63 additions and 3 deletions
+17
View File
@@ -10990,3 +10990,20 @@ Remaining in this pass:
- run the complete readiness gate, deploy the immutable revision and repeat
both the large overview rectangle and a regional partitioned rectangle in
the live browser.
## 2026-07-21 - Persisted raster scale guard
Live verification of the first scale-aware release showed that on-demand
provider fan-out was resolved, but already persisted 5 m terrain and flood
rasters could still enter a Belgium-scale analysis. The shared selection guard
now applies the same real pixel budgets to persisted rasters: country-scale
overview analysis keeps PostGIS vector and national statistical sources, while
high-resolution rasters require detail or safely bounded regional extent.
Validation:
- frontend typecheck, 29 unit tests and the production build passed;
- the map acquisition, component-boundary and density regression contracts
passed (12 tests);
- live redeployment and a repeated Belgium-scale rectangle follow on the
immutable patch revision.
+10 -3
View File
@@ -34,6 +34,7 @@ import {
normalizeBboxFromCorners,
operationalScopeProjectLabel,
parseBboxInput,
persistedDatasetSupportsSelection,
productCoversZones,
readablePropertyName,
resultCountLabel,
@@ -1154,7 +1155,8 @@ export function MapWorkspace({
if (boundedThemes.has(theme.id)) {
return true
}
if (!themeDatasetMap[theme.id]) {
const dataset = themeDatasetMap[theme.id]
if (!dataset || !persistedDatasetSupportsSelection(dataset, mapSelectionBbox)) {
return false
}
const coverageTheme = COVERAGE_THEME_BY_MAP_THEME[theme.id]
@@ -1830,7 +1832,7 @@ export function MapWorkspace({
const availableThemes: Array<MapThemeQuery<DataThemeId>> = []
for (const theme of DATA_THEMES) {
const dataset = themeDatasetMap[theme.id]
if (dataset) {
if (dataset && persistedDatasetSupportsSelection(dataset, bbox)) {
availableThemes.push({
themeId: theme.id,
dataset,
@@ -1865,7 +1867,12 @@ export function MapWorkspace({
setMapAnalysisDurationMs(null)
setSelectionBbox(bbox)
const tasks: Array<Promise<unknown>> = [loadAllThemeResults(bbox, areaId)]
if (activeThemeAvailable && !regionalPartitionedThemeActive && !onDemandThemeActive) {
const activeDatasetSupportsSelection = !activeThemeDataset
|| persistedDatasetSupportsSelection(activeThemeDataset, bbox)
if (
activeThemeAvailable && !regionalPartitionedThemeActive && !onDemandThemeActive
&& activeDatasetSupportsSelection
) {
tasks.push(onRunMapSelectionExtract(bbox, areaId))
}
if (analysisMode === 'evolution' && earlierDatasetId && laterDatasetId) {
@@ -5,6 +5,7 @@ import {
isSelectionBoundedDataset,
normalizeBboxFromCorners,
parseBboxInput,
persistedDatasetSupportsSelection,
productCoversZones,
resultMetricLabel,
selectedAreaCoverageZones,
@@ -138,4 +139,22 @@ describe('map workspace selection guards', () => {
}
expect(() => splitSelectionBbox(selection)).toThrow('detailpartities')
})
it('keeps persisted high-resolution rasters out of overview selections', () => {
const overview: VectorSelectionBBox = {
min_x: 2.5,
min_y: 49.5,
max_x: 6.4,
max_y: 51.5,
crs: 'EPSG:4326',
}
expect(persistedDatasetSupportsSelection(
{ dataset_type: 'raster', source_name: 'digitaal_vlaanderen_dhmv' },
overview,
)).toBe(false)
expect(persistedDatasetSupportsSelection(
{ dataset_type: 'vector', source_name: 'statbel' },
overview,
)).toBe(true)
})
})
@@ -100,6 +100,23 @@ export function selectionAnalysisScale(bbox: VectorSelectionBBox): SelectionAnal
return 'overview'
}
export function persistedDatasetSupportsSelection(
dataset: { dataset_type: string; source_name?: string | null },
bbox: VectorSelectionBBox,
): boolean {
if (dataset.dataset_type !== 'raster') return true
const scale = selectionAnalysisScale(bbox)
if (scale === 'overview') return false
const dimensions = selectionDimensions(bbox)
if (dataset.source_name === 'digitaal_vlaanderen_dhmv' || dataset.source_name === 'vmm_flood_hazard') {
return dimensions.areaSquareMetres <= 280_000_000
}
if (dataset.source_name === 'department_omgeving_thematic_raster') {
return dimensions.areaSquareMetres <= 2_800_000_000
}
return scale === 'detail'
}
export function splitSelectionBbox(
bbox: VectorSelectionBBox,
maxTileSideMetres = 18_000,