Skip to content
This repository was archived by the owner on Nov 8, 2025. It is now read-only.

Commit 3af8fa5

Browse files
committed
Add permalink/hash
Append coordinates on url string to obtain a permalink. We can jump directly to where we map.
1 parent 6ecdec0 commit 3af8fa5

3 files changed

Lines changed: 180 additions & 0 deletions

File tree

deriviste.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ function initialise() {
6565
shadowUrl: "images/marker-shadow.png", iconSize:[25,41], iconAnchor:[12,41],
6666
popupAnchor: [1,-34], tooltipAnchor: [16,-28], shadowSize:[41,41] });
6767

68+
//Initialise start position
69+
var hash = new L.Hash(map);
70+
const url = location.href;
71+
const match = url.match(/#(\d{1,2})\/(-?\d[0-9.]*)\/(-?\d[0-9.]*)/);
72+
if (match){
73+
const [, zoom, lat, lon] = match;
74+
map.setView([lat, lon], zoom);
75+
}
76+
6877
// Initialise Mapillary
6978
mly = new Mapillary.Viewer(
7079
'mapillary',

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<script src="https://unpkg.com/leaflet.vectorgrid@latest/dist/Leaflet.VectorGrid.bundled.js"></script>
1515
<script src="leaflet.rotatedMarker.js"></script>
1616
<script src="leaflet.bingLayer.min.js"></script>
17+
<script src="leaflet-hash.js"></script>
1718
<title>Deriviste</title>
1819
</head>
1920
<body onload="initialise()">

leaflet-hash.js

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/*
2+
Copyright (c) 2013 Michael Lawrence Evans
3+
Released under the MIT license
4+
License: https://github.com/mlevans/leaflet-hash/blob/master/LICENSE.md
5+
Source: https://github.com/mlevans/leaflet-hash
6+
*/
7+
8+
9+
(function(window) {
10+
var HAS_HASHCHANGE = (function() {
11+
var doc_mode = window.documentMode;
12+
return ('onhashchange' in window) &&
13+
(doc_mode === undefined || doc_mode > 7);
14+
})();
15+
16+
L.Hash = function(map) {
17+
this.onHashChange = L.Util.bind(this.onHashChange, this);
18+
19+
if (map) {
20+
this.init(map);
21+
}
22+
};
23+
24+
L.Hash.parseHash = function(hash) {
25+
if(hash.indexOf('#') === 0) {
26+
hash = hash.substr(1);
27+
}
28+
var args = hash.split("/");
29+
if (args.length == 3) {
30+
var zoom = parseInt(args[0], 10),
31+
lat = parseFloat(args[1]),
32+
lon = parseFloat(args[2]);
33+
if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
34+
return false;
35+
} else {
36+
return {
37+
center: new L.LatLng(lat, lon),
38+
zoom: zoom
39+
};
40+
}
41+
} else {
42+
return false;
43+
}
44+
};
45+
46+
L.Hash.formatHash = function(map) {
47+
var center = map.getCenter(),
48+
zoom = map.getZoom(),
49+
precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
50+
51+
return "#" + [zoom,
52+
center.lat.toFixed(precision),
53+
center.lng.toFixed(precision)
54+
].join("/");
55+
},
56+
57+
L.Hash.prototype = {
58+
map: null,
59+
lastHash: null,
60+
61+
parseHash: L.Hash.parseHash,
62+
formatHash: L.Hash.formatHash,
63+
64+
init: function(map) {
65+
this.map = map;
66+
67+
// reset the hash
68+
this.lastHash = null;
69+
this.onHashChange();
70+
71+
if (!this.isListening) {
72+
this.startListening();
73+
}
74+
},
75+
76+
removeFrom: function(map) {
77+
if (this.changeTimeout) {
78+
clearTimeout(this.changeTimeout);
79+
}
80+
81+
if (this.isListening) {
82+
this.stopListening();
83+
}
84+
85+
this.map = null;
86+
},
87+
88+
onMapMove: function() {
89+
// bail if we're moving the map (updating from a hash),
90+
// or if the map is not yet loaded
91+
92+
if (this.movingMap || !this.map._loaded) {
93+
return false;
94+
}
95+
96+
var hash = this.formatHash(this.map);
97+
if (this.lastHash != hash) {
98+
location.replace(hash);
99+
this.lastHash = hash;
100+
}
101+
},
102+
103+
movingMap: false,
104+
update: function() {
105+
var hash = location.hash;
106+
if (hash === this.lastHash) {
107+
return;
108+
}
109+
var parsed = this.parseHash(hash);
110+
if (parsed) {
111+
this.movingMap = true;
112+
113+
this.map.setView(parsed.center, parsed.zoom);
114+
115+
this.movingMap = false;
116+
} else {
117+
this.onMapMove(this.map);
118+
}
119+
},
120+
121+
// defer hash change updates every 100ms
122+
changeDefer: 100,
123+
changeTimeout: null,
124+
onHashChange: function() {
125+
// throttle calls to update() so that they only happen every
126+
// `changeDefer` ms
127+
if (!this.changeTimeout) {
128+
var that = this;
129+
this.changeTimeout = setTimeout(function() {
130+
that.update();
131+
that.changeTimeout = null;
132+
}, this.changeDefer);
133+
}
134+
},
135+
136+
isListening: false,
137+
hashChangeInterval: null,
138+
startListening: function() {
139+
this.map.on("moveend", this.onMapMove, this);
140+
141+
if (HAS_HASHCHANGE) {
142+
L.DomEvent.addListener(window, "hashchange", this.onHashChange);
143+
} else {
144+
clearInterval(this.hashChangeInterval);
145+
this.hashChangeInterval = setInterval(this.onHashChange, 50);
146+
}
147+
this.isListening = true;
148+
},
149+
150+
stopListening: function() {
151+
this.map.off("moveend", this.onMapMove, this);
152+
153+
if (HAS_HASHCHANGE) {
154+
L.DomEvent.removeListener(window, "hashchange", this.onHashChange);
155+
} else {
156+
clearInterval(this.hashChangeInterval);
157+
}
158+
this.isListening = false;
159+
}
160+
};
161+
L.hash = function(map) {
162+
return new L.Hash(map);
163+
};
164+
L.Map.prototype.addHash = function() {
165+
this._hash = L.hash(this);
166+
};
167+
L.Map.prototype.removeHash = function() {
168+
this._hash.removeFrom();
169+
};
170+
})(window);

0 commit comments

Comments
 (0)