nakarte

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

commit 7ae72a8901dc9ecb001359e4b005684291472605
parent 257d6c51c332e12b4f3d61319c1855424432d092
Author: Sergej Orlov <wladimirych@gmail.com>
Date:   Wed, 25 Apr 2018 10:47:20 +0300

add geolocation control #59

Diffstat:
Mpackage.json | 1+
Msrc/App.js | 6+++++-
Asrc/lib/leaflet.control.mylocation/index.js | 138+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/lib/leaflet.control.mylocation/location-arrow-active.svg | 5+++++
Asrc/lib/leaflet.control.mylocation/location-arrow.svg | 5+++++
Asrc/lib/leaflet.control.mylocation/style.css | 37+++++++++++++++++++++++++++++++++++++
6 files changed, 191 insertions(+), 1 deletion(-)

diff --git a/package.json b/package.json @@ -61,6 +61,7 @@ "image-promise": "^4.0.1", "knockout": "^3.4.0", "leaflet": "1.0.3", + "leaflet.locatecontrol": "^0.62.0", "load-script": "^1.0.0", "mapillary-js": "2.5.2", "pbf": "^3.0.5", diff --git a/src/App.js b/src/App.js @@ -26,6 +26,8 @@ import 'lib/leaflet.control.jnx'; import 'lib/leaflet.control.jnx/hash-state'; import 'lib/leaflet.control.azimuth'; import {hashState, bindHashStateReadOnly} from 'lib/leaflet.hashState/hashState'; +import {MyLocate} from 'lib/leaflet.control.mylocation'; + function setUp() { fixAll(); @@ -61,11 +63,13 @@ function setUp() { .enableHashState('n2'); L.Control.Panoramas.hashStateUpgrader(panoramas).enableHashState('n'); - new L.Control.Coordinates({position: 'topleft'}).addTo(map); const azimuthControl = new L.Control.Azimuth({position: 'topleft'}).addTo(map); + const location = new MyLocate(); + location.addTo(map); + /////////// controls top-right corner const layersControl = L.control.layers(null, null, {collapsed: false}) diff --git a/src/lib/leaflet.control.mylocation/index.js b/src/lib/leaflet.control.mylocation/index.js @@ -0,0 +1,137 @@ +import L from 'leaflet'; +import 'leaflet.locatecontrol'; +import './style.css'; + + +const MyLocate = L.Control.Locate.extend({ + options: { + icon: 'icon-position', + iconLoading: 'icon-position', + setView: 'untilPan', + flyTo: true, + cacheLocation: false, + showPopup: false, + locateOptions: { + enableHighAccuracy: true, + watch: true, + setView: false + }, + maxZoom: 16, + + circleStyle: { + interactive: false, + color: '#4271a8', + fillOpacity: 0.3, + weight: 0, + }, + markerStyle: { + color: '#2a85d4', + weight: 2.5, + opacity: 0.8, + fillOpacity: 0.4, + radius: 8 + }, + minCirclePixelRadius: 50 + + }, + + start: function() { + this.options.keepCurrentZoomLevel = false; + L.Control.Locate.prototype.start.call(this); + }, + + _onDrag: function() { + if (this._settingView) { + return; + } + L.Control.Locate.prototype._onDrag.call(this); + }, + + _activate: function() { + if (!this._active) { + this._map.on('movestart', this._onDrag, this); + this._map.on('zoom', this._onZoom, this); + } + L.Control.Locate.prototype._activate.call(this); + }, + + _deactivate: function() { + L.Control.Locate.prototype._deactivate.call(this); + this._map.off('movestart', this._onDrag, this); + this._map.off('zoom', this._onZoom, this); + }, + + _onZoom: function() { + if (!this._circle || !this.options.minCirclePixelRadius) { + return; + } + if (typeof this._circle._origFillOpacity === 'undefined') { + this._circle._origFillOpacity = this._circle.options.fillOpacity; + } + L.Util.requestAnimFrame(() => { + const opacity = this._circle._radius < this.options.minCirclePixelRadius ? + 0 : this._circle._origFillOpacity; + console.log(this._circle._radius, this.options.minCirclePixelRadius, this._circle._origFillOpacity); + this._circle.setStyle({fillOpacity: opacity}); + }); + }, + + _onClick: function() { + this.options.keepCurrentZoomLevel = false; + L.Control.Locate.prototype._onClick.call(this); + }, + + _onMarkerClick: function() { + this._userPanned = false; + this._updateContainerStyle(); + this.options.keepCurrentZoomLevel = false; + this.setView(); + }, + + _drawMarker: function() { + var newMarker = !this._marker; + L.Control.Locate.prototype._drawMarker.call(this); + if (newMarker) { + this._marker.on('click', this._onMarkerClick.bind(this)); + } + }, + + setView: function() { + this._drawMarker(); + if (this._isOutsideMapBounds()) { + this._event = undefined; // clear the current location so we can get back into the bounds + this.options.onLocationOutsideMapBounds(this); + } else { + var coords = this._event, + lat = coords.latitude, + lng = coords.longitude, + latlng = new L.LatLng(lat, lng), + zoom; + if (!this.options.keepCurrentZoomLevel) { + // fix for leaflet issue #6139 + var bounds = latlng.toBounds(coords.accuracy * 2); + zoom = this._map.getBoundsZoom(bounds); + zoom = this.options.maxZoom ? Math.min(zoom, this.options.maxZoom) : zoom; + } + this._settingView = true; + this._map.once('moveend', () => { + this._settingView = false; + }); + var f = this.options.flyTo ? this._map.flyTo : this._map.setView; + f.call(this._map, latlng, zoom); + + this.options.keepCurrentZoomLevel = true; + } + }, + + } +); + +export {MyLocate}; + + +// + при включение зумить, но не ближе ~16 уровня и не ближе круга точности. +// + зум можно уменьшать только если круг точности большой и на 16 уровень не помещается +// + при обновлении позиции зум не менять +// + при плавном приближении маркер сильно зумится +// + а что с сохранением состоямия в localStorage? -- ничего +\ No newline at end of file diff --git a/src/lib/leaflet.control.mylocation/location-arrow-active.svg b/src/lib/leaflet.control.mylocation/location-arrow-active.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<svg height="1792" viewBox="0 0 1792 1792" width="1792" xmlns="http://www.w3.org/2000/svg"> + <path style="fill:#c00;" d="M1593 349l-640 1280q-17 35-57 35-5 0-15-2-22-5-35.5-22.5t-13.5-39.5v-576h-576q-22 0-39.5-13.5t-22.5-35.5 4-42 29-30l1280-640q13-7 29-7 27 0 45 19 15 14 18.5 34.5t-6.5 39.5z"/> +</svg> +\ No newline at end of file diff --git a/src/lib/leaflet.control.mylocation/location-arrow.svg b/src/lib/leaflet.control.mylocation/location-arrow.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<svg height="1792" viewBox="0 0 1792 1792" width="1792" xmlns="http://www.w3.org/2000/svg"> + <path style="fill:#555;" d="M1593 349l-640 1280q-17 35-57 35-5 0-15-2-22-5-35.5-22.5t-13.5-39.5v-576h-576q-22 0-39.5-13.5t-22.5-35.5 4-42 29-30l1280-640q13-7 29-7 27 0 45 19 15 14 18.5 34.5t-6.5 39.5z"/> +</svg> +\ No newline at end of file diff --git a/src/lib/leaflet.control.mylocation/style.css b/src/lib/leaflet.control.mylocation/style.css @@ -0,0 +1,37 @@ +.icon-position { + display: block; + position: absolute; + width: 60%; + height: 60%; + top: 20%; + left: 20%; + background-image: url("location-arrow.svg"); + background-size: 100%; + background-repeat: no-repeat; + background-position: 50% 50%; +} + +.following .icon-position { + background-image: url("location-arrow-active.svg"); +} + +.requesting .icon-position { + animation-name: spin; + animation-duration: 500ms; + animation-iteration-count: infinite; + animation-timing-function: linear; + animation-delay: 100ms; +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.leaflet-control-locate.active a { + background-color: #cce8ff; +}