From 54ddf25bc128762fe99f525617f760514f16e82f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 Feb 2021 22:55:36 -0800 Subject: Implement map switcher --- web/app/view/map/BaseMap.js | 112 +++++++++++++++++++++++++------------------- web/load.js | 4 ++ 2 files changed, 68 insertions(+), 48 deletions(-) diff --git a/web/app/view/map/BaseMap.js b/web/app/view/map/BaseMap.js index 6c6522bd..4808a8c5 100644 --- a/web/app/view/map/BaseMap.js +++ b/web/app/view/map/BaseMap.js @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,57 +37,67 @@ Ext.define('Traccar.view.map.BaseMap', { type = Traccar.app.getPreference('map', null); bingKey = server.get('bingKey'); - switch (type) { - case 'custom': - layer = new ol.layer.Tile({ + layer = new ol.layer.Group({ + title: Strings.mapLayer, + layers: [ + new ol.layer.Tile({ + title: Strings.mapCustom, + type: 'base', + visible: type === 'custom', source: new ol.source.XYZ({ url: Ext.String.htmlDecode(server.get('mapUrl')), attributions: '' }) - }); - break; - case 'customArcgis': - layer = new ol.layer.Tile({ + }), + new ol.layer.Tile({ + title: Strings.mapCustomArcgis, + type: 'base', + visible: type === 'customArcgis', source: new ol.source.TileArcGISRest({ url: Ext.String.htmlDecode(server.get('mapUrl')) }) - }); - break; - case 'bingRoad': - layer = new ol.layer.Tile({ + }), + new ol.layer.Tile({ + title: Strings.mapBingRoad, + type: 'base', + visible: type === 'bingRoad', source: new ol.source.BingMaps({ key: bingKey, imagerySet: 'Road' }) - }); - break; - case 'bingAerial': - layer = new ol.layer.Tile({ + }), + new ol.layer.Tile({ + title: Strings.mapBingAerial, + type: 'base', + visible: type === 'bingAerial', source: new ol.source.BingMaps({ key: bingKey, imagerySet: 'Aerial' }) - }); - break; - case 'bingHybrid': - layer = new ol.layer.Tile({ + }), + new ol.layer.Tile({ + title: Strings.mapBingHybrid, + type: 'base', + visible: type === 'bingHybrid', source: new ol.source.BingMaps({ key: bingKey, imagerySet: 'AerialWithLabels' }) - }); - break; - case 'carto': - layer = new ol.layer.Tile({ + }), + new ol.layer.Tile({ + title: Strings.mapCarto, + type: 'base', + visible: type === 'carto', source: new ol.source.XYZ({ url: 'https://cartodb-basemaps-{a-d}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png', attributions: '© OpenStreetMap ' + 'contributors, © CARTO' }) - }); - break; - case 'baidu': - layer = new ol.layer.Tile({ + }), + new ol.layer.Tile({ + title: Strings.mapBaidu, + type: 'base', + visible: type === 'baidu', source: new ol.source.XYZ({ projection: 'BD-MC', tileUrlFunction: function (tileCoord) { @@ -103,7 +113,7 @@ Ext.define('Traccar.view.map.BaseMap', { if (y < 0) { y = 'M' + -y; } - return 'https://online{}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl' + return 'https://online{}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=sl&v=020' .replace('{}', index).replace('{x}', x).replace('{y}', y).replace('{z}', z); }, tileGrid: new ol.tilegrid.TileGrid({ @@ -117,39 +127,43 @@ Ext.define('Traccar.view.map.BaseMap', { }), attributions: '© Baidu' }) - }); - break; - case 'yandexMap': - layer = new ol.layer.Tile({ + }), + new ol.layer.Tile({ + title: Strings.mapYandexMap, + type: 'base', + visible: type === 'yandexMap', source: new ol.source.XYZ({ url: 'https://vec0{1-4}.maps.yandex.net/tiles?l=map&x={x}&y={y}&z={z}', projection: 'EPSG:3395', attributions: '© Yandex' }) - }); - break; - case 'yandexSat': - layer = new ol.layer.Tile({ + }), + new ol.layer.Tile({ + title: Strings.mapYandexSat, + type: 'base', + visible: type === 'yandexSat', source: new ol.source.XYZ({ url: 'https://sat0{1-4}.maps.yandex.net/tiles?l=sat&x={x}&y={y}&z={z}', projection: 'EPSG:3395', attributions: '© Yandex' }) - }); - break; - case 'wikimedia': - layer = new ol.layer.Tile({ + }), + new ol.layer.Tile({ + title: Strings.mapWikimedia, + type: 'base', + visible: type === 'wikimedia', source: new ol.source.OSM({ url: 'https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png' }) - }); - break; - default: - layer = new ol.layer.Tile({ + }), + new ol.layer.Tile({ + title: Strings.mapOsm, + type: 'base', + visible: type === 'osm' || !type, source: new ol.source.OSM({}) - }); - break; - } + }) + ] + }); lat = Traccar.app.getPreference('latitude', Traccar.Style.mapDefaultLat); lon = Traccar.app.getPreference('longitude', Traccar.Style.mapDefaultLon); @@ -197,6 +211,8 @@ Ext.define('Traccar.view.map.BaseMap', { break; } + this.map.addControl(new ol.control.LayerSwitcher()); + target = this.map.getTarget(); if (typeof target === 'string') { target = Ext.get(target).dom; diff --git a/web/load.js b/web/load.js index 528b9652..0d2ccd8a 100644 --- a/web/load.js +++ b/web/load.js @@ -157,6 +157,7 @@ extjsVersion = '6.2.0'; olVersion = '6.1.1'; + olLayerSwitcherVersion = '3.8.3'; proj4jsVersion = '2.6.0'; if (debugMode) { @@ -176,6 +177,9 @@ addStyleFile('https://cdn.traccar.com/js/ol/' + olVersion + '/ol.css'); addScriptFile('https://cdn.traccar.com/js/ol/' + olVersion + '/ol.js'); + addStyleFile('https://cdn.traccar.com/js/ol-layerswitcher/' + olLayerSwitcherVersion + '/ol-layerswitcher.css'); + addScriptFile('https://cdn.traccar.com/js/ol-layerswitcher/' + olLayerSwitcherVersion + '/ol-layerswitcher.js'); + if (debugMode) { addScriptFile('https://cdn.traccar.com/js/proj4js/' + proj4jsVersion + '/proj4-src.js'); } else { -- cgit v1.2.3