summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@proxience.com>2015-04-27 23:35:11 +0200
committerÉtienne Loks <etienne.loks@proxience.com>2015-04-27 23:35:11 +0200
commit1469e4552b0f9b789c46b3ce027d4acb9f906dbd (patch)
tree42363492b9157f396139511acb73a1ed73fe53a7
parentc6f7e24e373142e8618f4b6ed60df04bc0872354 (diff)
downloadChimère-1469e4552b0f9b789c46b3ce027d4acb9f906dbd.tar.bz2
Chimère-1469e4552b0f9b789c46b3ce027d4acb9f906dbd.zip
Add leaflet-pluginsleaflet-permalink
-rw-r--r--chimere/static/leaflet-plugins/LICENSE22
-rw-r--r--chimere/static/leaflet-plugins/README.md35
-rw-r--r--chimere/static/leaflet-plugins/control/Permalink.Layer.js71
-rw-r--r--chimere/static/leaflet-plugins/control/Permalink.Line.js47
-rw-r--r--chimere/static/leaflet-plugins/control/Permalink.Marker.js29
-rw-r--r--chimere/static/leaflet-plugins/control/Permalink.js161
6 files changed, 365 insertions, 0 deletions
diff --git a/chimere/static/leaflet-plugins/LICENSE b/chimere/static/leaflet-plugins/LICENSE
new file mode 100644
index 0000000..1471f11
--- /dev/null
+++ b/chimere/static/leaflet-plugins/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2011-2014, Pavel Shramov, Bruno Bergot
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ of conditions and the following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/chimere/static/leaflet-plugins/README.md b/chimere/static/leaflet-plugins/README.md
new file mode 100644
index 0000000..07c408e
--- /dev/null
+++ b/chimere/static/leaflet-plugins/README.md
@@ -0,0 +1,35 @@
+Leaflet plugins
+============
+
+What ?
+------
+
+Miscellaneous Leaflet plugins for services that need to display
+route information and need satellite imagery from different providers.
+Currently it consists of:
+
+ - Vector layers (`layer/vector/`):
+ * GPX
+ * KML
+
+ - Providers (`layer/tile`):
+ * Google - using Google Maps API v3;
+ * Yandex - using Yandex Maps API v2;
+ * Bing - with proper attribution.
+
+All these providers are implemented with respect to terms of use.
+
+Also there are some useful control plugins (`control/`):
+
+ * Permalink - OpenLayers compatible permanent link with support for storing
+ location data in hash part (#lat=...);
+ * Distance - simple tool to measure distances on maps
+
+Where ?
+------
+
+Homepage : https://github.com/shramov/leaflet-plugins
+
+Downloads : https://github.com/shramov/leaflet-plugins/releases
+
+npm : https://www.npmjs.org/package/leaflet-plugins
diff --git a/chimere/static/leaflet-plugins/control/Permalink.Layer.js b/chimere/static/leaflet-plugins/control/Permalink.Layer.js
new file mode 100644
index 0000000..b290d91
--- /dev/null
+++ b/chimere/static/leaflet-plugins/control/Permalink.Layer.js
@@ -0,0 +1,71 @@
+//#include "Permalink.js
+
+L.Control.Permalink.include({
+ /*
+ options: {
+ useMarker: true,
+ markerOptions: {}
+ },
+ */
+
+ initialize_layer: function() {
+ this.on('update', this._set_layer, this);
+ this.on('add', this._onadd_layer, this);
+ },
+
+ _onadd_layer: function(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;
+ var layer = this.options.layers.currentBaseLayer();
+ if (layer)
+ this._update({layer: layer.name});
+ },
+
+ _set_layer: function(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 j in this._layers) {
+ if (!this._layers.hasOwnProperty(j))
+ continue;
+ obj = this._layers[j];
+ 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;
+ }
+ }
+});
+
diff --git a/chimere/static/leaflet-plugins/control/Permalink.Line.js b/chimere/static/leaflet-plugins/control/Permalink.Line.js
new file mode 100644
index 0000000..794880a
--- /dev/null
+++ b/chimere/static/leaflet-plugins/control/Permalink.Line.js
@@ -0,0 +1,47 @@
+//#include "Permalink.js
+
+L.Control.Permalink.include({
+ /*
+ options: {
+ line: null
+ },
+ */
+
+ initialize_line: function() {
+ this.on('update', this._set_line, this);
+ this.on('add', this._onadd_line, this);
+ },
+
+ _onadd_line: function(e) {
+ if (!this.options.line) return;
+ this.options.line.on('edit', this._update_line, this);
+ this._update_line();
+ },
+
+ _update_line: function() {
+ if (!this.options.line) return;
+ var line = this.options.line;
+ if (!line) return;
+ var text = [], coords = line.getLatLngs();
+ if (!coords.length)
+ return this._update({line: null});
+ for (var i in coords)
+ text.push(coords[i].lat.toFixed(4) + ',' + coords[i].lng.toFixed(4));
+ this._update({line: text.join(';')});
+ },
+
+ _set_line: function(e) {
+ var p = e.params, l = this.options.line;
+ if (!l || !p.line) return;
+ var coords = [], text = p.line.split(';');
+ for (var i in text) {
+ var ll = text[i].split(',');
+ if (ll.length !== 2) continue;
+ coords.push(new L.LatLng(ll[0], ll[1]));
+ }
+ if (!coords.length) return;
+ l.setLatLngs(coords);
+ if (!this._map.hasLayer(l))
+ this._map.addLayer(l);
+ }
+});
diff --git a/chimere/static/leaflet-plugins/control/Permalink.Marker.js b/chimere/static/leaflet-plugins/control/Permalink.Marker.js
new file mode 100644
index 0000000..360f06f
--- /dev/null
+++ b/chimere/static/leaflet-plugins/control/Permalink.Marker.js
@@ -0,0 +1,29 @@
+//#include "Permalink.js
+
+L.Control.Permalink.include({
+ /*
+ options: {
+ useMarker: true,
+ markerOptions: {}
+ },
+ */
+
+ initialize_marker: function() {
+ this.on('update', this._set_marker, this);
+ },
+
+ _set_marker: function(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});
+ }
+});
diff --git a/chimere/static/leaflet-plugins/control/Permalink.js b/chimere/static/leaflet-plugins/control/Permalink.js
new file mode 100644
index 0000000..1ed4b9b
--- /dev/null
+++ b/chimere/static/leaflet-plugins/control/Permalink.js
@@ -0,0 +1,161 @@
+L.Control.Permalink = L.Control.extend({
+ includes: L.Mixin.Events,
+
+ options: {
+ position: 'bottomleft',
+ useAnchor: true,
+ useLocation: false,
+ 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);
+ if (this.options.useLocation)
+ location.replace('#' + params.slice(1));
+ 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;
+ var 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) {
+ 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].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)
+ {
+ 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]] = decodeURI(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);
+ }
+};