nakarte

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

commit dc647e828892011bc9ddf6b6fd608383e3139f98
parent 2b608371c9351e7e880bfa58c008f0875239fdd2
Author: Sergej Orlov <wladimirych@gmail.com>
Date:   Sun, 28 Oct 2018 22:44:48 +0100

reposition markers and vector objects to be visible when scrolling map 360 degress and after worldJump  #140

Diffstat:
Msrc/lib/leaflet.fixes/index.js | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+), 0 deletions(-)

diff --git a/src/lib/leaflet.fixes/index.js b/src/lib/leaflet.fixes/index.js @@ -6,6 +6,9 @@ function fixAll() { fixTouchDetection(); fixMapKeypressEvent(); fixVectorDrawWhileAnimation(); + fixVectorWorldJump(); + fixMarkerWorldJump(); + fixViewResetOnWorldJump(); } // https://github.com/Leaflet/Leaflet/issues/3575 @@ -78,4 +81,83 @@ function fixVectorDrawWhileAnimation() { L.Renderer.__animationFixed = true; } +function fixVectorWorldJump() { + // Shift line points longitude by +360 or -360, to minimize distance between line center and map view center + // Longitude is changed only for display, longitude of pints is not changed + // Breaks dipslay of lines spanning more then one world copy + L.Polyline.prototype._projectLatlngs = function(latlngs, result, projectedBounds) { + var flat = latlngs[0] instanceof L.LatLng, + len = latlngs.length, + i, ring; + const polylineBounds = this.getBounds(); + let shift = 0; + if (polylineBounds.isValid()) { + const worldWidth = this._map.getPixelWorldBounds().getSize().x; + const polylineCenter = polylineBounds.getCenter(); + const mapCenter = this._map.getCenter(); + + if (polylineCenter.lng < mapCenter.lng - 180) { + shift = worldWidth + } else if (polylineCenter.lng > mapCenter.lng + 180) { + shift = -worldWidth; + } + } + + if (flat) { + ring = []; + for (i = 0; i < len; i++) { + let p = this._map.latLngToLayerPoint(latlngs[i]); + p.x += shift; + ring[i] = p; + projectedBounds.extend(p); + } + result.push(ring); + } else { + for (i = 0; i < len; i++) { + this._projectLatlngs(latlngs[i], result, projectedBounds); + } + } + } +} + +function fixMarkerWorldJump() { + // Shift marker longitude by +360 or -360, which is closer to map view center + // Longitude is changed only for positioning html-element, Marker._latlng is not changed + // Breaks display of markers with huge longitudes like 750 (can be displayed only at zoom levels 0 or 1) + L.Marker.prototype.update = function() { + if (this._icon) { + const mapCenter = this._map.getCenter(); + const worldWidth = this._map.getPixelWorldBounds().getSize().x; + var pos = this._map.latLngToLayerPoint(this._latlng).round(); + if (this._latlng.lng < mapCenter.lng - 180) { + pos.x += worldWidth + } else if (this._latlng.lng > mapCenter.lng + 180) { + pos.x -= worldWidth; + } + this._setPos(pos); + } + + return this; + }; +} + +function fixViewResetOnWorldJump() { + L.Map.addInitHook(function() { + this._lastResetLongitude = null; + this.on('viewreset', () => { + this._lastResetLongitude = this.getCenter().lng; + }); + + this.on('move', (e) => { + const lng = this.getCenter().lng; + if (this._lastResetLongitude === null) { + this._lastResetLongitude = lng; + } else if (Math.abs(lng - this._lastResetLongitude) > 90) { + this.fire('viewreset'); + } + }) + }); +} + + export {fixAll}