feat(tours): bike tours in the planner, CyclOSM, and the planned cards' last points (BIK-01 to BIK-06, RTE-01, IO-01, LIB-02)

The tour type is a dropdown; a bike tour picks its profile, routes for it,
says when a point lies off every way, and shows what it runs on: surfaces,
kinds of way and, for a mountain bike, the trail grades, each pointed at on
the map. A type's own map (OpenHikingMap for a hike, CyclOSM for a bike tour)
is offered while a tour of that type is open, with an admin switch each.

From the planned cards: a hike avoids steep climbs, steps or ferries, nothing
else; a saved tour can be shared where the platform takes GPX files; and the
tours rail adds a tour from one menu: plan new, import GPX, or take one over
from another trip.
This commit is contained in:
Maurice
2026-10-19 21:33:49 +02:00
parent adcaca3c5f
commit 73237ffedb
85 changed files with 3728 additions and 647 deletions
+3 -3
View File
@@ -64,7 +64,7 @@ import { resolveTrackColor, hasManualTrackColor } from './trackColors'
import { SelectedTrackLine, TrackLines } from './TrackLines'
import DawarichTrailLayer from './DawarichTrailLayer'
import { OFM_POSITRON, DEFAULT_MAP_CENTER, DEFAULT_MAP_ZOOM, MAP_MAX_ZOOM, SATELLITE_TILE_URL, SATELLITE_TILE_MAXZOOM, AMAP_SATELLITE, attributionForTile } from '../../constants/mapDefaults'
import { tourRasterBaseOf } from './tourRasterBases'
import { tileHealthHandlers, tourRasterBaseOf } from './tourRasterBases'
import { crsForBasemap } from './gcj02Crs'
import { isGcj02Basemap, resolveBasemap } from '../../utils/tileUrl'
import VectorBasemap from './VectorBasemap'
@@ -840,7 +840,7 @@ export const MapView = memo(function MapView({
const baseLayer = (viewBaseLayer ?? globalBaseLayer) as TourBaseLayer
const hasViewBaseLayer = viewBaseLayer !== undefined && typeof onViewBaseLayerChange === 'function'
const isSatellite = baseLayer === 'satellite'
const tourRaster = tourRasterBaseOf(baseLayer) // topo or OpenHikingMap, the Tours planner's own
const tourRaster = tourRasterBaseOf(baseLayer) // topo, OpenHikingMap or CyclOSM, the Tours planner's own
// The caller hands over whatever the user configured; what kind of basemap
// that is decides which layer draws it. A saved raster template still wins,
// the default is a vector style.
@@ -1126,7 +1126,7 @@ export const MapView = memo(function MapView({
maxZoom={MAP_MAX_ZOOM}
keepBuffer={8} updateWhenZooming={false} updateWhenIdle={true}
referrerPolicy="strict-origin-when-cross-origin"
eventHandlers={baseLayer === 'hiking' && tourLayers?.hikingMap ? { tileerror: tourLayers.hikingMap.onTileError, tileload: tourLayers.hikingMap.onTileLoad } : undefined}
eventHandlers={tileHealthHandlers(tourLayers?.baseHealth, baseLayer)}
/>
) : basemap.kind === 'vector' ? (
<VectorBasemap style={basemap.style} />