mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
24461ecf76
In the admin's default user settings, the map template dropdown listed
seven tile presets, while every user's own map settings listed nine: the
same seven plus Amap and Amap Satellite. An admin running an instance for
people in mainland China could not pick the one basemap that works well
there as the default, short of pasting its URL by hand.
The Amap presets (57eac32f9) were added to the two user preset copies and
not to the admin's separate copy; nothing in that change or later gives a
reason, and the server stores any template as a default. The later
refactor kept the gap as DEFAULT_MAP_PRESETS beside MAP_PRESETS. There is
now one MAP_PRESETS list, read by the user settings and the admin defaults
on both desktop and phone.
Regression test FE-ADMIN-DUS-029 (DefaultUserSettingsTab.test.tsx) was red
on the old code: "Unable to find role="button" and name "高德地图 (Amap)"".
Changed assertions:
- useMapSettingsForm.test.ts FE-COMP-MAPFORM-001: it expected the admin list
DEFAULT_MAP_PRESETS to hold 7 presets and the user list to add Amap on
top; it now expects the one list to hold 9 presets including both Amap
templates.
94 lines
3.7 KiB
TypeScript
94 lines
3.7 KiB
TypeScript
import { AMAP_ROAD, AMAP_SATELLITE } from '../../constants/mapDefaults';
|
|
import type { Place } from '../../types';
|
|
import {
|
|
MAPBOX_DEFAULT_STYLE,
|
|
isOpenFreeMapStyle,
|
|
normalizeStyleForProvider,
|
|
type GlMapProvider,
|
|
} from '../Map/glProviders';
|
|
|
|
/**
|
|
* The map settings both shells share: the tile presets, the provider and style rules,
|
|
* and the preview place. The user's map settings and the admin's defaults for users
|
|
* read the same presets, so the two can never offer a different list by accident.
|
|
*/
|
|
|
|
export interface MapPreset {
|
|
name: string;
|
|
url: string;
|
|
}
|
|
|
|
/**
|
|
* The tile presets a user picks from in their own map settings, and the same list
|
|
* an admin picks the default for every user from.
|
|
*/
|
|
export const MAP_PRESETS: MapPreset[] = [
|
|
{ name: 'OpenStreetMap', url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png' },
|
|
{ name: 'OpenStreetMap DE', url: 'https://tile.openstreetmap.de/{z}/{x}/{y}.png' },
|
|
// The app default, and a vector style rather than a {z}/{x}/{y} template: no
|
|
// key, no registration, no request limits.
|
|
{ name: 'OpenFreeMap Positron', url: 'https://tiles.openfreemap.org/styles/positron' },
|
|
{ name: 'OpenFreeMap Bright', url: 'https://tiles.openfreemap.org/styles/bright' },
|
|
// CARTO watermarks keyless tiles since 26.08.2026 and issues keys by mail, so
|
|
// these two need one; without it the map falls back to the default (#2054).
|
|
{ name: 'CartoDB Light', url: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png' },
|
|
{ name: 'CartoDB Dark', url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png' },
|
|
{ name: 'Stadia Smooth', url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png' },
|
|
// Amap (高德). GCJ-02 tiles: the map switches to a shifted projection for
|
|
// these so markers still land on the right street (see gcj02Crs.ts). The only
|
|
// basemap here that is genuinely good inside mainland China.
|
|
{ name: '高德地图 (Amap)', url: AMAP_ROAD },
|
|
{ name: '高德卫星 (Amap Satellite)', url: AMAP_SATELLITE },
|
|
];
|
|
|
|
export type MapProvider = 'leaflet' | GlMapProvider;
|
|
|
|
export function normalizeProvider(value: unknown): MapProvider {
|
|
return value === 'mapbox-gl' || value === 'maplibre-gl' ? value : 'leaflet';
|
|
}
|
|
|
|
export function styleForProvider(provider: MapProvider, style?: string | null): string {
|
|
if (provider === 'leaflet') return style || MAPBOX_DEFAULT_STYLE;
|
|
if (provider === 'mapbox-gl' && isOpenFreeMapStyle(style)) return MAPBOX_DEFAULT_STYLE;
|
|
return normalizeStyleForProvider(provider, style);
|
|
}
|
|
|
|
// Each GL provider has its own style slot, so toggling providers never clobbers the
|
|
// other one's style. Leaflet/Mapbox use mapbox_style; MapLibre uses maplibre_style.
|
|
export function slotStyle(
|
|
provider: MapProvider,
|
|
s: { mapbox_style?: string; maplibre_style?: string }
|
|
): string | undefined {
|
|
return provider === 'maplibre-gl' ? s.maplibre_style : s.mapbox_style;
|
|
}
|
|
|
|
/**
|
|
* Somewhere recognisable for the style preview to render. A city shows off label density,
|
|
* 3D buildings and satellite texture in a way open ocean cannot. It is not a user setting,
|
|
* and no map opens here: each map frames itself on its own places.
|
|
*/
|
|
export const PREVIEW_CENTER: [number, number] = [48.8566, 2.3522];
|
|
export const PREVIEW_ZOOM = 16;
|
|
|
|
/** The one place the user's map preview shows. */
|
|
export function previewPlace(): Place {
|
|
return {
|
|
id: 1,
|
|
trip_id: 1,
|
|
name: 'Preview',
|
|
description: '',
|
|
lat: PREVIEW_CENTER[0],
|
|
lng: PREVIEW_CENTER[1],
|
|
address: '',
|
|
category_id: 0,
|
|
price: null,
|
|
image_url: null,
|
|
google_place_id: null,
|
|
osm_id: null,
|
|
route_geometry: null,
|
|
place_time: null,
|
|
end_time: null,
|
|
created_at: String(new Date()),
|
|
};
|
|
}
|