Refactoring: remove the Basemap, switch to Minimap everywhere

This commit is contained in:
Pieter Vander Vennet 2021-09-03 13:48:04 +02:00
parent 92e8f3f89d
commit b806c210a6
4 changed files with 61 additions and 105 deletions

View file

@ -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);
})
} }
} }

View file

@ -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;

View file

@ -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)
} }
} }

View file

@ -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')
}
}