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