fix(map): bound overview feature payloads
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 23:03:58 +02:00
parent 20ec8ad6b2
commit db96404218
5 changed files with 24 additions and 4 deletions
@@ -45,6 +45,7 @@ import {
selectionAnalysisScale,
selectionAreaSquareMetres,
selectionDimensions,
selectionFeatureLimit,
selectionMetricLabel,
splitSelectionBbox,
} from './mapWorkspaceUtils'
@@ -1830,12 +1831,14 @@ export function MapWorkspace({
}
}
const availableThemes: Array<MapThemeQuery<DataThemeId>> = []
const resultFeatureLimit = selectionFeatureLimit(bbox)
for (const theme of DATA_THEMES) {
const dataset = themeDatasetMap[theme.id]
if (dataset && persistedDatasetSupportsSelection(dataset, bbox)) {
availableThemes.push({
themeId: theme.id,
dataset,
featureLimit: resultFeatureLimit,
partitioned: regionalScopeSelected
&& (isPartitionedRaster(dataset) || isPartitionedBathymetry(dataset)),
})
@@ -1852,6 +1855,7 @@ export function MapWorkspace({
displayName: onDemandProduct.displayName,
},
acquisitionBboxes: onDemandProduct.acquisitionBboxes,
featureLimit: resultFeatureLimit,
})
}
continue
@@ -12,6 +12,7 @@ import {
selectionAnalysisScale,
selectionAreaSquareMetres,
selectionDimensions,
selectionFeatureLimit,
splitSelectionBbox,
} from './mapWorkspaceUtils'
import type { VectorSelectionBBox, VectorSelectionResponse } from '../../types'
@@ -156,5 +157,7 @@ describe('map workspace selection guards', () => {
{ dataset_type: 'vector', source_name: 'statbel' },
overview,
)).toBe(true)
expect(selectionFeatureLimit(overview)).toBe(25)
expect(selectionFeatureLimit({ ...overview, min_x: 5, max_x: 5.1, min_y: 51, max_y: 51.1 })).toBe(1000)
})
})
@@ -117,6 +117,13 @@ export function persistedDatasetSupportsSelection(
return scale === 'detail'
}
export function selectionFeatureLimit(bbox: VectorSelectionBBox): number {
const scale = selectionAnalysisScale(bbox)
if (scale === 'overview') return 25
if (scale === 'regional') return 250
return 1000
}
export function splitSelectionBbox(
bbox: VectorSelectionBBox,
maxTileSideMetres = 18_000,
@@ -27,6 +27,7 @@ export interface MapThemeQuery<TThemeId extends string> {
partitioned?: boolean
acquisition?: MapThemeAcquisition
acquisitionBboxes?: VectorSelectionBBox[]
featureLimit?: number
}
export interface MapThemeInsight<TThemeId extends string> {
@@ -104,9 +105,10 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
const settled = await settleWithConcurrency(
queries,
3,
async ({ themeId, dataset: existingDataset, partitioned, acquisition, acquisitionBboxes }) => {
async ({ themeId, dataset: existingDataset, partitioned, acquisition, acquisitionBboxes, featureLimit }) => {
let dataset = existingDataset
let acquiredDatasets: DatasetCreateResponse[] = []
const resultLimit = featureLimit ?? 1000
if (acquisition) {
const requestedBboxes = acquisitionBboxes?.length ? acquisitionBboxes : [bbox]
const acquisitionResults = await settleWithConcurrency(requestedBboxes, 1, async (acquisitionBbox) => {
@@ -209,18 +211,18 @@ export function useMapThemeSelectionInsights<TThemeId extends string>(
dataset_ids: acquiredDatasetIds,
bbox,
area_id: areaId,
limit: 1000,
limit: resultLimit,
})
: dataset.source_name === 'vmm_vha_bathymetry_profiles' && partitioned
? await datasetsApi.selectBathymetryProfilePartitions(selectedProjectId, {
bbox,
area_id: areaId,
limit: 1000,
limit: resultLimit,
})
: await datasetsApi.selectVectorFeatures(selectedProjectId, dataset.id, {
bbox,
area_id: areaId,
limit: 1000,
limit: resultLimit,
}),
}
},