1 OSM.HistoryChangesetBboxLayer = L.FeatureGroup.extend({
2 getLayerId: function (layer) {
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";
14 return "changeset-in-sidebar-viewport";
18 _getAreaStyle: function (changeset) {
22 className: this._getSidebarRelativeClassName(changeset)
26 _getBorderStyle: function (changeset) {
29 color: "var(--changeset-border-color)",
31 className: this._getSidebarRelativeClassName(changeset)
35 _getHighlightStyle: function (changeset) {
39 color: "var(--changeset-border-color)",
40 fillColor: "var(--changeset-fill-color)",
42 className: this._getSidebarRelativeClassName(changeset) + " changeset-highlighted"
46 updateChangesets: function (map, changesets) {
47 this._changesets = new Map(changesets.map(changeset => [changeset.id, changeset]));
48 this.updateChangesetShapes(map);
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
59 if (width < minSize) {
60 bottomLeft.x -= ((minSize - width) / 2);
61 topRight.x += ((minSize - width) / 2);
64 if (height < minSize) {
65 bottomLeft.y += ((minSize - height) / 2);
66 topRight.y -= ((minSize - height) / 2);
69 changeset.bounds = L.latLngBounds(map.unproject(bottomLeft),
70 map.unproject(topRight));
73 this.updateChangesetLocations(map);
74 this.reorderChangesets();
77 updateChangesetLocations: function (map) {
78 const mapCenterLng = map.getCenter().lng;
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);
86 if (shiftInWorldCircumferences) {
87 changesetSouthWest.lng -= shiftInWorldCircumferences * 360;
88 changesetNorthEast.lng -= shiftInWorldCircumferences * 360;
90 for (const layer of this._bboxLayers) {
91 layer.getLayer(changeset.id)?.setBounds(changeset.bounds);
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();
105 this._changesets = new Map(changesetEntries);
107 for (const layer of this._bboxLayers) {
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);
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);
124 toggleChangesetHighlight: function (id, state) {
125 const changeset = this._changesets.get(id);
126 if (!changeset) return;
129 const highlightRect = L.rectangle(changeset.bounds, this._getHighlightStyle(changeset));
130 highlightRect.id = id;
131 this._highlightLayer.addLayer(highlightRect);
133 this._highlightLayer.removeLayer(id);
137 setChangesetSidebarRelativePosition: function (id, state) {
138 const changeset = this._changesets.get(id);
139 if (!changeset) return;
140 changeset.sidebarRelativePosition = state;
144 OSM.HistoryChangesetsLayer.addInitHook(function () {
145 this._changesets = new Map;
148 this._areaLayer = new OSM.HistoryChangesetBboxLayer().addTo(this),
149 this._borderLayer = new OSM.HistoryChangesetBboxLayer().addTo(this),
150 this._highlightLayer = new OSM.HistoryChangesetBboxLayer().addTo(this)