diff --git a/lib/www/client/source/src/views/Map.vue b/lib/www/client/source/src/views/Map.vue index 3d31171..f13710d 100644 --- a/lib/www/client/source/src/views/Map.vue +++ b/lib/www/client/source/src/views/Map.vue @@ -222,6 +222,40 @@ export default { } }, + updateURL (includeLayers = true) { + const { lat, lng } = map.getCenter(); + const zoom = map.getZoom(); + const o = []; + const l = []; + if (includeLayers) { + for (const overlay of Object.keys(tileMaps)) { + if (map.hasLayer(tileMaps[overlay])) { + o.push(overlay); + } + } + for (const layer of Object.keys(layers)) { + if (map.hasLayer(layers[layer])) { + l.push(layer); + } + } + document.location.hash = `${zoom}/${lat.toFixed(4)}/${lng.toFixed(4)}:${o.join(";")}:${l.join(";")}`; + } else { + document.location.hash = `${zoom}/${lat.toFixed(4)}/${lng.toFixed(4)}`; + } + }, + + decodeURL () { + const parts = document.location.hash.substring(1).split(":").map(p => decodeURIComponent(p)); + const activeOverlays = parts.length > 1 && parts[1].split(";"); + const activeLayers = parts.length > 2 && parts[2].split(";"); + let position = parts && parts[0].split("/").map(i => Number(i)); + if (position.length != 3) { + position = false; + } + + return {position, activeOverlays, activeLayers}; + }, + ...mapActions(["api"]) }, @@ -229,30 +263,59 @@ export default { mounted () { map = L.map('map', {maxZoom: 22}); - tileMaps["No background"].addTo(map); - layers.OpenSeaMap.addTo(map); - layers.Preplots.addTo(map); + const init = this.decodeURL(); + + if (init.activeOverlays) { + init.activeOverlays.forEach(o => tileMaps[o].addTo(map)); + } else { + tileMaps["No background"].addTo(map); + } + + if (init.activeLayers) { + init.activeLayers.forEach(l => layers[l].addTo(map)); + } else { + layers.OpenSeaMap.addTo(map); + layers.Preplots.addTo(map); + } const layerControl = L.control.layers(tileMaps, layers).addTo(map); - map.setView([0, 0], 3); + + if (init.position) { + map.setView(init.position.slice(1), init.position[0]); + } else { + map.setView([0, 0], 3); + } let moveStart = map.getBounds().pad(0.3); let zoomStart = map.getZoom(); + map.on('movestart', () => { moveStart = map.getBounds().pad(0.3); zoomStart = map.getZoom(); }); + map.on('moveend', () => { if (!moveStart.contains(map.getBounds()) || map.getZoom() != zoomStart) { this.refreshLayers(); } + + this.updateURL(); }); + map.on('overlayadd', this.updateURL); + map.on('overlayremove', this.updateURL); + map.on('layeradd', this.updateURL); + map.on('layerremove', this.updateURL); + this.layerRefreshConfig.forEach( l => { l.layer.on('add', ({target}) => this.refreshLayers([target])); }); - this.fitProjectBounds(); + if (init.position) { + this.refreshLayers(); + } else { + this.fitProjectBounds(); + } // /usr/share/icons/breeze/actions/16/zoom-fit-best.svg