1 OSM.HistoryChangesetBboxLayer = L.FeatureGroup.extend({
2 getLayerId: function (layer) {
6 updateChangesetLayerBounds: function (changeset) {
7 this.getLayer(changeset.id)?.setBounds(changeset.bounds);
10 _getSidebarRelativeClassName: function ({ sidebarRelativePosition }) {
11 if (sidebarRelativePosition > 0) {
12 return "changeset-above-sidebar-viewport";
13 } else if (sidebarRelativePosition < 0) {
14 return "changeset-below-sidebar-viewport";
16 return "changeset-in-sidebar-viewport";
21 OSM.HistoryChangesetBboxAreaLayer = OSM.HistoryChangesetBboxLayer.extend({
22 _getChangesetStyle: function (changeset) {
26 className: this._getSidebarRelativeClassName(changeset)
31 OSM.HistoryChangesetBboxBorderLayer = OSM.HistoryChangesetBboxLayer.extend({
32 _getChangesetStyle: function (changeset) {
35 color: "var(--changeset-border-color)",
37 className: this._getSidebarRelativeClassName(changeset)
42 OSM.HistoryChangesetBboxHighlightLayer = OSM.HistoryChangesetBboxLayer.extend({
43 _getChangesetStyle: function (changeset) {
47 color: "var(--changeset-border-color)",
48 fillColor: "var(--changeset-fill-color)",
50 className: this._getSidebarRelativeClassName(changeset) + " changeset-highlighted"
55 OSM.HistoryChangesetsLayer = L.FeatureGroup.extend({
56 updateChangesets: function (map, changesets) {
57 this._changesets = new Map(changesets.map(changeset => [changeset.id, changeset]));
58 this.updateChangesetShapes(map);
61 updateChangesetShapes: function (map) {
62 for (const changeset of this._changesets.values()) {
63 const bottomLeft = map.project(L.latLng(changeset.bbox.minlat, changeset.bbox.minlon)),
64 topRight = map.project(L.latLng(changeset.bbox.maxlat, changeset.bbox.maxlon)),
65 width = topRight.x - bottomLeft.x,
66 height = bottomLeft.y - topRight.y,
67 minSize = 20; // Min width/height of changeset in pixels
69 if (width < minSize) {
70 bottomLeft.x -= ((minSize - width) / 2);
71 topRight.x += ((minSize - width) / 2);
74 if (height < minSize) {
75 bottomLeft.y += ((minSize - height) / 2);
76 topRight.y -= ((minSize - height) / 2);
79 changeset.bounds = L.latLngBounds(map.unproject(bottomLeft),
80 map.unproject(topRight));
83 this.updateChangesetLocations(map);
84 this.reorderChangesets();
87 updateChangesetLocations: function (map) {
88 const mapCenterLng = map.getCenter().lng;
90 for (const changeset of this._changesets.values()) {
91 const changesetSouthWest = changeset.bounds.getSouthWest();
92 const changesetNorthEast = changeset.bounds.getNorthEast();
93 const changesetCenterLng = (changesetSouthWest.lng + changesetNorthEast.lng) / 2;
94 const shiftInWorldCircumferences = Math.round((changesetCenterLng - mapCenterLng) / 360);
96 if (shiftInWorldCircumferences) {
97 changesetSouthWest.lng -= shiftInWorldCircumferences * 360;
98 changesetNorthEast.lng -= shiftInWorldCircumferences * 360;
100 for (const layer of this._bboxLayers) {
101 layer.updateChangesetLayerBounds(changeset);
107 reorderChangesets: function () {
108 const changesetEntries = [...this._changesets];
109 changesetEntries.sort(([, a], [, b]) => {
110 const aInViewport = !a.sidebarRelativePosition;
111 const bInViewport = !b.sidebarRelativePosition;
112 if (aInViewport !== bInViewport) return aInViewport - bInViewport;
113 return b.bounds.getSize() - a.bounds.getSize();
115 this._changesets = new Map(changesetEntries);
117 for (const layer of this._bboxLayers) {
121 for (const changeset of this._changesets.values()) {
122 const rect = L.rectangle(changeset.bounds, this._areaLayer._getChangesetStyle(changeset));
123 rect.id = changeset.id;
124 rect.addTo(this._areaLayer);
127 for (const changeset of this._changesets.values()) {
128 const rect = L.rectangle(changeset.bounds, this._borderLayer._getChangesetStyle(changeset));
129 rect.id = changeset.id;
130 rect.addTo(this._borderLayer);
134 toggleChangesetHighlight: function (id, state) {
135 const changeset = this._changesets.get(id);
136 if (!changeset) return;
139 const highlightRect = L.rectangle(changeset.bounds, this._highlightLayer._getChangesetStyle(changeset));
140 highlightRect.id = id;
141 this._highlightLayer.addLayer(highlightRect);
143 this._highlightLayer.removeLayer(id);
147 setChangesetSidebarRelativePosition: function (id, state) {
148 const changeset = this._changesets.get(id);
149 if (!changeset) return;
150 changeset.sidebarRelativePosition = state;
154 OSM.HistoryChangesetsLayer.addInitHook(function () {
155 this._changesets = new Map;
158 this._areaLayer = new OSM.HistoryChangesetBboxAreaLayer().addTo(this),
159 this._borderLayer = new OSM.HistoryChangesetBboxBorderLayer().addTo(this),
160 this._highlightLayer = new OSM.HistoryChangesetBboxHighlightLayer().addTo(this)