aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modern/src/map/Map.js8
-rw-r--r--modern/src/map/mapStyles.js2
-rw-r--r--web/app/store/MapTypes.js9
-rw-r--r--web/app/view/map/BaseMap.js32
-rw-r--r--web/l10n/en.json3
5 files changed, 50 insertions, 4 deletions
diff --git a/modern/src/map/Map.js b/modern/src/map/Map.js
index 5e182a44..65094d77 100644
--- a/modern/src/map/Map.js
+++ b/modern/src/map/Map.js
@@ -8,7 +8,7 @@ import { SwitcherControl } from './switcher/switcher';
import deviceCategories from '../common/deviceCategories';
import { prepareIcon, loadImage } from './mapUtil';
import {
- styleCarto, styleMapbox, styleMapTiler, styleOsm,
+ styleCarto, styleLocationIq, styleMapbox, styleMapTiler, styleOsm,
} from './mapStyles';
import { useAttributePreference } from '../common/preferences';
import palette from '../theme/palette';
@@ -89,6 +89,7 @@ const Map = ({ children }) => {
const mapboxAccessToken = useAttributePreference('mapboxAccessToken');
const mapTilerKey = useAttributePreference('mapTilerKey');
+ const locationIqKey = useAttributePreference('locationIqKey', 'pk.b34237342901fc175252c790d1674dcc');
useEffect(() => {
maplibregl.accessToken = mapboxAccessToken;
@@ -96,6 +97,9 @@ const Map = ({ children }) => {
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') },
@@ -103,7 +107,7 @@ const Map = ({ children }) => {
{ 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) },
- ], 'osm');
+ ], 'locationIqStreets');
}, [mapTilerKey]);
useEffect(() => {
diff --git a/modern/src/map/mapStyles.js b/modern/src/map/mapStyles.js
index 9650ead5..86813a13 100644
--- a/modern/src/map/mapStyles.js
+++ b/modern/src/map/mapStyles.js
@@ -51,3 +51,5 @@ export const styleCarto = () => ({
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/web/app/store/MapTypes.js b/web/app/store/MapTypes.js
index 9cca525e..01657565 100644
--- a/web/app/store/MapTypes.js
+++ b/web/app/store/MapTypes.js
@@ -20,6 +20,15 @@ Ext.define('Traccar.store.MapTypes', {
fields: ['key', 'name'],
data: [{
+ key: 'locationIqStreets',
+ name: Strings.mapLocationIqStreets
+ }, {
+ key: 'locationIqEarth',
+ name: Strings.mapLocationIqEarth
+ }, {
+ key: 'locationIqHybrid',
+ name: Strings.mapLocationIqHybrid
+ }, {
key: 'osm',
name: Strings.mapOsm
}, {
diff --git a/web/app/view/map/BaseMap.js b/web/app/view/map/BaseMap.js
index efd05021..e280de8e 100644
--- a/web/app/view/map/BaseMap.js
+++ b/web/app/view/map/BaseMap.js
@@ -30,12 +30,13 @@ Ext.define('Traccar.view.map.BaseMap', {
},
initMap: function () {
- var server, layer, type, bingKey, lat, lon, zoom, maxZoom, target, poiLayer, self = this;
+ var server, layer, type, bingKey, locationIqKey, lat, lon, zoom, maxZoom, target, poiLayer, self = this;
server = Traccar.app.getServer();
type = Traccar.app.getPreference('map', null);
bingKey = server.get('bingKey');
+ locationIqKey = Traccar.app.getAttributePreference('locationIqKey', 'pk.b34237342901fc175252c790d1674dcc');
layer = new ol.layer.Group({
title: Strings.mapLayer,
@@ -125,8 +126,35 @@ Ext.define('Traccar.view.map.BaseMap', {
new ol.layer.Tile({
title: Strings.mapOsm,
type: 'base',
- visible: type === 'osm' || type === 'wikimedia' || !type,
+ visible: type === 'osm',
source: new ol.source.OSM({})
+ }),
+ new ol.layer.Tile({
+ title: Strings.mapLocationIqHybrid,
+ type: 'base',
+ visible: type === 'locationIqHybrid',
+ source: new ol.source.XYZ({
+ url: 'https://{a-c}-tiles.locationiq.com/v3/hybrid/r/{z}/{x}/{y}.jpg?key=' + locationIqKey,
+ attributions: '&copy; <a href="https://locationiq.com/">LocationIQ</a>'
+ })
+ }),
+ new ol.layer.Tile({
+ title: Strings.mapLocationIqEarth,
+ type: 'base',
+ visible: type === 'locationIqEarth',
+ source: new ol.source.XYZ({
+ url: 'https://{a-c}-tiles.locationiq.com/v3/earth/r/{z}/{x}/{y}.jpg?key=' + locationIqKey,
+ attributions: '&copy; <a href="https://locationiq.com/">LocationIQ</a>'
+ })
+ }),
+ new ol.layer.Tile({
+ title: Strings.mapLocationIqStreets,
+ type: 'base',
+ visible: type === 'locationIqStreets' || type === 'wikimedia' || !type,
+ source: new ol.source.XYZ({
+ url: 'https://{a-c}-tiles.locationiq.com/v3/streets/r/{z}/{x}/{y}.png?key=' + locationIqKey,
+ attributions: '&copy; <a href="https://locationiq.com/">LocationIQ</a>'
+ })
})
]
});
diff --git a/web/l10n/en.json b/web/l10n/en.json
index 8ee4d659..dd310577 100644
--- a/web/l10n/en.json
+++ b/web/l10n/en.json
@@ -263,6 +263,9 @@
"mapMapboxSatellite": "Mapbox Satellite",
"mapMapTilerBasic": "MapTiler Basic",
"mapMapTilerHybrid": "MapTiler Hybrid",
+ "mapLocationIqStreets": "LocationIQ Streets",
+ "mapLocationIqEarth": "LocationIQ Earth",
+ "mapLocationIqHybrid": "LocationIQ Hybrid",
"mapShapePolygon": "Polygon",
"mapShapeCircle": "Circle",
"mapShapePolyline": "Polyline",