fix: scope evolution series to work area
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-22 06:55:49 +02:00
parent 5a3e7c679b
commit 65749b1694
3 changed files with 44 additions and 4 deletions
+26 -4
View File
@@ -50,6 +50,7 @@ import {
selectionFeatureLimit,
selectionMetricLabel,
splitSelectionBbox,
temporalDatasetAreaMatch,
} from './mapWorkspaceUtils'
const DEFAULT_SELECTED_FEATURE_FILENAME = 'selected-feature.geojson'
@@ -584,22 +585,43 @@ function temporalSeriesLabel(items: DatasetCreateResponse[]): string {
return range ? `${source} (${range})` : source
}
function listThemeTemporalSeries(datasets: DatasetCreateResponse[], theme: DataTheme): TemporalSeriesGroup[] {
function listThemeTemporalSeries(
datasets: DatasetCreateResponse[],
theme: DataTheme,
selectedAreaId: string | null,
): TemporalSeriesGroup[] {
const groups = new Map<string, DatasetCreateResponse[]>()
for (const dataset of datasets) {
if (!datasetMatchesTheme(dataset, theme) || !dataset.temporal_series_key || !dataset.observed_at) {
continue
}
if (temporalDatasetAreaMatch(dataset, selectedAreaId) === 'other') {
continue
}
const items = groups.get(dataset.temporal_series_key) ?? []
items.push(dataset)
groups.set(dataset.temporal_series_key, items)
}
return Array.from(groups.entries())
const series = Array.from(groups.entries())
.map(([key, items]) => {
const ordered = deduplicateTemporalSnapshots(items)
return { key, label: temporalSeriesLabel(ordered), items: ordered }
})
.filter((group) => group.items.length >= 2)
const sourcesWithExactAreaSeries = new Set(
series
.filter((group) => group.items.some((item) => temporalDatasetAreaMatch(item, selectedAreaId) === 'exact'))
.map((group) => group.items[0]?.source_name)
.filter(Boolean),
)
return series
.filter((group) => {
const sourceName = group.items[0]?.source_name
if (!sourceName || !sourcesWithExactAreaSeries.has(sourceName)) return true
return group.items.some((item) => temporalDatasetAreaMatch(item, selectedAreaId) === 'exact')
})
.sort((left, right) => {
if (right.items.length !== left.items.length) {
return right.items.length - left.items.length
@@ -1442,9 +1464,9 @@ export function MapWorkspace({
const themeTemporalSeriesMap = useMemo(
() =>
Object.fromEntries(
DATA_THEMES.map((theme) => [theme.id, listThemeTemporalSeries(availableMapDatasets, theme)]),
DATA_THEMES.map((theme) => [theme.id, listThemeTemporalSeries(availableMapDatasets, theme, selectedMapAreaId)]),
) as Record<DataThemeId, TemporalSeriesGroup[]>,
[availableMapDatasets],
[availableMapDatasets, selectedMapAreaId],
)
const activeTemporalSeriesGroups = themeTemporalSeriesMap[activeTheme.id]
const availableEvolutionThemes = DATA_THEMES.filter((theme) =>