diff --git a/index.html b/index.html index b1a01e1..e2cf24a 100644 --- a/index.html +++ b/index.html @@ -115,11 +115,36 @@ background-color: transparent; } + + #mapTileServiceSelector { + position: absolute; + top: 10px; + left: 10px; + width: 150px; + height: auto; + padding: 5px; + font-size: 14px; + border: 1px solid #ccc; + border-radius: 4px; + background-color: white; + z-index: 1000; + } + #mapTileServiceSelector option { + padding: 5px; + background-color: #f9f9f9; + color: #333; + } + #mapTileServiceSelector:focus, + #mapTileServiceSelector:active { + border-color: #999; s + outline: none; + }
+ diff --git a/index.js b/index.js index 0357499..6f663c8 100644 --- a/index.js +++ b/index.js @@ -1,24 +1,71 @@ - // set up map - var map = L.map('map', { - doubleClickZoom: true, - zoomControl: false, // added manually below - tapHold: true + doubleClickZoom: true, + zoomControl: false, + tapHold: true }); + if (localStorage.getItem('map.lat') === null) { map.setView([30, -30], 3); } else { map.setView([localStorage.getItem('map.lat'), localStorage.getItem('map.lng')], localStorage.getItem('map.zoom')); } + map.attributionControl.setPrefix(''); L.control.scale({position: 'bottomleft'}).addTo(map); L.control.zoom({position: 'topright'}).addTo(map); -L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { - maxZoom: 19, - attribution: "© OpenStreetMap" +var select = document.createElement('select'); +select.id = 'mapTileServiceSelector'; + +for (var serviceKey in mapServices) { + var option = document.createElement('option'); + option.value = serviceKey; + option.textContent = serviceKey; + select.appendChild(option); +} + +document.body.appendChild(select); + +var tileLayer = null; +var annotationLayer = null; + +function addMapService(map, serviceKey) { + const service = mapServices[serviceKey]; + if (!service) return; + + if (tileLayer && map.hasLayer(tileLayer)) { + map.removeLayer(tileLayer); + } + if (annotationLayer && map.hasLayer(annotationLayer)) { + map.removeLayer(annotationLayer); + } + const subdomains = service.subdomains || []; + + tileLayer = L.tileLayer(service.url, { + maxZoom: service.options.maxZoom, + attribution: service.options.attribution, + tms: service.options.tms || false, + subdomains: subdomains//service.subdomains.join(',') + }).addTo(map); + + if(service.annotationLayer) { + const annotationLayersubdomains = service.annotationLayer.subdomains || []; + annotationLayer = L.tileLayer(service.annotationLayer.url, { + maxZoom: service.annotationLayer.options.maxZoom, + tms: service.annotationLayer.options.tms || false, + subdomains: annotationLayersubdomains//service.subdomains.join(',') }).addTo(map); + } +} + +//addMapService(map, defaultServiceKey); +select.value = defaultServiceKey; +select.addEventListener('change', function() { + const selectedService = this.value; + addMapService(map, selectedService); +}); +select.dispatchEvent(new Event('change')); var pinIcon = L.icon({ iconUrl: 'images/pin-icon.png', @@ -31,10 +78,7 @@ var pinIcon = L.icon({ var tracks = {}; var initDone = false; - - // set up webxdc - window.webxdc.setUpdateListener((update) => { const payload = update.payload; if (payload.action === 'pos') { @@ -91,10 +135,7 @@ window.webxdc.setUpdateListener((update) => { initDone = true; }); - - // contact's tracks - function updateTrack(contactId) { var track = tracks[contactId]; @@ -153,7 +194,6 @@ setInterval(() => { // share a dedicated location - var popup; var popupLatlng; @@ -192,7 +232,6 @@ map.on('contextmenu', onMapLongClick); // handle position and zoom - function onMapMoveOrZoom(e) { localStorage.setItem('map.lat', map.getCenter().lat); localStorage.setItem('map.lng', map.getCenter().lng); @@ -203,9 +242,7 @@ map.on('moveend', onMapMoveOrZoom); map.on('zoomend', onMapMoveOrZoom); - // tools - function htmlentities(rawStr) { return rawStr.replace(/[\u00A0-\u9999<>\&]/g, ((i) => `&#${i.charCodeAt(0)};`)); } diff --git a/manifest.toml b/manifest.toml index 5d74bf3..c6fa453 100644 --- a/manifest.toml +++ b/manifest.toml @@ -1,3 +1,4 @@ name = "Maps" source_code_url = "https://github.com/deltachat/maps" request_internet_access = true +request_integration = "map" diff --git a/mapServices.js b/mapServices.js new file mode 100644 index 0000000..293b93b --- /dev/null +++ b/mapServices.js @@ -0,0 +1,119 @@ +const defaultServiceKey = 'OSmap.de'; +const mapServices = { + 'OpenStreetMap': { + url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', + options: { + maxZoom: 19, + attribution: '© OpenStreetMap' + } + }, + 'OSmap': { + url: 'https://{s}.tile.osm.org/{z}/{x}/{y}.png', + subdomains: ['a', 'b', 'c'], + options: { + maxZoom: 18, + attribution: '© OSmap' + } + }, + 'OSmap.de': { + url: 'https://{s}.tile.openstreetmap.de/{z}/{x}/{y}.png', + subdomains: ['a', 'b', 'c', 'd'], + options: { + maxZoom: 18, + attribution: '© OSmap.de' + } + }, + 'OSmap.fr': { + url: 'https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', + subdomains: ['a', 'b', 'c'], + options: { + maxZoom: 18, + attribution: '© OSmap.fr' + } + }, + 'opentopomap': { + url: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', + subdomains: ['a', 'b', 'c'], + options: { + maxZoom: 18, + attribution: '© opentopomap' + } + }, + '高德地图': { + url: 'https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', + subdomains: '1234', + options: { + maxZoom: 18, + attribution: '© 高德地图' + } + }, + '高德路况': { + url: 'https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', + subdomains: '1234', + options: { + maxZoom: 18, + attribution: '© 高德路况' + }, + annotationLayer: { + url: 'https://tm.amap.com/trafficengine/mapabc/traffictile?v=1.0&=&=&t=1&t=1&x={x}&y={y}&z={z}', + options: { + maxZoom: 18 + } + } + }, + '高德卫星': { + url: 'https://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', + subdomains: '1234', + options: { + maxZoom: 18, + attribution: '© 高德卫星' + }, + annotationLayer: { + url: 'https://webst0{s}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}', + subdomains: '1234', + options: { + maxZoom: 18 + } + } + }, + '腾讯地图': { + url: 'https://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={y}&type=vector&styleid=1', + subdomains: '012', + options: { + maxZoom: 18, + tms: true, + attribution: '© 腾讯地图' + } + }, + '天地图': { + url: 'https://t{s}.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec_w&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=75f0434f240669f4a2df6359275146d2', + subdomains: '01234567',//['0', '1', '2', '3', '4', '5', '6', '7'], + options: { + maxZoom: 18, + attribution: '© 天地图' + }, + annotationLayer: { + url: 'https://t{s}.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=75f0434f240669f4a2df6359275146d2', + subdomains: '01234567', + options: { + maxZoom: 18 + } + } + }, + '天地图卫星': { + url: 'https://t{s}.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=75f0434f240669f4a2df6359275146d2', + subdomains: '01234567', + options: { + maxZoom: 18, + attribution: '© 天地图' + }, + annotationLayer: { + url: 'https://t{s}.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=75f0434f240669f4a2df6359275146d2', + subdomains: '01234567', + options: { + maxZoom: 18 + } + } + } +}; +