From 510d80ef585e77d8edf4082c536c9ac09eb79472 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] manual geoloc stuff (draft, #14478) --- wcs/qommon/http_response.py | 2 + wcs/qommon/static/css/leaflet-gps.css | 52 +++++++++ wcs/qommon/static/images/gps-icon.png | Bin 0 -> 2081 bytes wcs/qommon/static/js/leaflet-gps.js | 195 ++++++++++++++++++++++++++++++++++ wcs/qommon/static/js/qommon.map.js | 2 + 5 files changed, 251 insertions(+) create mode 100644 wcs/qommon/static/css/leaflet-gps.css create mode 100644 wcs/qommon/static/images/gps-icon.png 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..45813ad9 100644 --- a/wcs/qommon/http_response.py +++ b/wcs/qommon/http_response.py @@ -75,6 +75,8 @@ 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_css_include('leaflet-gps.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/css/leaflet-gps.css b/wcs/qommon/static/css/leaflet-gps.css new file mode 100644 index 00000000..40c2ab6d --- /dev/null +++ b/wcs/qommon/static/css/leaflet-gps.css @@ -0,0 +1,52 @@ + +.leaflet-container .leaflet-control-gps { + position:relative; + float:left; + background:#fff; + color:#1978cf; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + /*background-color: rgba(0, 0, 0, 0.25);*/ + background-color: rgba(255, 255, 255, 0.8); + z-index:1000; + box-shadow: 0 1px 7px rgba(0,0,0,0.65); + margin-left:10px; + margin-top:10px; +} +.leaflet-control-gps .gps-button { + display:block; + float:left; + width:26px; + height:26px; + background-image: url('../images/gps-icon.png'); + background-repeat: no-repeat; + background-position: 1px 1px; + background-color: #fff; + border-radius:4px; +} +.leaflet-control-gps .gps-button:hover, +.leaflet-control-gps .gps-button.active:hover { + background-color: #f4f4f4; +} +.leaflet-control-gps .gps-button.disabled { + background-position: 1px -28px; +} +.leaflet-control-gps .gps-button.active { + background-position: 1px -56px; +} + +.leaflet-control-gps .gps-alert { + position:absolute; + left:26px; + bottom:-1px; + width:220px; + padding:2px; + line-height:.95em; + color:#e00; + border: 1px solid #888; + background-color: rgba(255, 255, 255, 0.75); + border-radius:4px; +} + + diff --git a/wcs/qommon/static/images/gps-icon.png b/wcs/qommon/static/images/gps-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..703c0dbd4ee799c31484030802906fb8c3fd9f55 GIT binary patch literal 2081 zcmV++2;TRJP)Zl*! z0OtUEfy2ND05?+KQGh=K{02A*Xw`Qdcmh~lHv!NB++%@`06T!&fjz)Wz*m87K-RX| z4xAZ@0GJEBY&+fqw3OBD2KJTx-wbpEMc@@+{)hy?8NlCwLExGI@(O~o@{a?DY`-ZZ z5!`D>z93}j;=t;Vx{unKJQzp-eAUeFkfba|TM)rRKn{587zoAze+QlpB6tOO z?9GCg;q(G0fCg2?0T7WHc7yxEk7Q)&0~&zy00dYA+z8A9_5uH}4Y#W5_oE<+$PGZr ze6(2bzW@)qz}ta|w(|6{eiMl7SePnnK>~xL- zbLtp%n9KnR!0&+yEqWAq6&N>$(YwI&z_X6}C^C4hv0LU(2Z$SC`f&CaCF*DE>RoSGYcB8(9J(0F< zH@yZ|i1_<=v!HqQX(24an%5dwS>qr%nh zvh=-ZH#XEiM^(QwfKOmlFbiA_Opel5EI=d?kxdxidv)YK^$=JR(K#=hA39Y_7(u*@J90doOUU zh&-Op=NGoOw?9{^^L@YcQ$5c+0366p0q_O;Q7jgB09QpJ zC>D#~bsT3=Rq+~C{k*HHH>m1$j^lhoMDD_5j}!`pr=oxZ0uL_C9Vn1qVXxJ7+5R1j`0Nw|zOe7M| z*AM_C5{dhOEvkBRDwWzbvXw*t$7ou22V%j;{*b!%(uO#=f1`+-&Y ze14Db`>RFdm*u0fz*AkU1gRrLZ9nS(I{F^rb<0nZc)g&pnf?f(kHs4KGb zeSaq~#q+#bqc*luSJN`r7nZ)>sBEeba3&2-^SX~6bG~i(iau9Qm;c+rgz6Fyz@3(E91l|*g0ORP7U^4wq z;MB6Z-Bf1!F6I{ab<8!wXGbIe&cwu@hk$tjKuwvbueXP4@<;U&VPLke^RfKOL=tqi=J zt2-D{jotx68&I51e6);ny)_X3t^io&sg(Z8Vqw_KReU4ai(tLY%{XvijC zUqy04!3){s2QVkQv6^6~U8>d)l4(|(mMXj}1iT6JMAH{^(5|sl`|%hK+IowzD9lvc zZyVG+5S3}mts!;u?56LiD6eWX3G;rC1+EML*-h{()I6)6M}VoJ1h(;|mPCO~n77M7 z0^n4PNiSINPu1XsOm`Bn#gb%!pJ6=LAA!FDD}bNa4ONVDnihyP%BJ0j$$WCuy2~Np zcR+$N^IR7}8Bq*#%e4<<0_FgxMCltTHdWOE@T`bz$2=uQz7hC0L|NH!Zd&jw00000 LNkvXXu0mjfmbm2+ literal 0 HcmV?d00001 diff --git a/wcs/qommon/static/js/leaflet-gps.js b/wcs/qommon/static/js/leaflet-gps.js new file mode 100644 index 00000000..43f7d3be --- /dev/null +++ b/wcs/qommon/static/js/leaflet-gps.js @@ -0,0 +1,195 @@ +(function (factory) { + if(typeof define === 'function' && define.amd) { + //AMD + define(['leaflet'], factory); + } else if(typeof module !== 'undefined') { + // Node/CommonJS + module.exports = factory(require('leaflet')); + } else { + // Browser globals + 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, + // + //Managed Events: + // Event Data passed Description + // + // gps:located {latlng, marker} fired after gps marker is located + // gps:disabled fired after gps is disabled + // + //Methods exposed: + // Method Description + // + // getLocation return Latlng and marker of current position + // activate active tracking on runtime + // deactivate deactive tracking on runtime + // + options: { + autoActive: false, //activate control at startup + autoCenter: false, //move map when gps location change + maxZoom: null, //max zoom for autoCenter + textErr: null, //error message on alert notification + callErr: null, //function that run on gps error activating + style: { //default L.CircleMarker styles + radius: 5, + weight: 2, + color: '#c20', + opacity: 1, + fillColor: '#f23', + fillOpacity: 1 + }, + marker: null, //L.Marker used for location, default use a L.CircleMarker + accuracy: true, //show accuracy Circle + title: 'Center map on your location', + position: 'topleft', + transform: function(latlng) { return latlng }, + setView: false + //TODO add gpsLayer + //TODO timeout autoCenter + }, + + initialize: function(options) { + if(options && options.style) + options.style = L.Util.extend({}, this.options.style, options.style); + L.Util.setOptions(this, options); + this._errorFunc = this.options.callErr || this.showAlert; + 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'); + + this._button = L.DomUtil.create('a', 'gps-button', container); + this._button.href = '#'; + this._button.title = this.options.title; + L.DomEvent + .on(this._button, 'click', L.DomEvent.stop, this) + .on(this._button, 'click', this._switchGps, this); + + this._alert = L.DomUtil.create('div', 'gps-alert', container); + this._alert.style.display = 'none'; + + this._gpsMarker = this.options.marker ? this.options.marker : new L.CircleMarker([0,0], this.options.style); + //if(this.options.accuracy) + // this._accuracyCircle = new L.Circle([0,0], this.options.style); + + this._map + .on('locationfound', this._drawGps, this) + .on('locationerror', this._errorGps, this); + + if(this.options.autoActive) + this.activate(); + + return container; + }, + + onRemove: function(map) { + this.deactivate(); + }, + + _switchGps: function() { + if(this._isActive) + this.deactivate(); + else + this.activate(); + }, + + getLocation: function() { //get last location + return this._currentLocation; + }, + + activate: function() { + this._isActive = true; + this._map.addLayer( this._gpsMarker ); + this._map.locate({ + enableHighAccuracy: true, + watch: true, + //maximumAge:s + setView: this.options.setView, //automatically sets the map view to the user location + maxZoom: this.options.maxZoom + }); + }, + + deactivate: function() { + this._isActive = false; + this._firstMoved = false; + this._map.stopLocate(); + L.DomUtil.removeClass(this._button, 'active'); + this._map.removeLayer( this._gpsMarker ); + //this._gpsMarker.setLatLng([-90,0]); //move to antarctica! + //TODO make method .hide() using _icon.style.display = 'none' + this.fire('gps:disabled'); + }, + + _drawGps: function(e) { + //TODO use e.accuracy for gps circle radius/color + this._currentLocation = this.options.transform(e.latlng); + + this._gpsMarker.setLatLng(this._currentLocation); + + if(this._isActive && (!this._firstMoved || this.options.autoCenter)) + this._moveTo(this._currentLocation); + // if(this._gpsMarker.accuracyCircle) + // this._gpsMarker.accuracyCircle.setRadius((e.accuracy / 2).toFixed(0)); + + this.fire('gps:located', {latlng: this._currentLocation, marker: this._gpsMarker}); + + L.DomUtil.addClass(this._button, 'active'); + }, + + _moveTo: function(latlng) { + this._firstMoved = true; + if(this.options.maxZoom) + this._map.setView(latlng, Math.min(this._map.getZoom(), this.options.maxZoom) ); + else + this._map.panTo(latlng); + }, + + _errorGps: function(e) { + this.deactivate(); + //this._errorFunc.call(this, this.options.textErr || e.message); + }, + + /* _updateAccuracy: function (event) { + var newZoom = this._map.getZoom(), + scale = this._map.options.crs.scale(newZoom); + this._gpsMarker.setRadius(this.options.style.radius * scale); + this._gpsMarker.redraw(); + }, + */ + showAlert: function(text) { + this._alert.style.display = 'block'; + this._alert.innerHTML = text; + var that = this; + clearTimeout(this.timerAlert); + this.timerAlert = setTimeout(function() { + that._alert.style.display = 'none'; + }, 5000); + } +}); + +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..1ba8630d 100644 --- a/wcs/qommon/static/js/qommon.map.js +++ b/wcs/qommon/static/js/qommon.map.js @@ -13,6 +13,7 @@ $(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); + map.addControl( new L.Control.Gps() ); var hidden = $(this).prev(); map.marker = null; var latlng; @@ -67,6 +68,7 @@ $(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 + ''); }); $map_widget.parent().parent().find('label').addClass('activity') -- 2.11.0