]> git.openstreetmap.org Git - rails.git/commitdiff
Merge remote-tracking branch 'upstream/pull/5914'
authorAnton Khorev <tony29@yandex.ru>
Thu, 10 Apr 2025 11:09:50 +0000 (14:09 +0300)
committerAnton Khorev <tony29@yandex.ru>
Thu, 10 Apr 2025 11:09:50 +0000 (14:09 +0300)
app/assets/javascripts/index/history-changesets-layer.js [new file with mode: 0644]
app/assets/javascripts/index/history.js

diff --git a/app/assets/javascripts/index/history-changesets-layer.js b/app/assets/javascripts/index/history-changesets-layer.js
new file mode 100644 (file)
index 0000000..37a4587
--- /dev/null
@@ -0,0 +1,76 @@
+OSM.HistoryChangesetsLayer = L.FeatureGroup.extend({
+  _changesets: [],
+
+  updateChangesets: function (map, changesets) {
+    this._changesets = changesets;
+    this.updateChangesetShapes(map);
+  },
+
+  updateChangesetShapes: function (map) {
+    this.clearLayers();
+
+    for (const changeset of this._changesets) {
+      const bottomLeft = map.project(L.latLng(changeset.bbox.minlat, changeset.bbox.minlon)),
+            topRight = map.project(L.latLng(changeset.bbox.maxlat, changeset.bbox.maxlon)),
+            width = topRight.x - bottomLeft.x,
+            height = bottomLeft.y - topRight.y,
+            minSize = 20; // Min width/height of changeset in pixels
+
+      if (width < minSize) {
+        bottomLeft.x -= ((minSize - width) / 2);
+        topRight.x += ((minSize - width) / 2);
+      }
+
+      if (height < minSize) {
+        bottomLeft.y += ((minSize - height) / 2);
+        topRight.y -= ((minSize - height) / 2);
+      }
+
+      changeset.bounds = L.latLngBounds(map.unproject(bottomLeft),
+                                        map.unproject(topRight));
+    }
+
+    this._changesets.sort(function (a, b) {
+      return b.bounds.getSize() - a.bounds.getSize();
+    });
+
+    this.updateChangesetLocations(map);
+
+    for (const changeset of this._changesets) {
+      const rect = L.rectangle(changeset.bounds,
+                               { weight: 2, color: "#FF9500", opacity: 1, fillColor: "#FFFFAF", fillOpacity: 0 });
+      rect.id = changeset.id;
+      rect.addTo(this);
+    }
+  },
+
+  updateChangesetLocations: function (map) {
+    const mapCenterLng = map.getCenter().lng;
+
+    for (const changeset of this._changesets) {
+      const changesetSouthWest = changeset.bounds.getSouthWest();
+      const changesetNorthEast = changeset.bounds.getNorthEast();
+      const changesetCenterLng = (changesetSouthWest.lng + changesetNorthEast.lng) / 2;
+      const shiftInWorldCircumferences = Math.round((changesetCenterLng - mapCenterLng) / 360);
+
+      if (shiftInWorldCircumferences) {
+        changesetSouthWest.lng -= shiftInWorldCircumferences * 360;
+        changesetNorthEast.lng -= shiftInWorldCircumferences * 360;
+
+        this.getLayer(changeset.id)?.setBounds(changeset.bounds);
+      }
+    }
+  },
+
+  highlightChangeset: function (id) {
+    this.getLayer(id)?.setStyle({ fillOpacity: 0.3, color: "#FF6600", weight: 3 });
+  },
+
+  unHighlightChangeset: function (id) {
+    this.getLayer(id)?.setStyle({ fillOpacity: 0, color: "#FF9500", weight: 2 });
+  },
+
+  getLayerId: function (layer) {
+    return layer.id;
+  }
+});
index c35aaf2887c13c1390e4b5ddcbeaf07542310628..05877784035fba11cb621125ebca2e13f4a6a88b 100644 (file)
@@ -1,4 +1,5 @@
 //= require jquery-simulate/jquery.simulate
+//= require ./history-changesets-layer
 
 OSM.History = function (map) {
   const page = {};
@@ -12,7 +13,7 @@ OSM.History = function (map) {
       unHighlightChangeset($(this).data("changeset").id);
     });
 
-  const group = L.featureGroup()
+  const changesetsLayer = new OSM.HistoryChangesetsLayer()
     .on("mouseover", function (e) {
       highlightChangeset(e.layer.id);
     })
@@ -23,10 +24,6 @@ OSM.History = function (map) {
       clickChangeset(e.layer.id, e.originalEvent);
     });
 
-  group.getLayerId = function (layer) {
-    return layer.id;
-  };
-
   let changesetIntersectionObserver;
 
   function disableChangesetIntersectionObserver() {
@@ -87,14 +84,12 @@ OSM.History = function (map) {
   }
 
   function highlightChangeset(id) {
-    const layer = group.getLayer(id);
-    if (layer) layer.setStyle({ fillOpacity: 0.3, color: "#FF6600", weight: 3 });
+    changesetsLayer.highlightChangeset(id);
     $("#changeset_" + id).addClass("selected");
   }
 
   function unHighlightChangeset(id) {
-    const layer = group.getLayer(id);
-    if (layer) layer.setStyle({ fillOpacity: 0, color: "#FF9500", weight: 2 });
+    changesetsLayer.unHighlightChangeset(id);
     $("#changeset_" + id).removeClass("selected");
   }
 
@@ -237,60 +232,30 @@ OSM.History = function (map) {
     }
   }
 
-  function reloadChangesetsBecauseOfMapMovement() {
-    OSM.router.replace("/history" + window.location.hash);
-    loadFirstChangesets();
-  }
-
-  let changesets = [];
-
-  function updateBounds() {
-    group.clearLayers();
-
-    for (const changeset of changesets) {
-      const bottomLeft = map.project(L.latLng(changeset.bbox.minlat, changeset.bbox.minlon)),
-            topRight = map.project(L.latLng(changeset.bbox.maxlat, changeset.bbox.maxlon)),
-            width = topRight.x - bottomLeft.x,
-            height = bottomLeft.y - topRight.y,
-            minSize = 20; // Min width/height of changeset in pixels
-
-      if (width < minSize) {
-        bottomLeft.x -= ((minSize - width) / 2);
-        topRight.x += ((minSize - width) / 2);
-      }
-
-      if (height < minSize) {
-        bottomLeft.y += ((minSize - height) / 2);
-        topRight.y -= ((minSize - height) / 2);
-      }
-
-      changeset.bounds = L.latLngBounds(map.unproject(bottomLeft),
-                                        map.unproject(topRight));
+  function moveEndListener() {
+    if (location.pathname === "/history") {
+      OSM.router.replace("/history" + window.location.hash);
+      loadFirstChangesets();
+    } else {
+      changesetsLayer.updateChangesetsPositions(map);
     }
+  }
 
-    changesets.sort(function (a, b) {
-      return b.bounds.getSize() - a.bounds.getSize();
-    });
-
-    for (const changeset of changesets) {
-      const rect = L.rectangle(changeset.bounds,
-                               { weight: 2, color: "#FF9500", opacity: 1, fillColor: "#FFFFAF", fillOpacity: 0 });
-      rect.id = changeset.id;
-      rect.addTo(group);
-    }
+  function zoomEndListener() {
+    changesetsLayer.updateChangesetShapes(map);
   }
 
   function updateMap() {
-    changesets = $("[data-changeset]").map(function (index, element) {
+    const changesets = $("[data-changeset]").map(function (index, element) {
       return $(element).data("changeset");
     }).get().filter(function (changeset) {
       return changeset.bbox;
     });
 
-    updateBounds();
+    changesetsLayer.updateChangesets(map, changesets);
 
     if (location.pathname !== "/history") {
-      const bounds = group.getBounds();
+      const bounds = changesetsLayer.getBounds();
       if (bounds.isValid()) map.fitBounds(bounds);
     }
   }
@@ -300,21 +265,16 @@ OSM.History = function (map) {
   };
 
   page.load = function () {
-    map.addLayer(group);
-
-    if (location.pathname === "/history") {
-      map.on("moveend", reloadChangesetsBecauseOfMapMovement);
-    }
-
-    map.on("zoomend", updateBounds);
-
+    map.addLayer(changesetsLayer);
+    map.on("moveend", moveEndListener);
+    map.on("zoomend", zoomEndListener);
     loadFirstChangesets();
   };
 
   page.unload = function () {
-    map.removeLayer(group);
-    map.off("moveend", reloadChangesetsBecauseOfMapMovement);
-    map.off("zoomend", updateBounds);
+    map.removeLayer(changesetsLayer);
+    map.off("moveend", moveEndListener);
+    map.off("zoomend", zoomEndListener);
     disableChangesetIntersectionObserver();
   };