nakarte

Source code of https://map.sikmir.ru (fork)
git clone git://git.sikmir.ru/nakarte
Log | Files | Refs | LICENSE

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:
Msrc/App.js | 10++++++++--
Msrc/lib/leaflet.control.locate/index.js | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/lib/leaflet.hashState/Leaflet.Map.js | 22+++++++++++++++-------
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; } } );