maps: add geolocate button to maps (#21049)

This commit is contained in:
Frédéric Péters 2018-03-27 13:56:29 +02:00
parent a00a5358c4
commit 3e52deedae
3 changed files with 151 additions and 1 deletions

View File

@ -209,7 +209,8 @@ class Map(CellBase):
verbose_name = _('Map')
class Media:
js = ('xstatic/leaflet.js', 'js/combo.map.js', 'xstatic/leaflet.markercluster.js')
js = ('xstatic/leaflet.js', 'js/leaflet-gps.js', 'js/combo.map.js',
'xstatic/leaflet.markercluster.js')
css = {'all': ('xstatic/leaflet.css', 'css/combo.map.css')}
def get_default_position(self):

View File

@ -102,6 +102,10 @@ $(function() {
var map = L.map($map_widget[0], map_options);
var map_controls_position = $('body').data('map-controls-position') || 'topleft';
new L.Control.Zoom({position: map_controls_position}).addTo(map);
if (L.Control.Gps) {
var gps_control = new L.Control.Gps({position: map_controls_position});
map.addControl(gps_control);
}
$map_widget[0].leaflet_map = map;
map.setView(latlng, map_options.zoom);

View File

@ -0,0 +1,145 @@
/* 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.LocationIcon = L.Icon.extend({
createIcon: function () {
var div = document.createElement('div');
div.className = 'location-icon';
return div;
},
createShadow: function () {
return null;
}
});
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);
var locationIcon = new L.LocationIcon();
this._gpsMarker = new L.Marker([0,0], {icon: locationIcon});
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;
},
addLayer: function() {
this._map.addLayer(this._gpsMarker);
},
activate: function() {
this._isActive = true;
this.addLayer();
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;
});