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