From 4d8750672058e4c95ae07400b07a73abc0be8351 Mon Sep 17 00:00:00 2001 From: "D. Berge" Date: Mon, 17 May 2021 17:01:44 +0200 Subject: [PATCH] Show a map marker if position given in URL hash. If the location URL contains a hash of either: * #z/x/y * #x/y In the first case it will zoom and pan to the location; in the second case it will only pan while maintaining the current (or last used) zoom level. If the location URL does not contain a hash in one of those formats, the marker will be removed from the map. --- lib/www/client/source/src/router/index.js | 1 + lib/www/client/source/src/views/Map.vue | 55 ++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/lib/www/client/source/src/router/index.js b/lib/www/client/source/src/router/index.js index 9458350..946e882 100644 --- a/lib/www/client/source/src/router/index.js +++ b/lib/www/client/source/src/router/index.js @@ -147,6 +147,7 @@ Vue.use(VueRouter) }, { path: "map", + name: "map", component: Map } ] diff --git a/lib/www/client/source/src/views/Map.vue b/lib/www/client/source/src/views/Map.vue index 8cc8ba7..9f65a83 100644 --- a/lib/www/client/source/src/views/Map.vue +++ b/lib/www/client/source/src/views/Map.vue @@ -31,6 +31,7 @@ import 'leaflet-arrowheads' import { mapActions, mapGetters, mapState } from 'vuex'; import ftstamp from '@/lib/FormatTimestamp' import zoomFitIcon from '@/assets/zoom-fit-best.svg' +import crosshairsIcon from '@/assets/crosshairs.svg' import { markdown, markdownInline } from '@/lib/markdown'; var map; @@ -339,7 +340,8 @@ export default { : `/project/${this.$route.params.project}/gis/final/point?${query.toString()}`; } } - ] + ], + hashMarker: null }; }, @@ -380,6 +382,12 @@ export default { } else if (event.channel == "event" && event.payload.schema == this.projectSchema) { //console.log("EVENT", event); } + }, + + $route (to, from) { + if (to.name == "map") { + this.setHashMarker(); + } } }, @@ -587,6 +595,48 @@ export default { map.on('layerremove', this.updateURL); }, + + setHashMarker () { + + const crosshairsMarkerIcon = L.divIcon({ + iconSize: [20, 20], + iconAnchor: [10, 10], + className: 'svgmarker', + html: ` + + + + ` + }); + + const updateMarker = (latlng) => { + if (this.hashMarker) { + if (latlng) { + this.hashMarker.setLatLng(latlng); + } else { + map.removeLayer(this.hashMarker); + this.hashMarker = null; + } + } else if (latlng) { + this.hashMarker = L.marker(latlng, {icon: crosshairsMarkerIcon, interactive: false}); + this.hashMarker.addTo(map).getElement().style.fill = "fuchsia"; + } + } + + const parts = document.location.hash.substring(1).split(":")[0].split("/").map(p => decodeURIComponent(p)); + if (parts.length == 3) { + setTimeout(() => map.setView(parts.slice(1).reverse(), parts[0]), 500); + updateMarker(parts.slice(1).reverse()); + } else if (parts.length == 2) { + parts.reverse(); + setTimeout(() => map.panTo(parts), 500); + updateMarker(parts); + } else { + updateMarker(); + } + }, ...mapActions(["api"]) @@ -745,6 +795,9 @@ export default { }); (new LoadingControl({position: "bottomright"})).addTo(map); + + // Decode a position if one given in the hash + this.setHashMarker(); } }