good
This commit is contained in:
parent
c995f12f8b
commit
8dc939d761
44 changed files with 3540 additions and 2159478 deletions
|
|
@ -50,16 +50,26 @@ import {
|
|||
} from './poi-distance-filter';
|
||||
import { dedupeTravelTimeEntries } from './travel-params';
|
||||
import { isOverlayId, type OverlayId } from './overlays';
|
||||
import { CRIME_TYPES, isCrimeTypeValue } from './crime-types';
|
||||
import { isBasemapId, type BasemapId } from './basemaps';
|
||||
import {
|
||||
DEFAULT_COLOR_OPACITY,
|
||||
colorOpacityToPercent,
|
||||
normalizeColorOpacity,
|
||||
} from './color-opacity';
|
||||
|
||||
const POI_NONE_PARAM = '__none';
|
||||
const CRIME_TYPES_NONE_PARAM = '__none';
|
||||
const CRIME_OVERLAY_ID: OverlayId = 'crime-hotspots';
|
||||
|
||||
export interface UrlState {
|
||||
viewState: ViewState;
|
||||
filters: FeatureFilters;
|
||||
poiCategories: Set<string>;
|
||||
overlays: Set<OverlayId>;
|
||||
crimeTypes?: Set<string>;
|
||||
basemap: BasemapId;
|
||||
colorOpacity: number;
|
||||
tab: 'properties' | 'area';
|
||||
travelTime?: TravelTimeInitial;
|
||||
postcode?: string;
|
||||
|
|
@ -216,6 +226,7 @@ export function parseUrlState(): UrlState {
|
|||
poiCategories: new Set(),
|
||||
overlays: new Set(),
|
||||
basemap: 'standard',
|
||||
colorOpacity: DEFAULT_COLOR_OPACITY,
|
||||
tab: 'area',
|
||||
};
|
||||
|
||||
|
|
@ -256,18 +267,36 @@ export function parseUrlState(): UrlState {
|
|||
result.overlays = new Set(overlayParams.filter(isOverlayId));
|
||||
}
|
||||
|
||||
// Crime-type filter: repeated `crimeType` params, or the `__none` sentinel.
|
||||
// Absent means "all types" (handled downstream), so leave it undefined.
|
||||
const crimeTypeParams = params.getAll('crimeType');
|
||||
if (crimeTypeParams.length > 0) {
|
||||
result.crimeTypes = crimeTypeParams.includes(CRIME_TYPES_NONE_PARAM)
|
||||
? new Set()
|
||||
: new Set(crimeTypeParams.filter(isCrimeTypeValue));
|
||||
}
|
||||
|
||||
const basemap = params.get('basemap');
|
||||
if (basemap && isBasemapId(basemap)) {
|
||||
result.basemap = basemap;
|
||||
}
|
||||
|
||||
const colorOpacity = params.get('colorOpacity');
|
||||
if (colorOpacity != null) {
|
||||
const colorOpacityPercent = Number(colorOpacity);
|
||||
if (!isNaN(colorOpacityPercent)) {
|
||||
result.colorOpacity = normalizeColorOpacity(colorOpacityPercent / 100);
|
||||
}
|
||||
}
|
||||
|
||||
// Tab: full name
|
||||
const tab = params.get('tab');
|
||||
if (tab === 'properties' || tab === 'area') {
|
||||
result.tab = tab;
|
||||
}
|
||||
|
||||
// Navigate-to-postcode: one-time param for opening a saved property
|
||||
// Selected postcode. This is also accepted as the historical one-time
|
||||
// navigate-to-postcode param used by saved-property links.
|
||||
const pc = params.get('pc');
|
||||
if (pc) {
|
||||
result.postcode = pc;
|
||||
|
|
@ -329,7 +358,10 @@ export function stateToParams(
|
|||
travelTimeEntries?: TravelTimeEntry[],
|
||||
share?: string,
|
||||
selectedOverlays?: Set<OverlayId>,
|
||||
basemap?: BasemapId
|
||||
basemap?: BasemapId,
|
||||
selectedCrimeTypes?: Set<string>,
|
||||
selectedPostcode?: string,
|
||||
colorOpacity?: number
|
||||
): URLSearchParams {
|
||||
const params = new URLSearchParams();
|
||||
|
||||
|
|
@ -412,16 +444,40 @@ export function stateToParams(
|
|||
params.set('tab', 'properties');
|
||||
}
|
||||
|
||||
if (selectedPostcode) {
|
||||
params.set('pc', selectedPostcode);
|
||||
}
|
||||
|
||||
if (selectedOverlays) {
|
||||
for (const overlay of selectedOverlays) {
|
||||
params.append('overlay', overlay);
|
||||
}
|
||||
}
|
||||
|
||||
// Crime-type selection only matters while the crime overlay is on. Emit it
|
||||
// only when it deviates from the default (all types selected) to keep URLs
|
||||
// clean; a fully-deselected state uses an explicit sentinel.
|
||||
if (selectedOverlays?.has(CRIME_OVERLAY_ID) && selectedCrimeTypes) {
|
||||
if (selectedCrimeTypes.size === 0) {
|
||||
params.append('crimeType', CRIME_TYPES_NONE_PARAM);
|
||||
} else if (selectedCrimeTypes.size < CRIME_TYPES.length) {
|
||||
for (const crimeType of selectedCrimeTypes) {
|
||||
params.append('crimeType', crimeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (basemap && basemap !== 'standard') {
|
||||
params.set('basemap', basemap);
|
||||
}
|
||||
|
||||
if (colorOpacity != null) {
|
||||
const normalizedColorOpacity = normalizeColorOpacity(colorOpacity);
|
||||
if (normalizedColorOpacity !== DEFAULT_COLOR_OPACITY) {
|
||||
params.set('colorOpacity', String(colorOpacityToPercent(normalizedColorOpacity)));
|
||||
}
|
||||
}
|
||||
|
||||
// Travel time: repeated `tt` params
|
||||
if (travelTimeEntries) {
|
||||
for (const entry of dedupeTravelTimeEntries(travelTimeEntries)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue