forked from MapComplete/MapComplete
Refactoring: remove the Basemap, switch to Minimap everywhere
This commit is contained in:
parent
92e8f3f89d
commit
b806c210a6
4 changed files with 61 additions and 105 deletions
|
@ -1,6 +1,5 @@
|
||||||
import {FixedUiElement} from "./UI/Base/FixedUiElement";
|
import {FixedUiElement} from "./UI/Base/FixedUiElement";
|
||||||
import Toggle from "./UI/Input/Toggle";
|
import Toggle from "./UI/Input/Toggle";
|
||||||
import {Basemap} from "./UI/BigComponents/Basemap";
|
|
||||||
import State from "./State";
|
import State from "./State";
|
||||||
import LoadFromOverpass from "./Logic/Actors/OverpassFeatureSource";
|
import LoadFromOverpass from "./Logic/Actors/OverpassFeatureSource";
|
||||||
import {UIEventSource} from "./Logic/UIEventSource";
|
import {UIEventSource} from "./Logic/UIEventSource";
|
||||||
|
@ -38,6 +37,7 @@ import RightControls from "./UI/BigComponents/RightControls";
|
||||||
import {LayoutConfigJson} from "./Models/ThemeConfig/Json/LayoutConfigJson";
|
import {LayoutConfigJson} from "./Models/ThemeConfig/Json/LayoutConfigJson";
|
||||||
import LayoutConfig from "./Models/ThemeConfig/LayoutConfig";
|
import LayoutConfig from "./Models/ThemeConfig/LayoutConfig";
|
||||||
import LayerConfig from "./Models/ThemeConfig/LayerConfig";
|
import LayerConfig from "./Models/ThemeConfig/LayerConfig";
|
||||||
|
import Minimap from "./UI/Base/Minimap";
|
||||||
|
|
||||||
export class InitUiElements {
|
export class InitUiElements {
|
||||||
static InitAll(
|
static InitAll(
|
||||||
|
@ -296,7 +296,7 @@ export class InitUiElements {
|
||||||
Hash.hash.data == "welcome"
|
Hash.hash.data == "welcome"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InitBaseMap() {
|
private static InitBaseMap() {
|
||||||
State.state.availableBackgroundLayers =
|
State.state.availableBackgroundLayers =
|
||||||
AvailableBaseLayers.AvailableLayersAt(State.state.locationControl);
|
AvailableBaseLayers.AvailableLayersAt(State.state.locationControl);
|
||||||
|
@ -334,14 +334,15 @@ export class InitUiElements {
|
||||||
State.state.leafletMap
|
State.state.leafletMap
|
||||||
);
|
);
|
||||||
|
|
||||||
const bm = new Basemap(
|
new Minimap({
|
||||||
"leafletDiv",
|
background: State.state.backgroundLayer,
|
||||||
State.state.locationControl,
|
location: State.state.locationControl,
|
||||||
State.state.backgroundLayer,
|
leafletMap: State.state.leafletMap,
|
||||||
State.state.LastClickLocation,
|
attribution: attr,
|
||||||
attr
|
lastClickLocation: State.state.LastClickLocation
|
||||||
);
|
}).SetClass("w-full h-full")
|
||||||
State.state.leafletMap.setData(bm.map);
|
.AttachTo("leafletDiv")
|
||||||
|
|
||||||
const layout = State.state.layoutToUse.data;
|
const layout = State.state.layoutToUse.data;
|
||||||
if (layout.lockLocation) {
|
if (layout.lockLocation) {
|
||||||
if (layout.lockLocation === true) {
|
if (layout.lockLocation === true) {
|
||||||
|
@ -360,8 +361,11 @@ export class InitUiElements {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
console.warn("Locking the bounds to ", layout.lockLocation);
|
console.warn("Locking the bounds to ", layout.lockLocation);
|
||||||
bm.map.setMaxBounds(layout.lockLocation);
|
State.state.leafletMap.addCallbackAndRunD(map => {
|
||||||
bm.map.setMinZoom(layout.startZoom);
|
// @ts-ignore
|
||||||
|
map.setMaxBounds(layout.lockLocation);
|
||||||
|
map.setMinZoom(layout.startZoom);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,9 @@ export default class OverpassFeatureSource implements FeatureSource {
|
||||||
location.addCallback(() => {
|
location.addCallback(() => {
|
||||||
self.update()
|
self.update()
|
||||||
});
|
});
|
||||||
|
leafletMap.addCallbackAndRunD(_ => {
|
||||||
|
self.update();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public ForceRefresh() {
|
public ForceRefresh() {
|
||||||
|
@ -143,7 +146,11 @@ export default class OverpassFeatureSource implements FeatureSource {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bounds = this._leafletMap.data.getBounds();
|
const bounds = this._leafletMap.data?.getBounds();
|
||||||
|
if(bounds === undefined){
|
||||||
|
console.log("Leaflet map not yet initialized; retrying later")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const diff = this._layoutToUse.data.widenFactor;
|
const diff = this._layoutToUse.data.widenFactor;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {Utils} from "../../Utils";
|
||||||
export default class Minimap extends BaseUIElement {
|
export default class Minimap extends BaseUIElement {
|
||||||
|
|
||||||
private static _nextId = 0;
|
private static _nextId = 0;
|
||||||
public readonly leafletMap: UIEventSource<Map> = new UIEventSource<Map>(undefined)
|
public readonly leafletMap: UIEventSource<Map>
|
||||||
private readonly _id: string;
|
private readonly _id: string;
|
||||||
private readonly _background: UIEventSource<BaseLayer>;
|
private readonly _background: UIEventSource<BaseLayer>;
|
||||||
private readonly _location: UIEventSource<Loc>;
|
private readonly _location: UIEventSource<Loc>;
|
||||||
|
@ -18,24 +18,31 @@ export default class Minimap extends BaseUIElement {
|
||||||
private _allowMoving: boolean;
|
private _allowMoving: boolean;
|
||||||
private readonly _leafletoptions: any;
|
private readonly _leafletoptions: any;
|
||||||
private readonly _onFullyLoaded: (leaflet: L.Map) => void
|
private readonly _onFullyLoaded: (leaflet: L.Map) => void
|
||||||
|
private readonly _attribution: BaseUIElement;
|
||||||
|
private readonly _lastClickLocation: UIEventSource<{ lat: number; lon: number }>;
|
||||||
|
|
||||||
constructor(options?: {
|
constructor(options?: {
|
||||||
background?: UIEventSource<BaseLayer>,
|
background?: UIEventSource<BaseLayer>,
|
||||||
location?: UIEventSource<Loc>,
|
location?: UIEventSource<Loc>,
|
||||||
allowMoving?: boolean,
|
allowMoving?: boolean,
|
||||||
leafletOptions?: any,
|
leafletOptions?: any,
|
||||||
|
attribution?: BaseUIElement,
|
||||||
onFullyLoaded?: (leaflet: L.Map) => void
|
onFullyLoaded?: (leaflet: L.Map) => void,
|
||||||
|
leafletMap?: UIEventSource<Map>,
|
||||||
|
lastClickLocation?: UIEventSource<{ lat: number, lon: number }>
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
options = options ?? {}
|
options = options ?? {}
|
||||||
|
this.leafletMap = options.leafletMap ?? new UIEventSource<Map>(undefined)
|
||||||
this._background = options?.background ?? new UIEventSource<BaseLayer>(AvailableBaseLayers.osmCarto)
|
this._background = options?.background ?? new UIEventSource<BaseLayer>(AvailableBaseLayers.osmCarto)
|
||||||
this._location = options?.location ?? new UIEventSource<Loc>({lat: 0, lon: 0, zoom: 1})
|
this._location = options?.location ?? new UIEventSource<Loc>({lat: 0, lon: 0, zoom: 1})
|
||||||
this._id = "minimap" + Minimap._nextId;
|
this._id = "minimap" + Minimap._nextId;
|
||||||
this._allowMoving = options.allowMoving ?? true;
|
this._allowMoving = options.allowMoving ?? true;
|
||||||
this._leafletoptions = options.leafletOptions ?? {}
|
this._leafletoptions = options.leafletOptions ?? {}
|
||||||
this._onFullyLoaded = options.onFullyLoaded
|
this._onFullyLoaded = options.onFullyLoaded
|
||||||
|
this._attribution = options.attribution
|
||||||
|
this._lastClickLocation = options.lastClickLocation;
|
||||||
Minimap._nextId++
|
Minimap._nextId++
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -85,14 +92,14 @@ export default class Minimap extends BaseUIElement {
|
||||||
zoom: location.data?.zoom ?? 2,
|
zoom: location.data?.zoom ?? 2,
|
||||||
layers: [currentLayer],
|
layers: [currentLayer],
|
||||||
zoomControl: false,
|
zoomControl: false,
|
||||||
attributionControl: false,
|
attributionControl: this._attribution !== undefined,
|
||||||
dragging: this._allowMoving,
|
dragging: this._allowMoving,
|
||||||
scrollWheelZoom: this._allowMoving,
|
scrollWheelZoom: this._allowMoving,
|
||||||
doubleClickZoom: this._allowMoving,
|
doubleClickZoom: this._allowMoving,
|
||||||
keyboard: this._allowMoving,
|
keyboard: this._allowMoving,
|
||||||
touchZoom: this._allowMoving,
|
touchZoom: this._allowMoving,
|
||||||
// Disabling this breaks the geojson layer - don't ask me why! zoomAnimation: this._allowMoving,
|
// Disabling this breaks the geojson layer - don't ask me why! zoomAnimation: this._allowMoving,
|
||||||
fadeAnimation: this._allowMoving
|
fadeAnimation: this._allowMoving,
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils.Merge(this._leafletoptions, options)
|
Utils.Merge(this._leafletoptions, options)
|
||||||
|
@ -106,10 +113,19 @@ export default class Minimap extends BaseUIElement {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Users are not allowed to zoom to the 'copies' on the left and the right, stuff goes wrong then
|
||||||
|
// We give a bit of leeway for people on the edges
|
||||||
|
// Also see: https://www.reddit.com/r/openstreetmap/comments/ih4zzc/mapcomplete_a_new_easytouse_editor/g31ubyv/
|
||||||
|
|
||||||
map.setMaxBounds(
|
map.setMaxBounds(
|
||||||
[[-100, -200], [100, 200]]
|
[[-100, -200], [100, 200]]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (this._attribution !== undefined) {
|
||||||
|
map.attributionControl.setPrefix(
|
||||||
|
"<span id='leaflet-attribution'>A</span>");
|
||||||
|
}
|
||||||
|
|
||||||
this._background.addCallbackAndRun(layer => {
|
this._background.addCallbackAndRun(layer => {
|
||||||
const newLayer = layer.layer()
|
const newLayer = layer.layer()
|
||||||
if (currentLayer !== undefined) {
|
if (currentLayer !== undefined) {
|
||||||
|
@ -124,6 +140,9 @@ export default class Minimap extends BaseUIElement {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
map.addLayer(newLayer);
|
map.addLayer(newLayer);
|
||||||
|
map.setMaxZoom(layer.max_zoom ?? map.getMaxZoom())
|
||||||
|
self._attribution?.AttachTo('leaflet-attribution')
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,6 +184,19 @@ export default class Minimap extends BaseUIElement {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
if (this._lastClickLocation) {
|
||||||
|
const lastClickLocation = this._lastClickLocation
|
||||||
|
map.on("click", function (e) {
|
||||||
|
// @ts-ignore
|
||||||
|
lastClickLocation?.setData({lat: e.latlng.lat, lon: e.latlng.lng})
|
||||||
|
});
|
||||||
|
|
||||||
|
map.on("contextmenu", function (e) {
|
||||||
|
// @ts-ignore
|
||||||
|
lastClickLocation?.setData({lat: e.latlng.lat, lon: e.latlng.lng});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.leafletMap.setData(map)
|
this.leafletMap.setData(map)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,87 +0,0 @@
|
||||||
import * as L from "leaflet"
|
|
||||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
|
||||||
import Loc from "../../Models/Loc";
|
|
||||||
import BaseLayer from "../../Models/BaseLayer";
|
|
||||||
import BaseUIElement from "../BaseUIElement";
|
|
||||||
import {FixedUiElement} from "../Base/FixedUiElement";
|
|
||||||
|
|
||||||
export class Basemap {
|
|
||||||
|
|
||||||
|
|
||||||
public readonly map: L.Map;
|
|
||||||
|
|
||||||
constructor(leafletElementId: string,
|
|
||||||
location: UIEventSource<Loc>,
|
|
||||||
currentLayer: UIEventSource<BaseLayer>,
|
|
||||||
lastClickLocation?: UIEventSource<{ lat: number, lon: number }>,
|
|
||||||
extraAttribution?: BaseUIElement) {
|
|
||||||
|
|
||||||
console.log("Currentlayer is" ,currentLayer, currentLayer.data, currentLayer.data?.id)
|
|
||||||
let previousLayer = currentLayer.data.layer();
|
|
||||||
|
|
||||||
this.map = L.map(leafletElementId, {
|
|
||||||
center: [location.data.lat ?? 0, location.data.lon ?? 0],
|
|
||||||
zoom: location.data.zoom ?? 2,
|
|
||||||
layers: [previousLayer],
|
|
||||||
zoomControl: false,
|
|
||||||
attributionControl: extraAttribution !== undefined
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// Users are not allowed to zoom to the 'copies' on the left and the right, stuff goes wrong then
|
|
||||||
// We give a bit of leeway for people on the edges
|
|
||||||
// Also see: https://www.reddit.com/r/openstreetmap/comments/ih4zzc/mapcomplete_a_new_easytouse_editor/g31ubyv/
|
|
||||||
this.map.setMaxBounds(
|
|
||||||
[[-100, -200], [100, 200]]
|
|
||||||
);
|
|
||||||
|
|
||||||
this.map.attributionControl.setPrefix(
|
|
||||||
"<span id='leaflet-attribution'>A</span>");
|
|
||||||
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
currentLayer.addCallbackAndRun(layer => {
|
|
||||||
const newLayer = layer.layer()
|
|
||||||
if (newLayer === previousLayer) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (previousLayer !== undefined) {
|
|
||||||
self.map.removeLayer(previousLayer);
|
|
||||||
}
|
|
||||||
previousLayer = newLayer;
|
|
||||||
self.map.addLayer(newLayer);
|
|
||||||
extraAttribution.AttachTo('leaflet-attribution')
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
this.map.on("moveend", function () {
|
|
||||||
location.data.zoom = self.map.getZoom();
|
|
||||||
location.data.lat = self.map.getCenter().lat;
|
|
||||||
location.data.lon = self.map.getCenter().lng;
|
|
||||||
location.ping();
|
|
||||||
});
|
|
||||||
|
|
||||||
location.map(loc => loc.zoom)
|
|
||||||
.addCallback(zoom => {
|
|
||||||
if (Math.abs(self.map.getZoom() - zoom) > 0.1) {
|
|
||||||
self.map.setZoom(zoom, {});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
this.map.on("click", function (e) {
|
|
||||||
// @ts-ignore
|
|
||||||
lastClickLocation?.setData({lat: e.latlng.lat, lon: e.latlng.lng})
|
|
||||||
});
|
|
||||||
|
|
||||||
this.map.on("contextmenu", function (e) {
|
|
||||||
// @ts-ignore
|
|
||||||
lastClickLocation?.setData({lat: e.latlng.lat, lon: e.latlng.lng});
|
|
||||||
});
|
|
||||||
|
|
||||||
extraAttribution.AttachTo('leaflet-attribution')
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue