]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/index/history-changesets-layer.js
751105e7227a3f7fbb7b23ac5440efc2359b5eec
[rails.git] / app / assets / javascripts / index / history-changesets-layer.js
1 OSM.HistoryChangesetsLayer = L.FeatureGroup.extend({
2   _changesets: new Map,
3
4   _getChangesetStyle: function ({ isHighlighted }) {
5     return {
6       weight: isHighlighted ? 3 : 2,
7       color: isHighlighted ? "#FF6600" : "#FF9500",
8       fillColor: "#FFFFAF",
9       fillOpacity: isHighlighted ? 0.3 : 0
10     };
11   },
12
13   _updateChangesetStyle: function (changeset) {
14     this.getLayer(changeset.id)?.setStyle(this._getChangesetStyle(changeset));
15   },
16
17   updateChangesets: function (map, changesets) {
18     this._changesets = new Map(changesets.map(changeset => [changeset.id, changeset]));
19     this.updateChangesetShapes(map);
20   },
21
22   updateChangesetShapes: function (map) {
23     this.clearLayers();
24
25     for (const changeset of this._changesets.values()) {
26       const bottomLeft = map.project(L.latLng(changeset.bbox.minlat, changeset.bbox.minlon)),
27             topRight = map.project(L.latLng(changeset.bbox.maxlat, changeset.bbox.maxlon)),
28             width = topRight.x - bottomLeft.x,
29             height = bottomLeft.y - topRight.y,
30             minSize = 20; // Min width/height of changeset in pixels
31
32       if (width < minSize) {
33         bottomLeft.x -= ((minSize - width) / 2);
34         topRight.x += ((minSize - width) / 2);
35       }
36
37       if (height < minSize) {
38         bottomLeft.y += ((minSize - height) / 2);
39         topRight.y -= ((minSize - height) / 2);
40       }
41
42       changeset.bounds = L.latLngBounds(map.unproject(bottomLeft),
43                                         map.unproject(topRight));
44     }
45
46     const changesetEntries = [...this._changesets];
47     changesetEntries.sort(([, a], [, b]) => {
48       return b.bounds.getSize() - a.bounds.getSize();
49     });
50     this._changesets = new Map(changesetEntries);
51
52     this.updateChangesetLocations(map);
53
54     for (const changeset of this._changesets.values()) {
55       delete changeset.isHighlighted;
56       const rect = L.rectangle(changeset.bounds, this._getChangesetStyle(changeset));
57       rect.id = changeset.id;
58       rect.addTo(this);
59     }
60   },
61
62   updateChangesetLocations: function (map) {
63     const mapCenterLng = map.getCenter().lng;
64
65     for (const changeset of this._changesets.values()) {
66       const changesetSouthWest = changeset.bounds.getSouthWest();
67       const changesetNorthEast = changeset.bounds.getNorthEast();
68       const changesetCenterLng = (changesetSouthWest.lng + changesetNorthEast.lng) / 2;
69       const shiftInWorldCircumferences = Math.round((changesetCenterLng - mapCenterLng) / 360);
70
71       if (shiftInWorldCircumferences) {
72         changesetSouthWest.lng -= shiftInWorldCircumferences * 360;
73         changesetNorthEast.lng -= shiftInWorldCircumferences * 360;
74
75         this.getLayer(changeset.id)?.setBounds(changeset.bounds);
76       }
77     }
78   },
79
80   toggleChangesetHighlight: function (id, state) {
81     const changeset = this._changesets.get(id);
82     if (!changeset) return;
83
84     changeset.isHighlighted = state;
85     this._updateChangesetStyle(changeset);
86   },
87
88   getLayerId: function (layer) {
89     return layer.id;
90   }
91 });