commit d3612280d9053502e5b5e84a82d2315ee302a353
parent fa61b77b8c88fd5ae3c0a664f81986d516609829
Author: Sergej Orlov <wladimirych@gmail.com>
Date: Wed, 9 May 2018 01:37:33 +0300
move map to current geo position at start #58
Diffstat:
3 files changed, 84 insertions(+), 11 deletions(-)
diff --git a/src/App.js b/src/App.js
@@ -47,7 +47,6 @@ function setUp() {
maxZoom: 18
}
);
- map.enableHashState('m', [10, 55.75185, 37.61856]);
const tracklist = new L.Control.TrackList();
@@ -73,7 +72,7 @@ function setUp() {
const azimuthControl = new L.Control.Azimuth({position: 'topleft'}).addTo(map);
- new LocateControl({
+ const locateControl = new LocateControl({
position: 'topleft',
showError: function({code, message}) {
let customMessage = locationErrorMessage[code];
@@ -84,6 +83,13 @@ function setUp() {
}
}).addTo(map);
+ const defaultLocation = L.latLng(55.75185, 37.61856);
+ const defaultZoom = 10;
+
+ let {lat, lng, zoom, valid} = map.validateState(hashState.getState('m'));
+ locateControl.moveMapToCurrentLocation(defaultZoom, defaultLocation,
+ valid ? L.latLng(lat, lng) : null, valid ? zoom : null);
+ map.enableHashState('m');
/////////// controls top-right corner
const layersControl = L.control.layers(null, null, {collapsed: false})
diff --git a/src/lib/leaflet.control.locate/index.js b/src/lib/leaflet.control.locate/index.js
@@ -1,6 +1,7 @@
import L from 'leaflet';
import 'lib/leaflet.control.commons'
import './style.css';
+import localStorage from 'lib/safe-localstorage';
const STATE_DISABLED = 'disabled';
const STATE_LOCATING = 'locating';
@@ -17,6 +18,7 @@ const EVENT_LOCATION_ERROR = 'location_error';
const EVENT_MAP_MOVE = 'user_move';
const EVENT_MAP_MOVE_END = 'map_move_end';
+const LOCALSTORAGE_POSITION = 'leaflet_locate_position';
const PositionMarker = L.LayerGroup.extend({
initialize: function(options) {
@@ -133,6 +135,47 @@ const LocateControl = L.Control.extend({
return container;
},
+ moveMapToCurrentLocation: function(zoom, fallbackLatLng, forceLatLng, forceZoom) {
+ let storedPosition;
+ try {
+ storedPosition = JSON.parse(localStorage.getItem(LOCALSTORAGE_POSITION));
+ let {lat, lon} = storedPosition;
+ if (lat && lon) {
+ storedPosition = L.latLng(lat, lon);
+ } else {
+ storedPosition = null;
+ }
+ } catch (e) {}
+
+ if (storedPosition) {
+ this._map.setView(forceLatLng ? forceLatLng : storedPosition, forceZoom ? forceZoom : zoom, {animate: false});
+ if (!('geolocation' in navigator)) {
+ return;
+ }
+ navigator.geolocation.getCurrentPosition(
+ (pos) => {
+ this._storePositionToLocalStorage(pos);
+ if (!forceLatLng) {
+ // TODO: check if map has not moved
+ this._map.setView(L.latLng(pos.coords.latitude, pos.coords.longitude), zoom, {animate: false});
+ }
+ },
+ (e) => {
+ if (e.code === 1) {
+ localStorage.removeItem(LOCALSTORAGE_POSITION);
+ }
+ }, {
+ enableHighAccuracy: false,
+ timeout: 500,
+ maximumAge: 0
+ });
+ } else {
+ this._map.setView(forceLatLng ? forceLatLng : fallbackLatLng, forceZoom ? forceZoom : zoom,
+ {animate: false});
+ }
+
+ },
+
_startLocating: function() {
if (!('geolocation' in navigator)) {
const error = {code: 0, message: 'Geolocation not supported'};
@@ -142,8 +185,7 @@ const LocateControl = L.Control.extend({
)
}
this._watchID = navigator.geolocation.watchPosition(
- (pos) => this._handleEvent(EVENT_LOCATION_RECEIVED, pos),
- (e) => this._handleEvent(EVENT_LOCATION_ERROR, e),
+ this._onLocationSuccess.bind(this), this._onLocationError.bind(this),
{
enableHighAccuracy: true,
timeout: this.options.locationAcquireTimeoutMS,
@@ -151,6 +193,23 @@ const LocateControl = L.Control.extend({
);
},
+ _storePositionToLocalStorage: function(pos) {
+ const coords = {lat: pos.coords.latitude, lon: pos.coords.latitude};
+ localStorage.setItem(LOCALSTORAGE_POSITION, JSON.stringify(coords));
+ },
+
+ _onLocationSuccess: function(pos) {
+ this._handleEvent(EVENT_LOCATION_RECEIVED, pos);
+ this._storePositionToLocalStorage(pos);
+ },
+
+ _onLocationError: function(e) {
+ this._handleEvent(EVENT_LOCATION_ERROR, e);
+ if (e.code === 1) {
+ localStorage.removeItem(LOCALSTORAGE_POSITION);
+ }
+ },
+
_stopLocating: function() {
if (this._watchID && navigator.geolocation) {
navigator.geolocation.clearWatch(this._watchID);
diff --git a/src/lib/leaflet.hashState/Leaflet.Map.js b/src/lib/leaflet.hashState/Leaflet.Map.js
@@ -18,18 +18,26 @@ L.Map.include({
return state;
},
- unserializeState: function(values) {
+ validateState: function(values) {
if (!values || values.length !== 3) {
- return false;
+ return {valid: false};
}
- var zoom = parseInt(values[0], 10),
+ let zoom = parseInt(values[0], 10),
lat = parseFloat(values[1]),
lng = parseFloat(values[2]);
- if (isNaN(zoom) || isNaN(lat) || isNaN(lng) || zoom < 0 || zoom > 32 || lat < -90 || lat > 90 ) {
- return false;
+ if (isNaN(zoom) || isNaN(lat) || isNaN(lng) || zoom < 0 || zoom > 32 || lat < -90 || lat > 90) {
+ return {valid: false};
+ }
+ return {lat, lng, zoom, valid: true};
+ },
+
+ unserializeState: function(values) {
+ let {lat, lng, zoom, valid} = this.validateState(values);
+ if (valid) {
+ this.setView([lat, lng], zoom);
+ return true;
}
- this.setView([lat, lng], zoom);
- return true;
+ return false;
}
}
);