fix(map): keep municipality analysis local
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-19 18:11:39 +02:00
parent e2c90da11d
commit 1f5a2f0ea7
5 changed files with 22 additions and 6 deletions
+3
View File
@@ -20,6 +20,9 @@
- Live-smoked a Mol rectangle through NGI, Statbel, GRB, Flemish thematic - Live-smoked a Mol rectangle through NGI, Statbel, GRB, Flemish thematic
rasters, DHMV, VMM flood hazard, BWK, DOV and VHA, including persisted rasters, DHMV, VMM flood hazard, BWK, DOV and VHA, including persisted
Dataset output and semantic vector/raster metrics. Dataset output and semantic vector/raster metrics.
- Classified both `Gemeente ...` and release-golden `... municipality` Areas
as local scope so a full municipality analysis cannot accidentally invoke
regional raster partition assembly.
- Rebuilt the complete frontend presentation as the Stitch-guided GeoIntel - Rebuilt the complete frontend presentation as the Stitch-guided GeoIntel
Atlas Workbench. The new shell uses one compact icon navigation rail, one Atlas Workbench. The new shell uses one compact icon navigation rail, one
context bar and task-specific work surfaces across Map, Sources, AI context bar and task-specific work surfaces across Map, Sources, AI
+5 -2
View File
@@ -10924,7 +10924,10 @@ Implemented:
states and counts results per theme rather than per contributing layer; states and counts results per theme rather than per contributing layer;
- registered VMM VHA historical profile points as an operational bounded - registered VMM VHA historical profile points as an operational bounded
Flanders bathymetry source and connected its existing acquire/select routes Flanders bathymetry source and connected its existing acquire/select routes
to the Map product catalogue. to the Map product catalogue;
- treated both Dutch municipality names and release-golden
`... municipality` Areas as local scope after live verification exposed a
false regional flood-raster partition path.
Live evidence: Live evidence:
@@ -10939,7 +10942,7 @@ Live evidence:
Validation: Validation:
- the complete readiness gate passed: 1,053 backend tests, 24 frontend tests, - the complete readiness gate passed: 1,053 backend tests, 25 frontend tests,
backend compile, frontend TypeScript/typecheck, production build, Alembic backend compile, frontend TypeScript/typecheck, production build, Alembic
head `202607160001` and script smoke checks; head `202607160001` and script smoke checks;
- a live API smoke over `5.10,51.17,5.11,51.18` proved all 17 applicable Mol - a live API smoke over `5.10,51.17,5.11,51.18` proved all 17 applicable Mol
+1 -4
View File
@@ -29,6 +29,7 @@ import {
getFeatureBBox, getFeatureBBox,
getFeatureCollectionBBox, getFeatureCollectionBBox,
getFeatureGeometrySummary, getFeatureGeometrySummary,
isMunicipalityAreaName,
isSelectionBoundedDataset, isSelectionBoundedDataset,
normalizeBboxFromCorners, normalizeBboxFromCorners,
operationalScopeProjectLabel, operationalScopeProjectLabel,
@@ -394,10 +395,6 @@ function datasetMatchesTheme(dataset: DatasetCreateResponse, theme: DataTheme):
return theme.tokens.some((token) => searchText.includes(token)) return theme.tokens.some((token) => searchText.includes(token))
} }
function isMunicipalityAreaName(name: string | null | undefined): boolean {
return /^Gemeente\s/i.test(name ?? '')
}
function isPartitionedRaster(dataset: DatasetCreateResponse | null | undefined): boolean { function isPartitionedRaster(dataset: DatasetCreateResponse | null | undefined): boolean {
return Boolean( return Boolean(
dataset?.dataset_type === 'raster' dataset?.dataset_type === 'raster'
@@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { import {
bboxesEqual, bboxesEqual,
isMunicipalityAreaName,
isSelectionBoundedDataset, isSelectionBoundedDataset,
normalizeBboxFromCorners, normalizeBboxFromCorners,
parseBboxInput, parseBboxInput,
@@ -65,6 +66,13 @@ describe('map workspace selection guards', () => {
expect(productCoversZones(['brussels'], ['wallonia'])).toBe(false) expect(productCoversZones(['brussels'], ['wallonia'])).toBe(false)
}) })
it('recognizes Dutch and release-golden municipality areas as local scope', () => {
expect(isMunicipalityAreaName('Gemeente Mol')).toBe(true)
expect(isMunicipalityAreaName('RC Golden - Mol municipality')).toBe(true)
expect(isMunicipalityAreaName('Flanders')).toBe(false)
expect(isMunicipalityAreaName('RC Golden - Kempen region')).toBe(false)
})
it('distinguishes selection-bounded acquisitions from reusable regional datasets', () => { it('distinguishes selection-bounded acquisitions from reusable regional datasets', () => {
expect(isSelectionBoundedDataset({ expect(isSelectionBoundedDataset({
geometry_clipped_to_selection: true, geometry_clipped_to_selection: true,
@@ -31,6 +31,11 @@ export function selectedAreaCoverageZones(areaName: string | null | undefined):
return null return null
} }
export function isMunicipalityAreaName(areaName: string | null | undefined): boolean {
const normalized = String(areaName ?? '').trim()
return /^Gemeente\s/i.test(normalized) || /\bmunicipality$/i.test(normalized)
}
export function productCoversZones(productZones: string[], selectedZones: string[] | null): boolean { export function productCoversZones(productZones: string[], selectedZones: string[] | null): boolean {
return selectedZones === null || selectedZones.some((zone) => productZones.includes(zone)) return selectedZones === null || selectedZones.some((zone) => productZones.includes(zone))
} }