Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

permalink: Modular permalink plugin

Incompatible initialization: layers is passed in options
and not as first argument
  • Loading branch information...
commit 0130233919d3f0472a7356d807e58c57915deafe 1 parent 3527666
Pavel Shramov authored
74 control/Permalink.Layer.js
View
@@ -0,0 +1,74 @@
+L.Control.Permalink.include({
+ /*
+ options: {
+ useMarker: true,
+ markerOptions: {}
+ },
+ */
+
+ initialize_layer: function() {
+ console.info("Initialize layer");
+ this.on('update', this._set_layer, this);
+ this.on('add', this._onadd_layer, this);
+ },
+
+ _onadd_layer: function(e) {
+ console.info("onAdd::layer", e);
+ this._map.on('layeradd', this._update_layer, this);
+ this._map.on('layerremove', this._update_layer, this);
+ this._update_layer();
+ },
+
+ _update_layer: function() {
+ if (!this.options.layers) return;
+ console.info(this.options.layers);
+ var layer = this.options.layers.currentBaseLayer();
+ if (layer)
+ this._update({layer: layer.name});
+ },
+
+ _set_layer: function(e) {
+ console.info("Set layer", e);
+ var p = e.params;
+ if (!this.options.layers || !p.layer) return;
+ this.options.layers.chooseBaseLayer(p.layer);
+ }
+});
+
+L.Control.Layers.include({
+ chooseBaseLayer: function(name) {
+ var layer, obj;
+ for (var i in this._layers) {
+ if (!this._layers.hasOwnProperty(i))
+ continue;
+ obj = this._layers[i];
+ if (!obj.overlay && obj.name == name)
+ layer = obj.layer;
+ }
+ if (!layer || this._map.hasLayer(layer))
+ return;
+
+ for (var i in this._layers) {
+ if (!this._layers.hasOwnProperty(i))
+ continue;
+ obj = this._layers[i];
+ if (!obj.overlay && this._map.hasLayer(obj.layer))
+ this._map.removeLayer(obj.layer)
+ }
+ this._map.addLayer(layer)
+ this._update();
+ },
+
+ currentBaseLayer: function() {
+ for (var i in this._layers) {
+ if (!this._layers.hasOwnProperty(i))
+ continue;
+ var obj = this._layers[i];
+ console.info("Layer: ", obj.name, obj);
+ if (obj.overlay) continue;
+ if (!obj.overlay && this._map.hasLayer(obj.layer))
+ return obj;
+ }
+ }
+});
+
29 control/Permalink.Marker.js
View
@@ -0,0 +1,29 @@
+L.Control.Permalink.include({
+ /*
+ options: {
+ useMarker: true,
+ markerOptions: {}
+ },
+ */
+
+ initialize_marker: function() {
+ console.info("Initialize marker");
+ this.on('update', this._set_marker, this);
+ },
+
+ _set_marker: function(e) {
+ console.info("Set marker", e);
+ var p = e.params;
+ //if (!this.options.useMarker) return;
+ if (this._marker) return;
+ if (p.marker != 1) return;
+ if (p.mlat !== undefined && p.mlon !== undefined)
+ return this._update({mlat: null, mlon: null,
+ lat: p.mlat, lon: p.mlon, marker: 1});
+ this._marker = new L.Marker(new L.LatLng(p.lat, p.lon),
+ this.options.markerOptions);
+ this._marker.bindPopup("<a href='" + this._update_href() + "'>" + this.options.text + "</a>");
+ this._map.addLayer(this._marker);
+ this._update({marker: null});
+ }
+});
380 control/Permalink.js
View
@@ -1,219 +1,161 @@
-L.Control.Permalink = L.Control.extend({
- options: {
- position: "bottomleft",
- useAnchor: true,
- useMarker: true,
- markerOptions: {}
- },
-
- initialize: function(layers, options) {
- L.Util.setOptions(this, options);
- this._set_urlvars();
- this._centered = false;
- this._layers = layers;
- this._marker = null;
- },
-
- onAdd: function(map) {
- this._container = L.DomUtil.create('div', 'leaflet-control-attribution leaflet-control-permalink');
- L.DomEvent.disableClickPropagation(this._container);
- map.on('moveend', this._update_center, this);
- map.on('layeradd', this._update_layers, this);
- map.on('layerremove', this._update_layers, this);
- this._map = map;
- this._href = L.DomUtil.create('a', null, this._container);
- this._href.innerHTML = "Permalink";
- this._set_center(this._params);
- this._set_marker(this._params);
- this._update_layers();
- this._update_center();
-
- if (this.options.useAnchor && 'onhashchange' in window) {
- var _this = this, fn = window.onhashchange;
- window.onhashchange = function() {
- _this._set_urlvars();
- _this._set_center(_this._params, true);
- _this._set_marker(_this._params);
- if (fn) return fn();
- }
- }
-
- return this._container;
- },
-
- _update_center: function() {
- if (!this._map) return;
-
- var center = this._map.getCenter();
- center = this._round_point(center);
- this._params['zoom'] = this._map.getZoom();
- this._params['lat'] = center.lat;
- this._params['lon'] = center.lng;
- this._update_href();
- },
-
- _update_href: function() {
- var params = L.Util.getParamString(this._params);
- var sep = '?';
- if (this.options.useAnchor) sep = '#';
- this._href.setAttribute('href', this._url_base + sep + params.slice(1))
- },
-
- _update_layers: function() {
- if (!this._layers) return;
- var layer = this._layers.currentBaseLayer();
- if (layer)
- this._params['layer'] = layer.name;
- this._update_href();
- },
-
- _round_point : function(point) {
- var bounds = this._map.getBounds(), size = this._map.getSize();
- var ne = bounds.getNorthEast(), sw = bounds.getSouthWest();
-
- var round = function (x, p) {
- if (p == 0) return x;
- shift = 1;
- while (p < 1 && p > -1) {
- x *= 10;
- p *= 10;
- shift *= 10;
- }
- return Math.floor(x)/shift;
- }
- point.lat = round(point.lat, (ne.lat - sw.lat) / size.y);
- point.lng = round(point.lng, (ne.lng - sw.lng) / size.x);
- return point;
- },
-
- _set_urlvars: function()
- {
- function alter(p) {
- if (!p.mlat || !p.mlon) return p;
- p.lat = p.mlat;
- p.lon = p.mlon;
- p.marker = '1';
- delete p['mlat'];
- delete p['mlon'];
- return p;
- }
-
- this._url_base = window.location.href.split('#')[0];
- var ph = {};
- if (this.options.useAnchor)
- ph = alter(L.UrlUtil.queryParse(window.location.hash.slice(1)));
-
- var q = L.UrlUtil.query();
- if (!q) {
- this._params = ph;
- return;
- }
-
- var pq = alter(L.UrlUtil.queryParse(q));
-
- if (!this.options.useAnchor) {
- this._url_base = this._url_base.split('?')[0]
- this._params = pq;
- return;
- }
-
- this._params = ph;
- if (pq.lat && pq.lon && pq.zoom)
- this._params = L.Util.extend({lat: pq.lat, lon: pq.lon, zoom: pq.zoom}, this._params);
- if (pq.layer)
- this._params = L.Util.extend({layer: pq.layer}, this._params);
- },
-
- _set_center: function(params, force)
- {
- if (!force && this._centered) return;
- if (params.zoom == undefined ||
- params.lat == undefined ||
- params.lon == undefined) return;
- this._centered = true;
- this._map.setView(new L.LatLng(params.lat, params.lon), params.zoom);
- if (params.layer && this._layers)
- this._layers.chooseBaseLayer(params.layer);
- },
-
- _set_marker: function(params)
- {
- if (this._marker)
- this._map.removeLayer(this._marker);
- this._marker = null;
- if (params.marker != '1' || !this._centered || !this.options.useMarker) return;
- this._marker = new L.Marker(new L.LatLng(params.lat, params.lon), this.options.markerOptions);
- this._map.addLayer(this._marker);
- }
-});
-
-L.Control.Layers.include({
- chooseBaseLayer: function(name) {
- var layer, obj;
- for (var i in this._layers) {
- if (!this._layers.hasOwnProperty(i))
- continue;
- obj = this._layers[i];
- if (!obj.overlay && obj.name == name)
- layer = obj.layer;
- }
- if (!layer || this._map.hasLayer(layer))
- return;
-
- for (var i in this._layers) {
- if (!this._layers.hasOwnProperty(i))
- continue;
- obj = this._layers[i];
- if (!obj.overlay && this._map.hasLayer(obj.layer))
- this._map.removeLayer(obj.layer)
- }
- this._map.addLayer(layer)
- this._update();
- },
-
- currentBaseLayer: function() {
- for (var i in this._layers) {
- if (!this._layers.hasOwnProperty(i))
- continue;
- var obj = this._layers[i];
- if (obj.overlay) continue;
- if (!obj.overlay && this._map.hasLayer(obj.layer))
- return obj;
- }
- }
-});
-
-L.UrlUtil = {
- queryParse: function(s) {
- var p = {};
- var sep = "&";
- if (s.search("&amp;") != -1)
- sep = "&amp;";
- var params = s.split(sep);
- for(var i = 0; i < params.length; i++) {
- var tmp = params[i].split('=');
- if (tmp.length != 2) continue;
- p[tmp[0]] = tmp[1];
- }
- return p;
- },
-
- query: function() {
- var href = window.location.href.split('#')[0], idx = href.indexOf('?');
- if (idx < 0)
- return '';
- return href.slice(idx+1);
- },
-
- hash: function() { return window.location.hash.slice(1) },
-
- updateParamString: function (q, obj) {
- var p = L.UrlUtil.queryParse(q);
- for (var i in obj) {
- if (obj.hasOwnProperty(i))
- p[i] = obj[i];
- }
- return L.Util.getParamString(p).slice(1);
- }
-};
-
+L.Control.Permalink = L.Control.extend({
+ includes: L.Mixin.Events,
+
+ options: {
+ position: "bottomleft",
+ useAnchor: true,
+ text: "Permalink"
+ },
+
+ initialize: function(options) {
+ L.Util.setOptions(this, options);
+ this._params = {};
+ this._set_urlvars();
+ this.on("update", this._set_center, this);
+ for (var i in this) {
+ if (typeof(i) === "string" && i.indexOf('initialize_') == 0)
+ this[i]();
+ }
+ },
+
+ onAdd: function(map) {
+ this._container = L.DomUtil.create('div', 'leaflet-control-attribution leaflet-control-permalink');
+ L.DomEvent.disableClickPropagation(this._container);
+ this._map = map;
+ this._href = L.DomUtil.create('a', null, this._container);
+ this._href.innerHTML = this.options.text
+
+ map.on('moveend', this._update_center, this);
+ this.fire("update", {params: this._params})
+ this._update_center();
+
+ if (this.options.useAnchor && 'onhashchange' in window) {
+ var _this = this, fn = window.onhashchange;
+ window.onhashchange = function() {
+ _this._set_urlvars();
+ if (fn) return fn();
+ }
+ }
+
+ this.fire('add', {map: map});
+
+ return this._container;
+ },
+
+ _update_center: function() {
+ if (!this._map) return;
+
+ var center = this._round_point(this._map.getCenter());
+ this._update({zoom: this._map.getZoom(), lat: center.lat, lon: center.lng});
+ },
+
+ _update_href: function() {
+ var params = L.Util.getParamString(this._params);
+ var sep = '?';
+ if (this.options.useAnchor) sep = '#';
+ var url = this._url_base + sep + params.slice(1);
+ if (this._href) this._href.setAttribute('href', url);
+ return url;
+ },
+
+ _round_point : function(point) {
+ var bounds = this._map.getBounds(), size = this._map.getSize();
+ var ne = bounds.getNorthEast(), sw = bounds.getSouthWest();
+
+ var round = function (x, p) {
+ if (p == 0) return x;
+ shift = 1;
+ while (p < 1 && p > -1) {
+ x *= 10;
+ p *= 10;
+ shift *= 10;
+ }
+ return Math.floor(x)/shift;
+ }
+ point.lat = round(point.lat, (ne.lat - sw.lat) / size.y);
+ point.lng = round(point.lng, (ne.lng - sw.lng) / size.x);
+ return point;
+ },
+
+ _update: function(obj, source) {
+ console.info("Update", obj, this._params);
+ for(var i in obj) {
+ if (!obj.hasOwnProperty(i)) continue;
+ if (obj[i] != null && obj[i] != undefined)
+ this._params[i] = obj[i]
+ else
+ delete this._params[i];
+ }
+
+ this._update_href();
+ },
+
+ _set_urlvars: function()
+ {
+ this._url_base = window.location.href.split('#')[0];
+
+ var p;
+ if (this.options.useAnchor)
+ p = L.UrlUtil.queryParse(L.UrlUtil.hash());
+ else
+ p = L.UrlUtil.queryParse(L.UrlUtil.query());
+
+ function eq(x, y) {
+ for(var i in x)
+ if (x.hasOwnProperty(i) && x[i] != y[i])
+ return false;
+ return true;
+ }
+
+ if (eq(p, this._params) && eq(this._params, p))
+ return;
+ this._params = p;
+ this._update_href();
+ this.fire("update", {params: this._params})
+ },
+
+ _set_center: function(e)
+ {
+ console.info("Update center", e);
+ var params = e.params;
+ if (params.zoom == undefined ||
+ params.lat == undefined ||
+ params.lon == undefined) return;
+ this._map.setView(new L.LatLng(params.lat, params.lon), params.zoom);
+ }
+});
+
+L.UrlUtil = {
+ queryParse: function(s) {
+ var p = {};
+ var sep = "&";
+ if (s.search("&amp;") != -1)
+ sep = "&amp;";
+ var params = s.split(sep);
+ for(var i = 0; i < params.length; i++) {
+ var tmp = params[i].split('=');
+ if (tmp.length != 2) continue;
+ p[tmp[0]] = tmp[1];
+ }
+ return p;
+ },
+
+ query: function() {
+ var href = window.location.href.split('#')[0], idx = href.indexOf('?');
+ if (idx < 0)
+ return '';
+ return href.slice(idx+1);
+ },
+
+ hash: function() { return window.location.hash.slice(1) },
+
+ updateParamString: function (q, obj) {
+ var p = L.UrlUtil.queryParse(q);
+ for (var i in obj) {
+ if (obj.hasOwnProperty(i))
+ p[i] = obj[i];
+ }
+ return L.Util.getParamString(p).slice(1);
+ }
+};
+
23 examples/permalink.html
View
@@ -0,0 +1,23 @@
+<html>
+<head>
+ <title>Leaflet</title>
+ <link rel="stylesheet" href="/leaflet/leaflet.css" />
+ <script src="/leaflet/leaflet.js"></script>
+ <script src="../control/Permalink.js"></script>
+ <script src="../control/Permalink.Marker.js"></script>
+ <script src="../control/Permalink.Layer.js"></script>
+</head>
+<body>
+ <div style="width:100%; height:100%" id="map"></div>
+<script type='text/javascript'>
+var map = new L.Map('map', {center: new L.LatLng(67.6755, 33.936), zoom: 10});
+var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
+map.addLayer(osm);
+var kosm = new L.TileLayer('http://{s}.tile.osmosnimki.ru/kosmo/{z}/{x}/{y}.png', {attribution:'Tiles Courtesy of <a href="http://kosmosnimki.ru/" target="_blank">kosmosnimki.ru</a>'});
+var layers = new L.Control.Layers({'OSM':osm, "Kosmo":kosm});
+map.addControl(layers);
+map.addControl(new L.Control.Permalink({text: 'Ссылка', layers: layers}));
+</script>
+
+</body>
+</html>
Please sign in to comment.
Something went wrong with that request. Please try again.