Feature: add possibility to show a scale on the map
This commit is contained in:
parent
0fdbf445be
commit
5a9ae3f104
6 changed files with 52 additions and 10 deletions
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "mapcomplete",
|
||||
"version": "0.46.5",
|
||||
"version": "0.46.6",
|
||||
"repository": "https://github.com/pietervdvn/MapComplete",
|
||||
"description": "A small website to edit OSM easily",
|
||||
"bugs": "https://github.com/pietervdvn/MapComplete/issues",
|
||||
|
|
|
@ -69,6 +69,8 @@ export default class UserRelatedState {
|
|||
"button" | "button_click_right" | "button_click" | "click" | "click_right"
|
||||
>("button_click_right")
|
||||
|
||||
public readonly showScale : UIEventSource<boolean>
|
||||
|
||||
/**
|
||||
* Preferences as tags exposes many preferences and state properties as record.
|
||||
* This is used to bridge the internal state with the usersettings.json layerconfig file
|
||||
|
@ -123,6 +125,7 @@ export default class UserRelatedState {
|
|||
documentation: "How adding a new feature is done",
|
||||
}
|
||||
)
|
||||
this.showScale = UIEventSource.asBoolean(this.osmConnection.GetPreference("preference-show-scale","false"))
|
||||
|
||||
this.imageLicense = this.osmConnection.GetPreference("pictures-license", "CC0", {
|
||||
documentation: "The license under which new images are uploaded",
|
||||
|
|
|
@ -22,6 +22,7 @@ export interface MapProperties {
|
|||
readonly lastClickLocation: Store<{ lon: number; lat: number }>
|
||||
readonly allowZooming: UIEventSource<true | boolean>
|
||||
readonly useTerrain: Store<boolean>
|
||||
readonly showScale: UIEventSource<boolean>
|
||||
|
||||
/**
|
||||
* Triggered when the user navigated by using the keyboard.
|
||||
|
|
|
@ -889,6 +889,9 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
}
|
||||
})
|
||||
})
|
||||
this.userRelatedState.showScale.addCallbackAndRun(showScale => {
|
||||
this.mapProperties.showScale.set(showScale)
|
||||
})
|
||||
new ThemeViewStateHashActor(this)
|
||||
new MetaTagging(this)
|
||||
new TitleHandler(this.selectedElement, this.featureProperties, this)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import maplibregl, { Map as MLMap, Map as MlMap, SourceSpecification } from "maplibre-gl"
|
||||
import maplibregl, { Map as MLMap, Map as MlMap, ScaleControl, SourceSpecification } from "maplibre-gl"
|
||||
import { RasterLayerPolygon } from "../../Models/RasterLayers"
|
||||
import { Utils } from "../../Utils"
|
||||
import { BBox } from "../../Logic/BBox"
|
||||
|
@ -23,13 +23,13 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
"dragRotate",
|
||||
"dragPan",
|
||||
"keyboard",
|
||||
"touchZoomRotate",
|
||||
"touchZoomRotate"
|
||||
]
|
||||
private static maplibre_zoom_handlers = [
|
||||
"scrollZoom",
|
||||
"boxZoom",
|
||||
"doubleClickZoom",
|
||||
"touchZoomRotate",
|
||||
"touchZoomRotate"
|
||||
]
|
||||
readonly location: UIEventSource<{ lon: number; lat: number }>
|
||||
readonly zoom: UIEventSource<number>
|
||||
|
@ -47,6 +47,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
readonly rotation: UIEventSource<number>
|
||||
readonly pitch: UIEventSource<number>
|
||||
readonly useTerrain: Store<boolean>
|
||||
readonly showScale: UIEventSource<boolean>
|
||||
|
||||
private static pmtilesInited = false
|
||||
/**
|
||||
|
@ -92,6 +93,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
this.useTerrain = state?.useTerrain ?? new ImmutableStore<boolean>(false)
|
||||
this.rasterLayer =
|
||||
state?.rasterLayer ?? new UIEventSource<RasterLayerPolygon | undefined>(undefined)
|
||||
this.showScale = state?.showScale ?? new UIEventSource<boolean>(false)
|
||||
|
||||
const lastClickLocation = new UIEventSource<{
|
||||
lat: number
|
||||
|
@ -104,6 +106,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
new RasterLayerHandler(this._maplibreMap, this.rasterLayer)
|
||||
|
||||
const clickmodes = ["left", "middle", "right"] as const
|
||||
|
||||
function handleClick(e: maplibregl.MapMouseEvent, mode?: "left" | "right" | "middle") {
|
||||
if (e.originalEvent["consumed"]) {
|
||||
// Workaround, 'ShowPointLayer' sets this flag
|
||||
|
@ -129,6 +132,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
self.setMaxzoom(self.maxzoom.data)
|
||||
self.setBounds(self.bounds.data)
|
||||
self.setTerrain(self.useTerrain.data)
|
||||
self.setScale(self.showScale.data)
|
||||
this.updateStores(true)
|
||||
})
|
||||
self.MoveMapToCurrentLoc(self.location.data)
|
||||
|
@ -142,6 +146,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
self.setBounds(self.bounds.data)
|
||||
self.SetRotation(self.rotation.data)
|
||||
self.setTerrain(self.useTerrain.data)
|
||||
self.setScale(self.showScale.data)
|
||||
this.updateStores(true)
|
||||
map.on("moveend", () => this.updateStores())
|
||||
map.on("click", (e) => {
|
||||
|
@ -213,6 +218,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
this.allowZooming.addCallbackAndRun((allowZooming) => self.setAllowZooming(allowZooming))
|
||||
this.bounds.addCallbackAndRunD((bounds) => self.setBounds(bounds))
|
||||
this.useTerrain?.addCallbackAndRun((useTerrain) => self.setTerrain(useTerrain))
|
||||
this.showScale?.addCallbackAndRun(showScale => self.setScale(showScale))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -227,9 +233,9 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
return {
|
||||
map: mlmap,
|
||||
ui: new SvelteUIElement(MaplibreMap, {
|
||||
map: mlmap,
|
||||
map: mlmap
|
||||
}),
|
||||
mapproperties: new MapLibreAdaptor(mlmap),
|
||||
mapproperties: new MapLibreAdaptor(mlmap)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,7 +303,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
) {
|
||||
const event = {
|
||||
date: new Date(),
|
||||
key: key,
|
||||
key: key
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._onKeyNavigation.length; i++) {
|
||||
|
@ -486,7 +492,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
const bounds = map.getBounds()
|
||||
const bbox = new BBox([
|
||||
[bounds.getEast(), bounds.getNorth()],
|
||||
[bounds.getWest(), bounds.getSouth()],
|
||||
[bounds.getWest(), bounds.getSouth()]
|
||||
])
|
||||
if (this.bounds.data === undefined || !isSetup) {
|
||||
this.bounds.setData(bbox)
|
||||
|
@ -664,18 +670,42 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
type: "raster-dem",
|
||||
url:
|
||||
"https://api.maptiler.com/tiles/terrain-rgb/tiles.json?key=" +
|
||||
Constants.maptilerApiKey,
|
||||
Constants.maptilerApiKey
|
||||
})
|
||||
try {
|
||||
while (!map?.isStyleLoaded()) {
|
||||
await Utils.waitFor(250)
|
||||
}
|
||||
map.setTerrain({
|
||||
source: id,
|
||||
source: id
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private scaleControl: maplibregl.ScaleControl = undefined
|
||||
|
||||
private setScale(showScale: boolean) {
|
||||
const map = this._maplibreMap.data
|
||||
if (!map) {
|
||||
return
|
||||
}
|
||||
if (!showScale && this.scaleControl) {
|
||||
map.removeControl(this.scaleControl)
|
||||
return
|
||||
}
|
||||
console.log("Adding scale")
|
||||
if (this.scaleControl === undefined) {
|
||||
|
||||
this.scaleControl = new ScaleControl({
|
||||
maxWidth: 80,
|
||||
unit: "metric"
|
||||
})
|
||||
}
|
||||
if (!map.hasControl(this.scaleControl)) {
|
||||
map.addControl(this.scaleControl, "bottom-right")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -390,6 +390,11 @@
|
|||
{/if}
|
||||
</div>
|
||||
</If>
|
||||
<If condition={state.mapProperties.showScale}>
|
||||
<div class="h-6">
|
||||
<!-- Empty. We just provide some space for the maplibre scalecontrol -->
|
||||
</div>
|
||||
</If>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue