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:
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}