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