From 02e1a9e753b2012149b0358426ce77ed053f024a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Wed, 25 Jan 2017 17:18:07 +0100 Subject: [PATCH] misc: add new button on maps, to re-ask for device geolocation (#14478) --- wcs/qommon/http_response.py | 1 + wcs/qommon/static/js/leaflet-gps.js | 128 ++++++++++++++++++++++++++++++++++++ wcs/qommon/static/js/qommon.map.js | 8 +++ 3 files changed, 137 insertions(+) create mode 100644 wcs/qommon/static/js/leaflet-gps.js diff --git a/wcs/qommon/http_response.py b/wcs/qommon/http_response.py index 5dd94a81..126ffe75 100644 --- a/wcs/qommon/http_response.py +++ b/wcs/qommon/http_response.py @@ -75,6 +75,7 @@ class HTTPResponse(quixote.http_response.HTTPResponse): self.add_javascript(['jquery.js']) self.add_javascript(['../leaflet/leaflet.js']) self.add_css_include('../leaflet/leaflet.css') + self.add_javascript(['leaflet-gps.js']) self.add_javascript(['../../i18n.js']) self.javascript_scripts.append(str(mapped_script_name)) if script_name == 'afterjob.js': diff --git a/wcs/qommon/static/js/leaflet-gps.js b/wcs/qommon/static/js/leaflet-gps.js new file mode 100644 index 00000000..16e4d2fc --- /dev/null +++ b/wcs/qommon/static/js/leaflet-gps.js @@ -0,0 +1,128 @@ +/* adapted from https://github.com/stefanocudini/leaflet-gps + * + * Leaflet Control plugin for tracking gps position, with more options + * by Stefano Cudini, stefano.cudini@gmail.com, http://labs.easyblog.it/ + * published under the MIT license. + */ + +(function (factory) { + if (typeof window.L === 'undefined') + throw 'Leaflet must be loaded first'; + factory(window.L); +})(function (L) { + +L.Control.Gps = L.Control.extend({ + includes: L.Mixin.Events, + options: { + style: { + radius: 5, + weight: 2, + color: '#c20', + opacity: 1, + fillColor: '#f23', + fillOpacity: 1 + }, + position: 'topleft' + }, + + initialize: function(options) { + if(options && options.style) + options.style = L.Util.extend({}, this.options.style, options.style); + L.Util.setOptions(this, options); + this._isActive = false; //global state of gps + this._firstMoved = false; //global state of gps + this._currentLocation = null; //store last location + }, + + onAdd: function (map) { + this._map = map; + + var container = L.DomUtil.create('div', 'leaflet-control-gps leaflet-bar'); + + this._button = L.DomUtil.create('a', 'gps-button', container); + this._button.href = '#'; + this._button.text = '\uf192'; + this._button.style.fontFamily = 'FontAwesome'; + this._button.style.borderRadius = '4px'; + L.DomEvent + .on(this._button, 'click', L.DomEvent.stop, this) + .on(this._button, 'click', this._askGps, this); + + this._gpsMarker = new L.CircleMarker([0,0], this.options.style); + + this._map + .on('locationfound', this._drawGps, this) + .on('locationerror', this._errorGps, this); + + return container; + }, + + onRemove: function(map) { + this.deactivate(); + }, + + _askGps: function() { + this.activate(); + }, + + getLocation: function() { + return this._currentLocation; + }, + + activate: function() { + this._isActive = true; + this._map.addLayer(this._gpsMarker); + this._map.locate({ + enableHighAccuracy: true, + watch: true, + setView: false, + maxZoom: null + }); + }, + + deactivate: function() { + this._isActive = false; + this._firstMoved = false; + this._map.stopLocate(); + this._map.removeLayer( this._gpsMarker ); + this.fire('gps:disabled'); + }, + + _drawGps: function(e) { + this._currentLocation = e.latlng; + + this._gpsMarker.setLatLng(this._currentLocation); + + if(this._isActive && !this._firstMoved) + this._moveTo(this._currentLocation); + + if (this._isActive) { + this.fire('gps:located', {latlng: this._currentLocation, marker: this._gpsMarker}); + } + }, + + _moveTo: function(latlng) { + this._firstMoved = true; + this._map.panTo(latlng); + }, + + _errorGps: function(e) { + this.deactivate(); + }, + +}); + +L.Map.addInitHook(function () { + if (this.options.gpsControl) { + this.gpsControl = L.control.gps(this.options.gpsControl); + this.addControl(this.gpsControl); + } +}); + +L.control.gps = function (options) { + return new L.Control.Gps(options); +}; + +return L.Control.Gps; + +}); diff --git a/wcs/qommon/static/js/qommon.map.js b/wcs/qommon/static/js/qommon.map.js index 4a81f71b..40a37a50 100644 --- a/wcs/qommon/static/js/qommon.map.js +++ b/wcs/qommon/static/js/qommon.map.js @@ -13,6 +13,8 @@ $(window).on('load', function() { var min_zoom = parseInt($map_widget.data('min_zoom')); if (! isNaN(min_zoom)) map_options.minZoom = min_zoom; var map = L.map($(this).attr('id'), map_options); + var gps_control = new L.Control.Gps(); + map.addControl(gps_control); var hidden = $(this).prev(); map.marker = null; var latlng; @@ -67,8 +69,14 @@ $(window).on('load', function() { else if (e.code == 2) message = WCS_I18N.geoloc_position_unavailable; else if (e.code == 3) message = WCS_I18N.geoloc_timeout; $map_widget.parent().parent().find('label').removeClass('activity'); + $map_widget.parent().parent().find('.geoloc-error').remove(); $map_widget.parent().parent().find('label').after('' + message + ''); }); + gps_control.on('gps:located', function(e) { + map.panTo(e.latlng); + map.stopLocate(); + $map_widget.trigger('set-geolocation', e.latlng); + }); $map_widget.parent().parent().find('label').addClass('activity') map.locate({timeout: 10000, maximumAge: 300000, enableHighAccuracy: false}); } -- 2.11.0