fix(map): bound overview feature payloads
This commit is contained in:
@@ -10999,6 +10999,10 @@ 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.
|
||||
Overview responses now return at most 25 representative GeoJSON features per
|
||||
source (250 regionally, 1,000 in detail) while `total_feature_count` and every
|
||||
PostGIS metric continue to cover the complete selection. This prevents large
|
||||
profile properties from blocking the browser without weakening measurements.
|
||||
|
||||
Validation:
|
||||
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user