mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 07:26:30 +00:00
Tours: provenance contract, source check, one assignment path and the map overview
- P2C-02: tours record their origin (planned, GPX with file name, wanderer) instead of reading it off their shape; the detail answers a provenance contract and a trip copy keeps a tour's import record - MF-03: a wanderer snapshot's source can be checked on purpose, read only, with a confirmed reimport as a new snapshot - PR1-18: every way of putting a tour on a day shares one set of rules - PR1-07/08: each person can hide tours from the trip map; the list shows each tour's line colour and the picked tour stands out on both maps
This commit is contained in:
@@ -41,7 +41,7 @@ import PlaceHoverCard from './PlaceHoverCard'
|
||||
import { ratingBadgeHtml } from './ratingBadge'
|
||||
import type { Poi } from './poiCategories'
|
||||
import { poiPinParts } from './poiMarker'
|
||||
import { resolveTrackColor, hasManualTrackColor } from './trackColors'
|
||||
import { resolveTrackColor, hasManualTrackColor, TRACK_CASING_COLOR } from './trackColors'
|
||||
import { parseRenderableRouteGeometry } from '../../utils/routeGeometry'
|
||||
import { buildPoiPopupHtml } from './placePopup'
|
||||
import { pluginsApi, type PluginMapMarker, type PluginMapLayer } from '../../api/client'
|
||||
@@ -67,6 +67,8 @@ const PLACE_CLUSTER_CIRCLE_LAYER_ID = 'trip-place-clusters-circle'
|
||||
const PLACE_CLUSTER_COUNT_LAYER_ID = 'trip-place-clusters-count'
|
||||
const PLACE_UNCLUSTERED_LAYER_ID = 'trip-place-unclustered-hit'
|
||||
const GPX_HIT_LAYER_ID = 'trip-gpx-hit'
|
||||
const GPX_SELECTED_CASING_LAYER_ID = 'trip-gpx-selected-casing'
|
||||
const GPX_SELECTED_LAYER_ID = 'trip-gpx-selected'
|
||||
/**
|
||||
* The satellite base layer, the GL twin of the Leaflet one.
|
||||
*
|
||||
@@ -1369,6 +1371,24 @@ export function MapViewGL({
|
||||
},
|
||||
layout: { 'line-cap': 'round', 'line-join': 'round' },
|
||||
})
|
||||
// PR1-08: the picked tour's track on top, wider with a light rim, as the Leaflet map draws
|
||||
// it. The filter follows the selection; until something is picked it matches no track.
|
||||
map.addLayer({
|
||||
id: GPX_SELECTED_CASING_LAYER_ID,
|
||||
type: 'line',
|
||||
source: 'trip-gpx',
|
||||
filter: ['==', ['get', 'place_id'], -1],
|
||||
paint: { 'line-color': TRACK_CASING_COLOR, 'line-width': 9, 'line-opacity': 0.95 },
|
||||
layout: { 'line-cap': 'round', 'line-join': 'round' },
|
||||
})
|
||||
map.addLayer({
|
||||
id: GPX_SELECTED_LAYER_ID,
|
||||
type: 'line',
|
||||
source: 'trip-gpx',
|
||||
filter: ['==', ['get', 'place_id'], -1],
|
||||
paint: { 'line-color': ['coalesce', ['get', 'color'], '#3b82f6'], 'line-width': 5.5 },
|
||||
layout: { 'line-cap': 'round', 'line-join': 'round' },
|
||||
})
|
||||
// Invisible fat line that catches the click — 3.5px is not a target,
|
||||
// and the start markers cluster below zoom 11, so without this a track
|
||||
// is unreachable at the very zoom where you compare walks side by side.
|
||||
@@ -2093,6 +2113,16 @@ export function MapViewGL({
|
||||
src.setData({ type: 'FeatureCollection', features })
|
||||
}, [places, mapReady])
|
||||
|
||||
// The picked tour's track stands out (PR1-08); -1 matches no track.
|
||||
useEffect(() => {
|
||||
const map = mapRef.current
|
||||
if (!map || !mapReady || typeof map.getLayer !== 'function') return
|
||||
const filter = ['==', ['get', 'place_id'], selectedPlaceId ?? -1] as mapboxgl.FilterSpecification
|
||||
for (const id of [GPX_SELECTED_CASING_LAYER_ID, GPX_SELECTED_LAYER_ID]) {
|
||||
if (map.getLayer(id)) map.setFilter(id, filter)
|
||||
}
|
||||
}, [selectedPlaceId, mapReady])
|
||||
|
||||
// Reservation overlay — mirrors the Leaflet ReservationOverlay: great-
|
||||
// circle arcs for flights/cruises, straight lines for trains/cars,
|
||||
// clickable endpoint badges, rotating mid-arc stats label for flights.
|
||||
|
||||
Reference in New Issue
Block a user