1 OSM.HistoryChangesetsLayer = L.FeatureGroup.extend({
4 _getChangesetStyle: function ({ isHighlighted }) {
5 let className = "changeset-in-sidebar-viewport";
8 className += " changeset-highlighted";
12 weight: isHighlighted ? 3 : 2,
13 color: "var(--changeset-border-color)",
14 fillColor: "var(--changeset-fill-color)",
15 fillOpacity: isHighlighted ? 0.3 : 0,
20 _updateChangesetStyle: function (changeset) {
21 const rect = this.getLayer(changeset.id);
24 const style = this._getChangesetStyle(changeset);
26 // setStyle doesn't update css classes: https://github.com/leaflet/leaflet/issues/2662
27 rect._path.classList.value = style.className;
28 rect._path.classList.add("leaflet-interactive");
31 updateChangesets: function (map, changesets) {
32 this._changesets = new Map(changesets.map(changeset => [changeset.id, changeset]));
33 this.updateChangesetShapes(map);
36 updateChangesetShapes: function (map) {
39 for (const changeset of this._changesets.values()) {
40 const bottomLeft = map.project(L.latLng(changeset.bbox.minlat, changeset.bbox.minlon)),
41 topRight = map.project(L.latLng(changeset.bbox.maxlat, changeset.bbox.maxlon)),
42 width = topRight.x - bottomLeft.x,
43 height = bottomLeft.y - topRight.y,
44 minSize = 20; // Min width/height of changeset in pixels
46 if (width < minSize) {
47 bottomLeft.x -= ((minSize - width) / 2);
48 topRight.x += ((minSize - width) / 2);
51 if (height < minSize) {
52 bottomLeft.y += ((minSize - height) / 2);
53 topRight.y -= ((minSize - height) / 2);
56 changeset.bounds = L.latLngBounds(map.unproject(bottomLeft),
57 map.unproject(topRight));
60 const changesetEntries = [...this._changesets];
61 changesetEntries.sort(([, a], [, b]) => {
62 return b.bounds.getSize() - a.bounds.getSize();
64 this._changesets = new Map(changesetEntries);
66 this.updateChangesetLocations(map);
68 for (const changeset of this._changesets.values()) {
69 delete changeset.isHighlighted;
70 const rect = L.rectangle(changeset.bounds, this._getChangesetStyle(changeset));
71 rect.id = changeset.id;
76 updateChangesetLocations: function (map) {
77 const mapCenterLng = map.getCenter().lng;
79 for (const changeset of this._changesets.values()) {
80 const changesetSouthWest = changeset.bounds.getSouthWest();
81 const changesetNorthEast = changeset.bounds.getNorthEast();
82 const changesetCenterLng = (changesetSouthWest.lng + changesetNorthEast.lng) / 2;
83 const shiftInWorldCircumferences = Math.round((changesetCenterLng - mapCenterLng) / 360);
85 if (shiftInWorldCircumferences) {
86 changesetSouthWest.lng -= shiftInWorldCircumferences * 360;
87 changesetNorthEast.lng -= shiftInWorldCircumferences * 360;
89 this.getLayer(changeset.id)?.setBounds(changeset.bounds);
94 toggleChangesetHighlight: function (id, state) {
95 const changeset = this._changesets.get(id);
96 if (!changeset) return;
98 changeset.isHighlighted = state;
99 this._updateChangesetStyle(changeset);
102 getLayerId: function (layer) {