]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/index/history-changesets-layer.js
Move changesets layer properties init to init hook
[rails.git] / app / assets / javascripts / index / history-changesets-layer.js
1 OSM.HistoryChangesetsLayer = L.FeatureGroup.extend({
2   _getChangesetStyle: function ({ isHighlighted, sidebarRelativePosition }) {
3     let className;
4
5     if (sidebarRelativePosition > 0) {
6       className = "changeset-above-sidebar-viewport";
7     } else if (sidebarRelativePosition < 0) {
8       className = "changeset-below-sidebar-viewport";
9     } else {
10       className = "changeset-in-sidebar-viewport";
11     }
12     if (isHighlighted) {
13       className += " changeset-highlighted";
14     }
15
16     return {
17       weight: isHighlighted ? 4 : 2,
18       color: "var(--changeset-border-color)",
19       fillColor: "var(--changeset-fill-color)",
20       fillOpacity: isHighlighted ? 0.3 : 0,
21       className
22     };
23   },
24
25   _updateChangesetStyle: function (changeset) {
26     const rect = this.getLayer(changeset.id);
27     if (!rect) return;
28
29     const style = this._getChangesetStyle(changeset);
30     rect.setStyle(style);
31     // setStyle doesn't update css classes: https://github.com/leaflet/leaflet/issues/2662
32     rect._path.classList.value = style.className;
33     rect._path.classList.add("leaflet-interactive");
34   },
35
36   updateChangesets: function (map, changesets) {
37     this._changesets = new Map(changesets.map(changeset => [changeset.id, changeset]));
38     this.updateChangesetShapes(map);
39   },
40
41   updateChangesetShapes: function (map) {
42     for (const changeset of this._changesets.values()) {
43       const bottomLeft = map.project(L.latLng(changeset.bbox.minlat, changeset.bbox.minlon)),
44             topRight = map.project(L.latLng(changeset.bbox.maxlat, changeset.bbox.maxlon)),
45             width = topRight.x - bottomLeft.x,
46             height = bottomLeft.y - topRight.y,
47             minSize = 20; // Min width/height of changeset in pixels
48
49       if (width < minSize) {
50         bottomLeft.x -= ((minSize - width) / 2);
51         topRight.x += ((minSize - width) / 2);
52       }
53
54       if (height < minSize) {
55         bottomLeft.y += ((minSize - height) / 2);
56         topRight.y -= ((minSize - height) / 2);
57       }
58
59       changeset.bounds = L.latLngBounds(map.unproject(bottomLeft),
60                                         map.unproject(topRight));
61     }
62
63     this.updateChangesetLocations(map);
64     this.reorderChangesets();
65   },
66
67   updateChangesetLocations: function (map) {
68     const mapCenterLng = map.getCenter().lng;
69
70     for (const changeset of this._changesets.values()) {
71       const changesetSouthWest = changeset.bounds.getSouthWest();
72       const changesetNorthEast = changeset.bounds.getNorthEast();
73       const changesetCenterLng = (changesetSouthWest.lng + changesetNorthEast.lng) / 2;
74       const shiftInWorldCircumferences = Math.round((changesetCenterLng - mapCenterLng) / 360);
75
76       if (shiftInWorldCircumferences) {
77         changesetSouthWest.lng -= shiftInWorldCircumferences * 360;
78         changesetNorthEast.lng -= shiftInWorldCircumferences * 360;
79
80         this.getLayer(changeset.id)?.setBounds(changeset.bounds);
81       }
82     }
83   },
84
85   reorderChangesets: function () {
86     const changesetEntries = [...this._changesets];
87     changesetEntries.sort(([, a], [, b]) => {
88       const aInViewport = !a.sidebarRelativePosition;
89       const bInViewport = !b.sidebarRelativePosition;
90       if (aInViewport !== bInViewport) return aInViewport - bInViewport;
91       return b.bounds.getSize() - a.bounds.getSize();
92     });
93     this._changesets = new Map(changesetEntries);
94
95     this.clearLayers();
96
97     for (const changeset of this._changesets.values()) {
98       delete changeset.isHighlighted;
99       const rect = L.rectangle(changeset.bounds, this._getChangesetStyle(changeset));
100       rect.id = changeset.id;
101       rect.addTo(this);
102     }
103   },
104
105   toggleChangesetHighlight: function (id, state) {
106     const changeset = this._changesets.get(id);
107     if (!changeset) return;
108
109     changeset.isHighlighted = state;
110     this._updateChangesetStyle(changeset);
111   },
112
113   setChangesetSidebarRelativePosition: function (id, state) {
114     const changeset = this._changesets.get(id);
115     if (!changeset) return;
116
117     if (changeset.sidebarRelativePosition !== state) {
118       changeset.sidebarRelativePosition = state;
119       this._updateChangesetStyle(changeset);
120     }
121   },
122
123   getLayerId: function (layer) {
124     return layer.id;
125   }
126 });
127
128 OSM.HistoryChangesetsLayer.addInitHook(function () {
129   this._changesets = new Map;
130 });