diff options
Diffstat (limited to 'modern/src')
-rw-r--r-- | modern/src/map/core/MapView.js | 28 | ||||
-rw-r--r-- | modern/src/map/core/mapStyles.js | 55 | ||||
-rw-r--r-- | modern/src/map/core/useMapStyles.js | 137 |
3 files changed, 142 insertions, 78 deletions
diff --git a/modern/src/map/core/MapView.js b/modern/src/map/core/MapView.js index eea5827a..7f183346 100644 --- a/modern/src/map/core/MapView.js +++ b/modern/src/map/core/MapView.js @@ -4,15 +4,11 @@ import maplibregl from 'maplibre-gl'; import React, { useRef, useLayoutEffect, useEffect, useState, } from 'react'; -import { useSelector } from 'react-redux'; import { SwitcherControl } from '../switcher/switcher'; -import { - styleCarto, styleCustom, styleLocationIq, styleMapbox, styleMapTiler, styleOsm, -} from './mapStyles'; import { useAttributePreference } from '../../common/util/preferences'; -import { useTranslation } from '../../common/components/LocalizationProvider'; import usePersistedState, { savePersistedState } from '../../common/util/usePersistedState'; import { mapImages } from './preloadImages'; +import useMapStyles from './useMapStyles'; const element = document.createElement('div'); element.style.width = '100%'; @@ -75,35 +71,21 @@ map.addControl(switcher); const MapView = ({ children }) => { const containerEl = useRef(null); - const t = useTranslation(); const [mapReady, setMapReady] = useState(false); const [defaultMapLayer] = usePersistedState('mapLayer', 'locationIqStreets'); const mapboxAccessToken = useAttributePreference('mapboxAccessToken'); - const mapTilerKey = useAttributePreference('mapTilerKey'); - const locationIqKey = useAttributePreference('locationIqKey', 'pk.0f147952a41c555a5b70614039fd148b'); - const customMapUrl = useSelector((state) => state.session.server?.mapUrl); + + const mapStyles = useMapStyles(); useEffect(() => { maplibregl.accessToken = mapboxAccessToken; }, [mapboxAccessToken]); useEffect(() => { - switcher.updateStyles([ - { id: 'locationIqStreets', title: t('mapLocationIqStreets'), uri: styleLocationIq('streets', locationIqKey) }, - { id: 'locationIqEarth', title: t('mapLocationIqEarth'), uri: styleLocationIq('earth', locationIqKey) }, - { id: 'locationIqHybrid', title: t('mapLocationIqHybrid'), uri: styleLocationIq('hybrid', locationIqKey) }, - { id: 'osm', title: t('mapOsm'), uri: styleOsm() }, - { id: 'carto', title: t('mapCarto'), uri: styleCarto() }, - { id: 'mapboxStreets', title: t('mapMapboxStreets'), uri: styleMapbox('streets-v11') }, - { id: 'mapboxOutdoors', title: t('mapMapboxOutdoors'), uri: styleMapbox('outdoors-v11') }, - { id: 'mapboxSatellite', title: t('mapMapboxSatellite'), uri: styleMapbox('satellite-v9') }, - { id: 'mapTilerBasic', title: t('mapMapTilerBasic'), uri: styleMapTiler('basic', mapTilerKey) }, - { id: 'mapTilerHybrid', title: t('mapMapTilerHybrid'), uri: styleMapTiler('hybrid', mapTilerKey) }, - { id: 'custom', title: t('mapCustom'), uri: styleCustom(customMapUrl) }, - ], defaultMapLayer); - }, [t, locationIqKey, mapTilerKey, customMapUrl, defaultMapLayer]); + switcher.updateStyles(mapStyles, defaultMapLayer); + }, [mapStyles, defaultMapLayer]); useEffect(() => { const listener = (ready) => setMapReady(ready); diff --git a/modern/src/map/core/mapStyles.js b/modern/src/map/core/mapStyles.js deleted file mode 100644 index 86813a13..00000000 --- a/modern/src/map/core/mapStyles.js +++ /dev/null @@ -1,55 +0,0 @@ -export const styleCustom = (url, attribution) => ({ - version: 8, - sources: { - osm: { - type: 'raster', - tiles: [url], - attribution, - tileSize: 256, - }, - }, - glyphs: 'https://cdn.traccar.com/map/fonts/{fontstack}/{range}.pbf', - layers: [{ - id: 'osm', - type: 'raster', - source: 'osm', - }], -}); - -export const styleOsm = () => styleCustom( - 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', - '© <a target="_top" rel="noopener" href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors', -); - -export const styleCarto = () => ({ - version: 8, - sources: { - 'raster-tiles': { - type: 'raster', - tiles: [ - 'https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png', - 'https://b.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png', - 'https://c.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png', - 'https://d.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png', - ], - tileSize: 256, - attribution: '© <a target="_top" rel="noopener" href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a target="_top" rel="noopener" href="https://carto.com/attribution">CARTO</a>', - }, - }, - glyphs: 'https://cdn.traccar.com/map/fonts/{fontstack}/{range}.pbf', - layers: [ - { - id: 'simple-tiles', - type: 'raster', - source: 'raster-tiles', - minzoom: 0, - maxzoom: 22, - }, - ], -}); - -export const styleMapbox = (style) => `mapbox://styles/mapbox/${style}`; - -export const styleMapTiler = (style, key) => `https://api.maptiler.com/maps/${style}/style.json?key=${key}`; - -export const styleLocationIq = (style, key) => `https://tiles.locationiq.com/v3/${style}/vector.json?key=${key}`; diff --git a/modern/src/map/core/useMapStyles.js b/modern/src/map/core/useMapStyles.js new file mode 100644 index 00000000..f635e15c --- /dev/null +++ b/modern/src/map/core/useMapStyles.js @@ -0,0 +1,137 @@ +import { useSelector } from 'react-redux'; +import { useTranslation } from '../../common/components/LocalizationProvider'; +import { useAttributePreference } from '../../common/util/preferences'; + +const styleCustom = (url, attribution) => ({ + version: 8, + sources: { + osm: { + type: 'raster', + tiles: [url], + attribution, + tileSize: 256, + }, + }, + glyphs: 'https://cdn.traccar.com/map/fonts/{fontstack}/{range}.pbf', + layers: [{ + id: 'osm', + type: 'raster', + source: 'osm', + }], +}); + +const styleOsm = () => styleCustom( + 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', + '© <a target="_top" rel="noopener" href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors', +); + +const styleCarto = () => ({ + version: 8, + sources: { + 'raster-tiles': { + type: 'raster', + tiles: [ + 'https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png', + 'https://b.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png', + 'https://c.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png', + 'https://d.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png', + ], + tileSize: 256, + attribution: '© <a target="_top" rel="noopener" href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a target="_top" rel="noopener" href="https://carto.com/attribution">CARTO</a>', + }, + }, + glyphs: 'https://cdn.traccar.com/map/fonts/{fontstack}/{range}.pbf', + layers: [ + { + id: 'simple-tiles', + type: 'raster', + source: 'raster-tiles', + minzoom: 0, + maxzoom: 22, + }, + ], +}); + +const styleMapbox = (style) => `mapbox://styles/mapbox/${style}`; + +const styleMapTiler = (style, key) => `https://api.maptiler.com/maps/${style}/style.json?key=${key}`; + +const styleLocationIq = (style, key) => `https://tiles.locationiq.com/v3/${style}/vector.json?key=${key}`; + +export default () => { + const t = useTranslation(); + + const mapboxAccessToken = useAttributePreference('mapboxAccessToken'); + const mapTilerKey = useAttributePreference('mapTilerKey'); + const locationIqKey = useAttributePreference('locationIqKey'); + const customMapUrl = useSelector((state) => state.session.server?.mapUrl); + + return [ + { + id: 'locationIqStreets', + title: t('mapLocationIqStreets'), + uri: styleLocationIq('streets', locationIqKey || 'pk.0f147952a41c555a5b70614039fd148b'), + available: true, + }, + { + id: 'locationIqEarth', + title: t('mapLocationIqEarth'), + uri: styleLocationIq('earth', locationIqKey), + available: !!locationIqKey, + }, + { + id: 'locationIqHybrid', + title: t('mapLocationIqHybrid'), + uri: styleLocationIq('hybrid', locationIqKey), + available: !!locationIqKey, + }, + { + id: 'osm', + title: t('mapOsm'), + uri: styleOsm(), + available: true, + }, + { + id: 'carto', + title: t('mapCarto'), + uri: styleCarto(), + available: true, + }, + { + id: 'mapboxStreets', + title: t('mapMapboxStreets'), + uri: styleMapbox('streets-v11'), + available: !!mapboxAccessToken, + }, + { + id: 'mapboxOutdoors', + title: t('mapMapboxOutdoors'), + uri: styleMapbox('outdoors-v11'), + available: !!mapboxAccessToken, + }, + { + id: 'mapboxSatellite', + title: t('mapMapboxSatellite'), + uri: styleMapbox('satellite-v9'), + available: !!mapboxAccessToken, + }, + { + id: 'mapTilerBasic', + title: t('mapMapTilerBasic'), + uri: styleMapTiler('basic', mapTilerKey), + available: !!mapTilerKey, + }, + { + id: 'mapTilerHybrid', + title: t('mapMapTilerHybrid'), + uri: styleMapTiler('hybrid', mapTilerKey), + available: !!mapTilerKey, + }, + { + id: 'custom', + title: t('mapCustom'), + uri: styleCustom(customMapUrl), + available: !!customMapUrl, + }, + ]; +}; |