1 OSM.HistoryChangesetBboxLayer = L.FeatureGroup.extend({
2 getLayerId: function (layer) {
6 addChangesetLayer: function (changeset) {
7 const style = this._getChangesetStyle(changeset);
8 const rectangle = L.rectangle(changeset.bounds, style);
9 rectangle.id = changeset.id;
10 return this.addLayer(rectangle);
13 updateChangesetLayerBounds: function (changeset) {
14 this.getLayer(changeset.id)?.setBounds(changeset.bounds);
17 _getSidebarRelativeClassName: function ({ sidebarRelativePosition }) {
18 if (sidebarRelativePosition > 0) {
19 return "changeset-above-sidebar-viewport";
20 } else if (sidebarRelativePosition < 0) {
21 return "changeset-below-sidebar-viewport";
23 return "changeset-in-sidebar-viewport";
28 OSM.HistoryChangesetBboxAreaLayer = OSM.HistoryChangesetBboxLayer.extend({
29 _getChangesetStyle: function (changeset) {
33 className: this._getSidebarRelativeClassName(changeset)
38 OSM.HistoryChangesetBboxOutlineLayer = OSM.HistoryChangesetBboxLayer.extend({
39 _getChangesetStyle: function (changeset) {
42 color: "var(--changeset-outline-color)",
44 className: this._getSidebarRelativeClassName(changeset)
49 OSM.HistoryChangesetBboxBorderLayer = OSM.HistoryChangesetBboxLayer.extend({
50 _getChangesetStyle: function (changeset) {
53 color: "var(--changeset-border-color)",
55 className: this._getSidebarRelativeClassName(changeset)
60 OSM.HistoryChangesetBboxHighlightBackLayer = OSM.HistoryChangesetBboxLayer.extend({
61 _getChangesetStyle: function (changeset) {
65 color: "var(--changeset-outline-color)",
66 fillColor: "var(--changeset-fill-color)",
68 className: this._getSidebarRelativeClassName(changeset) + " changeset-highlighted"
73 OSM.HistoryChangesetBboxHighlightBorderLayer = OSM.HistoryChangesetBboxLayer.extend({
74 _getChangesetStyle: function (changeset) {
78 color: "var(--changeset-border-color)",
80 className: this._getSidebarRelativeClassName(changeset) + " changeset-highlighted"
85 OSM.HistoryChangesetsLayer = L.FeatureGroup.extend({
86 updateChangesets: function (map, changesets) {
87 this._changesets = new Map(changesets.map(changeset => [changeset.id, changeset]));
88 this.updateChangesetShapes(map);
91 updateChangesetShapes: function (map) {
92 for (const changeset of this._changesets.values()) {
93 const topLeft = map.project(L.latLng(changeset.bbox.maxlat, changeset.bbox.minlon)),
94 bottomRight = map.project(L.latLng(changeset.bbox.minlat, changeset.bbox.maxlon)),
95 width = bottomRight.x - topLeft.x,
96 height = bottomRight.y - topLeft.y,
97 minSize = 20; // Min width/height of changeset in pixels
99 if (width < minSize) {
100 topLeft.x -= ((minSize - width) / 2);
101 bottomRight.x += ((minSize - width) / 2);
104 if (height < minSize) {
105 topLeft.y -= ((minSize - height) / 2);
106 bottomRight.y += ((minSize - height) / 2);
109 changeset.bounds = L.latLngBounds(map.unproject(topLeft),
110 map.unproject(bottomRight));
113 this.updateChangesetLocations(map);
114 this.reorderChangesets();
117 updateChangesetLocations: function (map) {
118 const mapCenterLng = map.getCenter().lng;
120 for (const changeset of this._changesets.values()) {
121 const changesetNorthWest = changeset.bounds.getNorthWest();
122 const changesetSouthEast = changeset.bounds.getSouthEast();
123 const changesetCenterLng = (changesetNorthWest.lng + changesetSouthEast.lng) / 2;
124 const shiftInWorldCircumferences = Math.round((changesetCenterLng - mapCenterLng) / 360);
126 if (shiftInWorldCircumferences) {
127 changesetNorthWest.lng -= shiftInWorldCircumferences * 360;
128 changesetSouthEast.lng -= shiftInWorldCircumferences * 360;
129 changeset.bounds = L.latLngBounds(changesetNorthWest, changesetSouthEast);
131 for (const layer of this._bboxLayers) {
132 layer.updateChangesetLayerBounds(changeset);
138 reorderChangesets: function () {
139 const changesetEntries = [...this._changesets];
140 changesetEntries.sort(([, a], [, b]) => b.bounds.getSize() - a.bounds.getSize());
141 this._changesets = new Map(changesetEntries);
143 for (const layer of this._bboxLayers) {
147 for (const changeset of this._changesets.values()) {
148 if (changeset.sidebarRelativePosition !== 0) {
149 this._areaLayer.addChangesetLayer(changeset);
153 for (const changeset of this._changesets.values()) {
154 if (changeset.sidebarRelativePosition === 0) {
155 this._areaLayer.addChangesetLayer(changeset);
159 for (const changeset of this._changesets.values()) {
160 if (changeset.sidebarRelativePosition !== 0) {
161 this._borderLayer.addChangesetLayer(changeset);
165 for (const changeset of this._changesets.values()) {
166 if (changeset.sidebarRelativePosition === 0) {
167 this._outlineLayer.addChangesetLayer(changeset);
171 for (const changeset of this._changesets.values()) {
172 if (changeset.sidebarRelativePosition === 0) {
173 this._borderLayer.addChangesetLayer(changeset);
178 toggleChangesetHighlight: function (id, state) {
179 const changeset = this._changesets.get(id);
180 if (!changeset) return;
183 this._highlightBackLayer.addChangesetLayer(changeset);
184 this._highlightBorderLayer.addChangesetLayer(changeset);
186 this._highlightBackLayer.removeLayer(id);
187 this._highlightBorderLayer.removeLayer(id);
191 setChangesetSidebarRelativePosition: function (id, state) {
192 const changeset = this._changesets.get(id);
193 if (!changeset) return;
194 changeset.sidebarRelativePosition = state;
198 OSM.HistoryChangesetsLayer.addInitHook(function () {
199 this._changesets = new Map;
202 this._areaLayer = new OSM.HistoryChangesetBboxAreaLayer().addTo(this),
203 this._outlineLayer = new OSM.HistoryChangesetBboxOutlineLayer().addTo(this),
204 this._borderLayer = new OSM.HistoryChangesetBboxBorderLayer().addTo(this),
205 this._highlightBackLayer = new OSM.HistoryChangesetBboxHighlightBackLayer().addTo(this),
206 this._highlightBorderLayer = new OSM.HistoryChangesetBboxHighlightBorderLayer().addTo(this)