diff --git a/frontend/src/mapstyles/index.js b/frontend/src/mapstyles/index.js index f1347b5..28e3a62 100644 --- a/frontend/src/mapstyles/index.js +++ b/frontend/src/mapstyles/index.js @@ -3,6 +3,8 @@ import _ from 'lodash' import bright from './bright.json' import positron from './positron.json' +export {bright, positron} + export function colorByDistance(attribute = 'distance_overtaker_mean', fallback = '#ABC') { return [ 'case', @@ -24,62 +26,58 @@ export function colorByDistance(attribute = 'distance_overtaker_mean', fallback ] } -function addRoadsStyle(style, mapSource) { - style.sources.obs = mapSource +export const roadsLayer = { + id: 'obs', + type: 'line', + source: 'obs', + 'source-layer': 'obs_roads', + layout: { + 'line-cap': 'round', + 'line-join': 'round', + }, + paint: { + 'line-width': [ + 'interpolate', + ['exponential', 1.5], + ['zoom'], + 12, + 2, + 17, + ['case', ['!', ['to-boolean', ['get', 'distance_overtaker_mean']]], 2, 6], + ], + 'line-color': colorByDistance(), + 'line-opacity': [ + 'interpolate', + ['linear'], + ['zoom'], + 12, + 0, + 13, + ['case', ['!', ['to-boolean', ['get', 'distance_overtaker_mean']]], 0, 1], + 14, + ['case', ['!', ['to-boolean', ['get', 'distance_overtaker_mean']]], 0, 1], + 15, + 1, + ], + 'line-offset': [ + 'interpolate', + ['exponential', 1.5], + ['zoom'], + 12, + ['get', 'offset_direction'], + 19, + ['*', ['get', 'offset_direction'], 8], + ], + }, + minzoom: 12, +} - // insert before "road_oneway" layer - let idx = style.layers.findIndex((l) => l.id === 'road_oneway') - if (idx === -1) { - idx = style.layers.length +export const trackLayer = { + type: 'line', + paint: { + 'line-width': ['interpolate', ['linear'], ['zoom'], 14, 2, 17, 5], + 'line-color': '#F06292', } - style.layers.splice(idx, 0, { - id: 'obs', - type: 'line', - source: 'obs', - 'source-layer': 'obs_roads', - layout: { - 'line-cap': 'round', - 'line-join': 'round', - }, - paint: { - 'line-width': [ - 'interpolate', - ['exponential', 1.5], - ['zoom'], - 12, - 2, - 17, - ['case', ['!', ['to-boolean', ['get', 'distance_overtaker_mean']]], 2, 6], - ], - 'line-color': colorByDistance(), - 'line-opacity': [ - 'interpolate', - ['linear'], - ['zoom'], - 12, - 0, - 13, - ['case', ['!', ['to-boolean', ['get', 'distance_overtaker_mean']]], 0, 1], - 14, - ['case', ['!', ['to-boolean', ['get', 'distance_overtaker_mean']]], 0, 1], - 15, - 1, - ], - 'line-offset': [ - 'interpolate', - ['exponential', 1.5], - ['zoom'], - 12, - ['get', 'offset_direction'], - 19, - ['*', ['get', 'offset_direction'], 8], - ], - }, - minzoom: 12, - }) - - return style } export const basemap = positron -export const obsRoads = (sourceUrl) => addRoadsStyle(_.cloneDeep(basemap), sourceUrl) diff --git a/frontend/src/pages/MapPage.tsx b/frontend/src/pages/MapPage.tsx index d14faf7..0cb5ae3 100644 --- a/frontend/src/pages/MapPage.tsx +++ b/frontend/src/pages/MapPage.tsx @@ -1,13 +1,14 @@ import React from 'react' +import ReactMapGl, {AttributionControl, NavigationControl, Layer, Source} from 'react-map-gl' + import {Page} from 'components' import {useConfig, Config} from 'config' import {useHistory, useLocation} from 'react-router-dom' -import ReactMapGl, {AttributionControl } from 'react-map-gl' import styles from './MapPage.module.less' -import {obsRoads, basemap } from '../mapstyles' +import {roadsLayer, basemap} from '../mapstyles' function parseHash(v) { if (!v) return null @@ -37,52 +38,47 @@ function useViewportFromUrl() { return [value || EMPTY_VIEWPORT, setter] } -function CustomMapInner({viewportFromUrl, mapSource, config, mode, children}: {viewportFromUrl?: boolean, mapSource: string, config: Config, mode?: 'roads'}) { - const mapStyle = React.useMemo(() => { - if (mode === 'roads') { - return mapSource && obsRoads(mapSource) - } else { - return basemap - } - }, [mapSource, mode]) - +export function CustomMap({viewportFromUrl, children, boundsFromJson}: {viewportFromUrl?: boolean, children: React.ReactNode}) { const [viewportState, setViewportState] = React.useState(EMPTY_VIEWPORT) const [viewportUrl, setViewportUrl] = useViewportFromUrl() const [viewport, setViewport] = viewportFromUrl ? [viewportUrl, setViewportUrl] : [viewportState, setViewportState] + + const config = useConfig() React.useEffect(() => { if (config?.mapHome && viewport.zoom === 0) { setViewport(config.mapHome) } }, [config]) - if (!mapStyle) { - return null - } - return ( - + © OpenStreetMap contributors', '© OpenMapTiles', '© OpenBikeSensor', ]} /> + {children} ) } -export function CustomMap(props) { - const config = useConfig() || {} - if (!config) return null; - const {obsMapSource: mapSource} = config +export function RoadsMap() { + const {obsMapSource} = useConfig() || {} - if (!mapSource) return null; + if (!obsMapSource) { + return null; + } return ( - + + + + + ) } @@ -90,7 +86,7 @@ export default function MapPage() { return (
- +
) diff --git a/frontend/src/pages/TrackPage/TrackMap.tsx b/frontend/src/pages/TrackPage/TrackMap.tsx index 5bd22c2..0ecbcea 100644 --- a/frontend/src/pages/TrackPage/TrackMap.tsx +++ b/frontend/src/pages/TrackPage/TrackMap.tsx @@ -4,7 +4,7 @@ import {Source, Layer} from 'react-map-gl' import type {TrackData} from 'types' import {CustomMap} from '../MapPage' -import {colorByDistance} from '../../mapstyles' +import {colorByDistance, trackLayer} from '../../mapstyles' export default function TrackMap({ trackData, @@ -27,14 +27,7 @@ export default function TrackMap({ {showTrack && ( - + )}