diff --git a/InitUiElements.ts b/InitUiElements.ts index e74b7fa842..206d32d2d0 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -1,6 +1,5 @@ import {FixedUiElement} from "./UI/Base/FixedUiElement"; import Toggle from "./UI/Input/Toggle"; -import {Basemap} from "./UI/BigComponents/Basemap"; import State from "./State"; import LoadFromOverpass from "./Logic/Actors/OverpassFeatureSource"; import {UIEventSource} from "./Logic/UIEventSource"; @@ -38,6 +37,7 @@ import RightControls from "./UI/BigComponents/RightControls"; import {LayoutConfigJson} from "./Models/ThemeConfig/Json/LayoutConfigJson"; import LayoutConfig from "./Models/ThemeConfig/LayoutConfig"; import LayerConfig from "./Models/ThemeConfig/LayerConfig"; +import Minimap from "./UI/Base/Minimap"; export class InitUiElements { static InitAll( @@ -296,7 +296,7 @@ export class InitUiElements { Hash.hash.data == "welcome" ); } - + private static InitBaseMap() { State.state.availableBackgroundLayers = AvailableBaseLayers.AvailableLayersAt(State.state.locationControl); @@ -334,14 +334,15 @@ export class InitUiElements { State.state.leafletMap ); - const bm = new Basemap( - "leafletDiv", - State.state.locationControl, - State.state.backgroundLayer, - State.state.LastClickLocation, - attr - ); - State.state.leafletMap.setData(bm.map); + new Minimap({ + background: State.state.backgroundLayer, + location: State.state.locationControl, + leafletMap: State.state.leafletMap, + attribution: attr, + lastClickLocation: State.state.LastClickLocation + }).SetClass("w-full h-full") + .AttachTo("leafletDiv") + const layout = State.state.layoutToUse.data; if (layout.lockLocation) { if (layout.lockLocation === true) { @@ -360,8 +361,11 @@ export class InitUiElements { ]; } console.warn("Locking the bounds to ", layout.lockLocation); - bm.map.setMaxBounds(layout.lockLocation); - bm.map.setMinZoom(layout.startZoom); + State.state.leafletMap.addCallbackAndRunD(map => { + // @ts-ignore + map.setMaxBounds(layout.lockLocation); + map.setMinZoom(layout.startZoom); + }) } } diff --git a/Logic/Actors/OverpassFeatureSource.ts b/Logic/Actors/OverpassFeatureSource.ts index 8f8957dc4a..710086da96 100644 --- a/Logic/Actors/OverpassFeatureSource.ts +++ b/Logic/Actors/OverpassFeatureSource.ts @@ -73,6 +73,9 @@ export default class OverpassFeatureSource implements FeatureSource { location.addCallback(() => { self.update() }); + leafletMap.addCallbackAndRunD(_ => { + self.update(); + }) } public ForceRefresh() { @@ -143,7 +146,11 @@ export default class OverpassFeatureSource implements FeatureSource { 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; diff --git a/UI/Base/Minimap.ts b/UI/Base/Minimap.ts index c030812ce2..f259fca938 100644 --- a/UI/Base/Minimap.ts +++ b/UI/Base/Minimap.ts @@ -10,7 +10,7 @@ import {Utils} from "../../Utils"; export default class Minimap extends BaseUIElement { private static _nextId = 0; - public readonly leafletMap: UIEventSource = new UIEventSource(undefined) + public readonly leafletMap: UIEventSource private readonly _id: string; private readonly _background: UIEventSource; private readonly _location: UIEventSource; @@ -18,24 +18,31 @@ export default class Minimap extends BaseUIElement { private _allowMoving: boolean; private readonly _leafletoptions: any; private readonly _onFullyLoaded: (leaflet: L.Map) => void + private readonly _attribution: BaseUIElement; + private readonly _lastClickLocation: UIEventSource<{ lat: number; lon: number }>; constructor(options?: { background?: UIEventSource, location?: UIEventSource, allowMoving?: boolean, leafletOptions?: any, - - onFullyLoaded?: (leaflet: L.Map) => void + attribution?: BaseUIElement, + onFullyLoaded?: (leaflet: L.Map) => void, + leafletMap?: UIEventSource, + lastClickLocation?: UIEventSource<{ lat: number, lon: number }> } ) { super() options = options ?? {} + this.leafletMap = options.leafletMap ?? new UIEventSource(undefined) this._background = options?.background ?? new UIEventSource(AvailableBaseLayers.osmCarto) this._location = options?.location ?? new UIEventSource({lat: 0, lon: 0, zoom: 1}) this._id = "minimap" + Minimap._nextId; this._allowMoving = options.allowMoving ?? true; this._leafletoptions = options.leafletOptions ?? {} this._onFullyLoaded = options.onFullyLoaded + this._attribution = options.attribution + this._lastClickLocation = options.lastClickLocation; Minimap._nextId++ } @@ -85,14 +92,14 @@ export default class Minimap extends BaseUIElement { zoom: location.data?.zoom ?? 2, layers: [currentLayer], zoomControl: false, - attributionControl: false, + attributionControl: this._attribution !== undefined, dragging: this._allowMoving, scrollWheelZoom: this._allowMoving, doubleClickZoom: this._allowMoving, keyboard: this._allowMoving, touchZoom: 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) @@ -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( [[-100, -200], [100, 200]] ); + if (this._attribution !== undefined) { + map.attributionControl.setPrefix( + "A"); + } + this._background.addCallbackAndRun(layer => { const newLayer = layer.layer() if (currentLayer !== undefined) { @@ -124,6 +140,9 @@ export default class Minimap extends BaseUIElement { }) } 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) } } \ No newline at end of file diff --git a/UI/BigComponents/Basemap.ts b/UI/BigComponents/Basemap.ts deleted file mode 100644 index 9d627b6317..0000000000 --- a/UI/BigComponents/Basemap.ts +++ /dev/null @@ -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, - currentLayer: UIEventSource, - 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( - "A"); - - 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') - - } - - -}