mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-19 21:31:46 +00:00
117942f45e
* fix(journey): remove photo upload count limit and surface upload errors (#997) Removes the arbitrary 10-file cap on journey entry photo uploads and 20-file cap on gallery uploads. MulterErrors now return proper 4xx responses instead of 500, and the client surfaces the server error message via toast rather than silently trapping the user in the post editor overlay. * fix(planner): remove correct assignment when place assigned to same day multiple times When a place was assigned to the same day more than once, the "Remove from day" button in PlaceInspector always deleted the first assignment (Array.find on place.id) instead of the currently selected one. Now prefers selectedAssignmentId when available. Fixes #1005 * fix(map): enable 3D terrain for Mapbox outdoors style in trip planner wantsTerrain() only matched satellite styles, so the outdoors-v12 style was flat in the planner despite showing correct 3D terrain in the settings preview. Added outdoors-v12 to the allowlist; marker drift is already handled by syncMarkerAltitudes(). Fixes #1002 * fix(maps): send Referer header on Google API calls when APP_URL is set Supports HTTP referrer restrictions on GCP API keys. Documents the restriction types and photo troubleshooting steps in the wiki.
104 lines
4.0 KiB
TypeScript
104 lines
4.0 KiB
TypeScript
import type mapboxgl from 'mapbox-gl'
|
|
|
|
// "mapbox/standard" and "mapbox/standard-satellite" ship their own 3D
|
|
// buildings and terrain. For every other style we inject a fill-extrusion
|
|
// layer against the classic `composite` vector source so the user still
|
|
// gets real 3D buildings (not just a tilted 2D view) when they toggle 3D.
|
|
export function isStandardFamily(style: string): boolean {
|
|
return style === 'mapbox://styles/mapbox/standard' || style === 'mapbox://styles/mapbox/standard-satellite'
|
|
}
|
|
|
|
// Terrain is only genuinely useful for styles that benefit from elevation
|
|
// data. On flat vector styles (streets/light/dark) it nudges route lines
|
|
// onto the DEM while HTML markers stay at Z=0, causing a visible drift
|
|
// when the map is pitched. Satellite and Outdoors are the intended styles
|
|
// for terrain; markers are re-pinned by syncMarkerAltitudes().
|
|
export function wantsTerrain(style: string): boolean {
|
|
return style === 'mapbox://styles/mapbox/satellite-v9'
|
|
|| style === 'mapbox://styles/mapbox/satellite-streets-v12'
|
|
|| style === 'mapbox://styles/mapbox/outdoors-v12'
|
|
}
|
|
|
|
// 3D can be added to every style now — the standard family has it built-in
|
|
// and for everything else we either reuse the style's own `composite`
|
|
// building layer or attach the public `mapbox-streets-v8` tileset as an
|
|
// extra source (needed for pure satellite, which has no vector data).
|
|
export function supportsCustom3d(style: string): boolean {
|
|
return !isStandardFamily(style)
|
|
}
|
|
|
|
// Add a 3D buildings extrusion layer to a non-Standard Mapbox style. For
|
|
// the pure satellite style we lazily attach `mapbox-streets-v8` as a
|
|
// fallback source so real building volumes sit on top of the imagery —
|
|
// the Apple Maps-style "3D satellite" look the user asked for.
|
|
export function addCustom3dBuildings(map: mapboxgl.Map, dark: boolean) {
|
|
if (map.getLayer('trek-3d-buildings')) return
|
|
const baseColor = dark ? '#3b3b3f' : '#cfd2d6'
|
|
|
|
// Styles without a `composite` source (pure satellite) need a fallback
|
|
// vector tileset for building geometry.
|
|
let sourceId = 'composite'
|
|
if (!map.getSource('composite')) {
|
|
sourceId = 'mapbox-streets-v8'
|
|
if (!map.getSource(sourceId)) {
|
|
try {
|
|
map.addSource(sourceId, { type: 'vector', url: 'mapbox://mapbox.mapbox-streets-v8' })
|
|
} catch { return }
|
|
}
|
|
}
|
|
|
|
try {
|
|
// Place extrusions below the first label layer so text stays readable.
|
|
const layers = map.getStyle()?.layers || []
|
|
const firstSymbolId = layers.find(l => l.type === 'symbol')?.id
|
|
map.addLayer({
|
|
id: 'trek-3d-buildings',
|
|
source: sourceId,
|
|
'source-layer': 'building',
|
|
filter: ['==', 'extrude', 'true'],
|
|
type: 'fill-extrusion',
|
|
minzoom: 14,
|
|
paint: {
|
|
'fill-extrusion-color': baseColor,
|
|
'fill-extrusion-height': [
|
|
'interpolate', ['linear'], ['zoom'],
|
|
14, 0,
|
|
15.5, ['coalesce', ['get', 'height'], 0],
|
|
],
|
|
'fill-extrusion-base': [
|
|
'interpolate', ['linear'], ['zoom'],
|
|
14, 0,
|
|
15.5, ['coalesce', ['get', 'min_height'], 0],
|
|
],
|
|
'fill-extrusion-opacity': 0.85,
|
|
},
|
|
}, firstSymbolId)
|
|
} catch { /* building source-layer unavailable */ }
|
|
}
|
|
|
|
// Terrain + sky that works against any style that has the DEM source.
|
|
// The Standard family already handles terrain internally, skip there.
|
|
export function addTerrainAndSky(map: mapboxgl.Map) {
|
|
try {
|
|
if (!map.getSource('mapbox-dem')) {
|
|
map.addSource('mapbox-dem', {
|
|
type: 'raster-dem',
|
|
url: 'mapbox://mapbox.mapbox-terrain-dem-v1',
|
|
tileSize: 512,
|
|
maxzoom: 14,
|
|
})
|
|
}
|
|
map.setTerrain({ source: 'mapbox-dem', exaggeration: 1.2 })
|
|
if (!map.getLayer('sky')) {
|
|
map.addLayer({
|
|
id: 'sky',
|
|
type: 'sky',
|
|
paint: {
|
|
'sky-type': 'atmosphere',
|
|
'sky-atmosphere-sun-intensity': 15,
|
|
} as unknown as mapboxgl.SkyLayerSpecification['paint'],
|
|
})
|
|
}
|
|
} catch { /* style doesn't support terrain */ }
|
|
}
|