forked from MapComplete/MapComplete
Chore: reformat all files with prettier
This commit is contained in:
parent
5757ae5dea
commit
d008dcb54d
214 changed files with 8926 additions and 8196 deletions
|
@ -1,14 +1,14 @@
|
|||
import {Store, UIEventSource} from "../../Logic/UIEventSource"
|
||||
import type {Map as MLMap} from "maplibre-gl"
|
||||
import {Map as MlMap, SourceSpecification} from "maplibre-gl"
|
||||
import {RasterLayerPolygon} from "../../Models/RasterLayers"
|
||||
import {Utils} from "../../Utils"
|
||||
import {BBox} from "../../Logic/BBox"
|
||||
import {ExportableMap, MapProperties} from "../../Models/MapProperties"
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import type { Map as MLMap } from "maplibre-gl"
|
||||
import { Map as MlMap, SourceSpecification } from "maplibre-gl"
|
||||
import { RasterLayerPolygon } from "../../Models/RasterLayers"
|
||||
import { Utils } from "../../Utils"
|
||||
import { BBox } from "../../Logic/BBox"
|
||||
import { ExportableMap, MapProperties } from "../../Models/MapProperties"
|
||||
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||
import MaplibreMap from "./MaplibreMap.svelte"
|
||||
import {RasterLayerProperties} from "../../Models/RasterLayerProperties"
|
||||
import * as htmltoimage from 'html-to-image';
|
||||
import { RasterLayerProperties } from "../../Models/RasterLayerProperties"
|
||||
import * as htmltoimage from "html-to-image"
|
||||
|
||||
/**
|
||||
* The 'MapLibreAdaptor' bridges 'MapLibre' with the various properties of the `MapProperties`
|
||||
|
@ -53,7 +53,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
if (this.location.data) {
|
||||
// The MapLibre adaptor updates the element in the location and then pings them
|
||||
// Often, code setting this up doesn't expect the object they pass in to be changed, so we create a copy
|
||||
this.location.setData({...this.location.data})
|
||||
this.location.setData({ ...this.location.data })
|
||||
}
|
||||
this.zoom = state?.zoom ?? new UIEventSource(1)
|
||||
this.minzoom = state?.minzoom ?? new UIEventSource(0)
|
||||
|
@ -86,7 +86,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
console.log(e)
|
||||
const lon = e.lngLat.lng
|
||||
const lat = e.lngLat.lat
|
||||
lastClickLocation.setData({lon, lat})
|
||||
lastClickLocation.setData({ lon, lat })
|
||||
}
|
||||
|
||||
maplibreMap.addCallbackAndRunD((map) => {
|
||||
|
@ -170,16 +170,25 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
}
|
||||
}
|
||||
|
||||
public static setDpi(drawOn: HTMLCanvasElement, ctx: CanvasRenderingContext2D, dpiFactor: number) {
|
||||
public static setDpi(
|
||||
drawOn: HTMLCanvasElement,
|
||||
ctx: CanvasRenderingContext2D,
|
||||
dpiFactor: number
|
||||
) {
|
||||
drawOn.style.width = drawOn.style.width || drawOn.width + "px"
|
||||
drawOn.style.height = drawOn.style.height || drawOn.height + "px"
|
||||
|
||||
|
||||
// Resize canvas and scale future draws.
|
||||
drawOn.width = Math.ceil(drawOn.width * dpiFactor)
|
||||
drawOn.height = Math.ceil(drawOn.height * dpiFactor)
|
||||
ctx.scale(dpiFactor, dpiFactor)
|
||||
console.log("Resizing canvas with setDPI:", drawOn.width, drawOn.height, drawOn.style.width, drawOn.style.height)
|
||||
console.log(
|
||||
"Resizing canvas with setDPI:",
|
||||
drawOn.width,
|
||||
drawOn.height,
|
||||
drawOn.style.width,
|
||||
drawOn.style.height
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,11 +239,21 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
console.log("Getting markers")
|
||||
// MapLibreAdaptor.setDpi(drawOn, ctx, 1)
|
||||
const markers = await this.drawMarkers(dpiFactor)
|
||||
console.log("Drawing markers (" + markers.width + "*" + markers.height + ") onto drawOn (" + drawOn.width + "*" + drawOn.height + ")")
|
||||
console.log(
|
||||
"Drawing markers (" +
|
||||
markers.width +
|
||||
"*" +
|
||||
markers.height +
|
||||
") onto drawOn (" +
|
||||
drawOn.width +
|
||||
"*" +
|
||||
drawOn.height +
|
||||
")"
|
||||
)
|
||||
ctx.drawImage(markers, 0, 0, drawOn.width, drawOn.height)
|
||||
ctx.scale(dpiFactor, dpiFactor)
|
||||
this._maplibreMap.data?.resize()
|
||||
return await new Promise<Blob>(resolve => drawOn.toBlob(blob => resolve(blob)))
|
||||
return await new Promise<Blob>((resolve) => drawOn.toBlob((blob) => resolve(blob)))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -270,7 +289,14 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
}
|
||||
const width = map.getCanvas().clientWidth
|
||||
const height = map.getCanvas().clientHeight
|
||||
console.log("Canvas size markers:", map.getCanvas().width, map.getCanvas().height, "canvasClientRect:", width, height)
|
||||
console.log(
|
||||
"Canvas size markers:",
|
||||
map.getCanvas().width,
|
||||
map.getCanvas().height,
|
||||
"canvasClientRect:",
|
||||
width,
|
||||
height
|
||||
)
|
||||
map.getCanvas().style.display = "none"
|
||||
const img = await htmltoimage.toCanvas(map.getCanvasContainer(), {
|
||||
pixelRatio: dpiFactor,
|
||||
|
@ -288,12 +314,12 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
if (!map) {
|
||||
return
|
||||
}
|
||||
const {lng, lat} = map.getCenter()
|
||||
const { lng, lat } = map.getCenter()
|
||||
if (lng === 0 && lat === 0) {
|
||||
return
|
||||
}
|
||||
if (this.location.data === undefined) {
|
||||
this.location.setData({lon: lng, lat})
|
||||
this.location.setData({ lon: lng, lat })
|
||||
} else if (!isSetup) {
|
||||
const dt = this.location.data
|
||||
dt.lon = map.getCenter().lng
|
||||
|
@ -329,7 +355,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
|
||||
const center = map.getCenter()
|
||||
if (center.lng !== loc.lon || center.lat !== loc.lat) {
|
||||
map.setCenter({lng: loc.lon, lat: loc.lat})
|
||||
map.setCenter({ lng: loc.lon, lat: loc.lat })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,7 +405,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
return
|
||||
}
|
||||
|
||||
if(background.type === "vector"){
|
||||
if (background.type === "vector") {
|
||||
console.log("Background layer is vector")
|
||||
map.setStyle(background.url)
|
||||
return
|
||||
|
@ -389,12 +415,12 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
|
||||
map.resize()
|
||||
|
||||
let addLayerBeforeId = "aeroway_fill"// this is the first non-landuse item in the stylesheet, we add the raster layer before the roads but above the landuse
|
||||
let addLayerBeforeId = "aeroway_fill" // this is the first non-landuse item in the stylesheet, we add the raster layer before the roads but above the landuse
|
||||
if (background.category === "osmbasedmap" || background.category === "map") {
|
||||
// The background layer is already an OSM-based map or another map, so we don't want anything from the baselayer
|
||||
let layers = map.getStyle().layers
|
||||
// THe last index of the maptiler layers
|
||||
let lastIndex = layers.findIndex(layer => layer.id === "housenumber")
|
||||
let lastIndex = layers.findIndex((layer) => layer.id === "housenumber")
|
||||
addLayerBeforeId = layers[lastIndex + 1]?.id ?? "housenumber"
|
||||
}
|
||||
|
||||
|
@ -404,7 +430,8 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
type: "raster",
|
||||
source: background.id,
|
||||
paint: {},
|
||||
}, addLayerBeforeId
|
||||
},
|
||||
addLayerBeforeId
|
||||
)
|
||||
await this.awaitStyleIsLoaded()
|
||||
this.removeCurrentLayer(map)
|
||||
|
|
|
@ -4,42 +4,46 @@
|
|||
*
|
||||
* As it replaces the old 'MinimapObj' onto MapLibre and the existing codebase, this is sometimes a bit awkward
|
||||
*/
|
||||
import { onMount } from "svelte";
|
||||
import { Map } from "@onsvisual/svelte-maps";
|
||||
import type { Map as MaplibreMap } from "maplibre-gl";
|
||||
import type { Writable } from "svelte/store";
|
||||
import {AvailableRasterLayers} from "../../Models/RasterLayers";
|
||||
|
||||
import { onMount } from "svelte"
|
||||
import { Map } from "@onsvisual/svelte-maps"
|
||||
import type { Map as MaplibreMap } from "maplibre-gl"
|
||||
import type { Writable } from "svelte/store"
|
||||
import { AvailableRasterLayers } from "../../Models/RasterLayers"
|
||||
|
||||
/**
|
||||
* Beware: this map will _only_ be set by this component
|
||||
* It should thus be treated as a 'store' by external parties
|
||||
*/
|
||||
export let map: Writable<MaplibreMap>
|
||||
export let map: Writable<MaplibreMap>
|
||||
|
||||
export let attribution = false
|
||||
let center = {};
|
||||
let center = {}
|
||||
|
||||
onMount(() => {
|
||||
$map.on("load", function() {
|
||||
$map.resize();
|
||||
});
|
||||
});
|
||||
const styleUrl = AvailableRasterLayers.maplibre.properties.url;
|
||||
$map.on("load", function () {
|
||||
$map.resize()
|
||||
})
|
||||
})
|
||||
const styleUrl = AvailableRasterLayers.maplibre.properties.url
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<Map bind:center={center}
|
||||
bind:map={$map}
|
||||
{attribution}
|
||||
css="./maplibre-gl.css"
|
||||
|
||||
id="map" location={{lng: 0, lat: 0, zoom: 0}} maxzoom=24 style={styleUrl} />
|
||||
<Map
|
||||
bind:center
|
||||
bind:map={$map}
|
||||
{attribution}
|
||||
css="./maplibre-gl.css"
|
||||
id="map"
|
||||
location={{ lng: 0, lat: 0, zoom: 0 }}
|
||||
maxzoom="24"
|
||||
style={styleUrl}
|
||||
/>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,69 +1,69 @@
|
|||
<script lang="ts">
|
||||
/**
|
||||
* The overlay map is a bit a weird map:
|
||||
* it is a HTML-component which is intended to be placed _over_ another map.
|
||||
* It will align itself in order to seamlessly show the same location; but possibly in a different style
|
||||
*/
|
||||
import MaplibreMap from "./MaplibreMap.svelte";
|
||||
import {Store, UIEventSource} from "../../Logic/UIEventSource";
|
||||
import {Map as MlMap} from "maplibre-gl";
|
||||
import {MapLibreAdaptor} from "./MapLibreAdaptor";
|
||||
import type {MapProperties} from "../../Models/MapProperties";
|
||||
import {onDestroy} from "svelte";
|
||||
import type {RasterLayerPolygon} from "../../Models/RasterLayers";
|
||||
/**
|
||||
* The overlay map is a bit a weird map:
|
||||
* it is a HTML-component which is intended to be placed _over_ another map.
|
||||
* It will align itself in order to seamlessly show the same location; but possibly in a different style
|
||||
*/
|
||||
import MaplibreMap from "./MaplibreMap.svelte"
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Map as MlMap } from "maplibre-gl"
|
||||
import { MapLibreAdaptor } from "./MapLibreAdaptor"
|
||||
import type { MapProperties } from "../../Models/MapProperties"
|
||||
import { onDestroy } from "svelte"
|
||||
import type { RasterLayerPolygon } from "../../Models/RasterLayers"
|
||||
|
||||
export let placedOverMapProperties: MapProperties
|
||||
export let placedOverMap: UIEventSource<MlMap>
|
||||
|
||||
export let placedOverMapProperties: MapProperties
|
||||
export let placedOverMap: UIEventSource<MlMap>
|
||||
export let rasterLayer: UIEventSource<RasterLayerPolygon>
|
||||
|
||||
export let rasterLayer: UIEventSource<RasterLayerPolygon>
|
||||
export let visible: Store<boolean> = undefined
|
||||
let altmap: UIEventSource<MlMap> = new UIEventSource(undefined)
|
||||
let altproperties = new MapLibreAdaptor(altmap, {
|
||||
rasterLayer,
|
||||
zoom: UIEventSource.feedFrom(placedOverMapProperties.zoom),
|
||||
})
|
||||
altproperties.allowMoving.setData(false)
|
||||
altproperties.allowZooming.setData(false)
|
||||
|
||||
export let visible: Store<boolean> = undefined
|
||||
let altmap: UIEventSource<MlMap> = new UIEventSource(undefined)
|
||||
let altproperties = new MapLibreAdaptor(altmap, {
|
||||
rasterLayer,
|
||||
zoom: UIEventSource.feedFrom(placedOverMapProperties.zoom)
|
||||
})
|
||||
altproperties.allowMoving.setData(false)
|
||||
altproperties.allowZooming.setData(false)
|
||||
function pixelCenterOf(map: UIEventSource<MlMap>): [number, number] {
|
||||
const rect = map?.data?.getCanvas()?.getBoundingClientRect()
|
||||
if (!rect) {
|
||||
return undefined
|
||||
}
|
||||
const x = (rect.left + rect.right) / 2
|
||||
const y = (rect.top + rect.bottom) / 2
|
||||
return [x, y]
|
||||
}
|
||||
|
||||
function pixelCenterOf(map: UIEventSource<MlMap>): [number, number] {
|
||||
const rect = map?.data?.getCanvas()?.getBoundingClientRect()
|
||||
if (!rect) {
|
||||
return undefined
|
||||
function updateLocation() {
|
||||
if (!placedOverMap.data || !altmap.data) {
|
||||
return
|
||||
}
|
||||
altmap.data.resize()
|
||||
const { lon, lat } = placedOverMapProperties.location.data
|
||||
const altMapCenter = pixelCenterOf(altmap)
|
||||
const c = placedOverMap.data.unproject(altMapCenter)
|
||||
altproperties.location.setData({ lon: c.lng, lat: c.lat })
|
||||
}
|
||||
|
||||
onDestroy(placedOverMapProperties.location.addCallbackAndRunD(updateLocation))
|
||||
updateLocation()
|
||||
window.setTimeout(updateLocation, 150)
|
||||
window.setTimeout(updateLocation, 500)
|
||||
|
||||
if (visible) {
|
||||
onDestroy(
|
||||
visible?.addCallbackAndRunD((v) => {
|
||||
if (!v) {
|
||||
return
|
||||
}
|
||||
const x = (rect.left + rect.right) / 2
|
||||
const y = (rect.top + rect.bottom) / 2
|
||||
return [x, y]
|
||||
}
|
||||
|
||||
function updateLocation() {
|
||||
if (!placedOverMap.data || !altmap.data) {
|
||||
return
|
||||
}
|
||||
altmap.data.resize()
|
||||
const {lon, lat} = placedOverMapProperties.location.data
|
||||
const altMapCenter = pixelCenterOf(altmap)
|
||||
const c = placedOverMap.data.unproject(altMapCenter)
|
||||
altproperties.location.setData({lon: c.lng, lat: c.lat})
|
||||
}
|
||||
|
||||
onDestroy(placedOverMapProperties.location.addCallbackAndRunD(updateLocation))
|
||||
updateLocation()
|
||||
window.setTimeout(updateLocation, 150)
|
||||
window.setTimeout(updateLocation, 500)
|
||||
|
||||
if (visible) {
|
||||
onDestroy(visible?.addCallbackAndRunD(v => {
|
||||
if (!v) {
|
||||
return
|
||||
}
|
||||
updateLocation()
|
||||
window.setTimeout(updateLocation, 150)
|
||||
window.setTimeout(updateLocation, 500)
|
||||
}))
|
||||
}
|
||||
|
||||
updateLocation()
|
||||
window.setTimeout(updateLocation, 150)
|
||||
window.setTimeout(updateLocation, 500)
|
||||
})
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
<MaplibreMap map={altmap}/>
|
||||
<MaplibreMap map={altmap} />
|
||||
|
|
|
@ -1,73 +1,94 @@
|
|||
<script lang="ts">
|
||||
/**
|
||||
* The RasterLayerOverview shows the available 4 categories of maps with a RasterLayerPicker
|
||||
*/
|
||||
import {Store, UIEventSource} from "../../Logic/UIEventSource";
|
||||
import type {RasterLayerPolygon} from "../../Models/RasterLayers";
|
||||
import type {MapProperties} from "../../Models/MapProperties";
|
||||
import {Map as MlMap} from "maplibre-gl";
|
||||
import RasterLayerPicker from "./RasterLayerPicker.svelte";
|
||||
import type {EliCategory} from "../../Models/RasterLayerProperties";
|
||||
import UserRelatedState from "../../Logic/State/UserRelatedState";
|
||||
import Translations from "../i18n/Translations";
|
||||
import Tr from "../Base/Tr.svelte";
|
||||
/**
|
||||
* The RasterLayerOverview shows the available 4 categories of maps with a RasterLayerPicker
|
||||
*/
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import type { RasterLayerPolygon } from "../../Models/RasterLayers"
|
||||
import type { MapProperties } from "../../Models/MapProperties"
|
||||
import { Map as MlMap } from "maplibre-gl"
|
||||
import RasterLayerPicker from "./RasterLayerPicker.svelte"
|
||||
import type { EliCategory } from "../../Models/RasterLayerProperties"
|
||||
import UserRelatedState from "../../Logic/State/UserRelatedState"
|
||||
import Translations from "../i18n/Translations"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
|
||||
export let availableLayers: Store<RasterLayerPolygon[]>
|
||||
export let mapproperties: MapProperties
|
||||
export let userstate: UserRelatedState
|
||||
export let map: Store<MlMap>
|
||||
/**
|
||||
* Used to toggle the background layers on/off
|
||||
*/
|
||||
export let visible: UIEventSource<boolean> = undefined
|
||||
export let availableLayers: Store<RasterLayerPolygon[]>
|
||||
export let mapproperties: MapProperties
|
||||
export let userstate: UserRelatedState
|
||||
export let map: Store<MlMap>
|
||||
/**
|
||||
* Used to toggle the background layers on/off
|
||||
*/
|
||||
export let visible: UIEventSource<boolean> = undefined
|
||||
|
||||
type CategoryType = "photo" | "map" | "other" | "osmbasedmap"
|
||||
const categories: Record<CategoryType, EliCategory[]> = {
|
||||
"photo": ["photo", "historicphoto"],
|
||||
"map": ["map", "historicmap"],
|
||||
"other": ["other", "elevation"],
|
||||
"osmbasedmap": ["osmbasedmap"]
|
||||
}
|
||||
type CategoryType = "photo" | "map" | "other" | "osmbasedmap"
|
||||
const categories: Record<CategoryType, EliCategory[]> = {
|
||||
photo: ["photo", "historicphoto"],
|
||||
map: ["map", "historicmap"],
|
||||
other: ["other", "elevation"],
|
||||
osmbasedmap: ["osmbasedmap"],
|
||||
}
|
||||
|
||||
function availableForCategory(type: CategoryType): Store<RasterLayerPolygon[]> {
|
||||
const keywords = categories[type]
|
||||
return availableLayers.mapD(available => available.filter(layer =>
|
||||
keywords.indexOf(<EliCategory>layer.properties.category) >= 0
|
||||
))
|
||||
}
|
||||
function availableForCategory(type: CategoryType): Store<RasterLayerPolygon[]> {
|
||||
const keywords = categories[type]
|
||||
return availableLayers.mapD((available) =>
|
||||
available.filter((layer) => keywords.indexOf(<EliCategory>layer.properties.category) >= 0)
|
||||
)
|
||||
}
|
||||
|
||||
const mapLayers = availableForCategory("map")
|
||||
const osmbasedmapLayers = availableForCategory("osmbasedmap")
|
||||
const photoLayers = availableForCategory("photo")
|
||||
const otherLayers = availableForCategory("other")
|
||||
const mapLayers = availableForCategory("map")
|
||||
const osmbasedmapLayers = availableForCategory("osmbasedmap")
|
||||
const photoLayers = availableForCategory("photo")
|
||||
const otherLayers = availableForCategory("other")
|
||||
|
||||
function onApply() {
|
||||
visible.setData(false)
|
||||
}
|
||||
|
||||
function getPref(type: CategoryType): undefined | UIEventSource<string> {
|
||||
return userstate?.osmConnection?.GetPreference("preferred-layer-" + type)
|
||||
}
|
||||
function onApply() {
|
||||
visible.setData(false)
|
||||
}
|
||||
|
||||
function getPref(type: CategoryType): undefined | UIEventSource<string> {
|
||||
return userstate?.osmConnection?.GetPreference("preferred-layer-" + type)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<div class="h-full flex flex-col">
|
||||
<slot name="title">
|
||||
<h2>
|
||||
<Tr t={Translations.t.general.backgroundMap}/>
|
||||
</h2>
|
||||
</slot>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 h-full w-full">
|
||||
<RasterLayerPicker availableLayers={photoLayers} favourite={getPref("photo")} {map} {mapproperties}
|
||||
on:appliedLayer={onApply} {visible}/>
|
||||
<RasterLayerPicker availableLayers={mapLayers} favourite={getPref("map")} {map} {mapproperties}
|
||||
on:appliedLayer={onApply} {visible}/>
|
||||
<RasterLayerPicker availableLayers={osmbasedmapLayers} favourite={getPref("osmbasedmap")}
|
||||
{map} {mapproperties} on:appliedLayer={onApply} {visible}/>
|
||||
<RasterLayerPicker availableLayers={otherLayers} favourite={getPref("other")} {map} {mapproperties}
|
||||
on:appliedLayer={onApply} {visible}/>
|
||||
</div>
|
||||
<slot name="title">
|
||||
<h2>
|
||||
<Tr t={Translations.t.general.backgroundMap} />
|
||||
</h2>
|
||||
</slot>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 h-full w-full">
|
||||
<RasterLayerPicker
|
||||
availableLayers={photoLayers}
|
||||
favourite={getPref("photo")}
|
||||
{map}
|
||||
{mapproperties}
|
||||
on:appliedLayer={onApply}
|
||||
{visible}
|
||||
/>
|
||||
<RasterLayerPicker
|
||||
availableLayers={mapLayers}
|
||||
favourite={getPref("map")}
|
||||
{map}
|
||||
{mapproperties}
|
||||
on:appliedLayer={onApply}
|
||||
{visible}
|
||||
/>
|
||||
<RasterLayerPicker
|
||||
availableLayers={osmbasedmapLayers}
|
||||
favourite={getPref("osmbasedmap")}
|
||||
{map}
|
||||
{mapproperties}
|
||||
on:appliedLayer={onApply}
|
||||
{visible}
|
||||
/>
|
||||
<RasterLayerPicker
|
||||
availableLayers={otherLayers}
|
||||
favourite={getPref("other")}
|
||||
{map}
|
||||
{mapproperties}
|
||||
on:appliedLayer={onApply}
|
||||
{visible}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,77 +1,92 @@
|
|||
<script lang="ts">
|
||||
import type {RasterLayerPolygon} from "../../Models/RasterLayers";
|
||||
import OverlayMap from "./OverlayMap.svelte";
|
||||
import type {MapProperties} from "../../Models/MapProperties";
|
||||
import {Store, UIEventSource} from "../../Logic/UIEventSource";
|
||||
import {Map as MlMap} from "maplibre-gl"
|
||||
import {createEventDispatcher, onDestroy} from "svelte";
|
||||
import type { RasterLayerPolygon } from "../../Models/RasterLayers"
|
||||
import OverlayMap from "./OverlayMap.svelte"
|
||||
import type { MapProperties } from "../../Models/MapProperties"
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Map as MlMap } from "maplibre-gl"
|
||||
import { createEventDispatcher, onDestroy } from "svelte"
|
||||
|
||||
/***
|
||||
* Chooses a background-layer out of available options
|
||||
*/
|
||||
export let availableLayers: Store<RasterLayerPolygon[]>
|
||||
export let mapproperties: MapProperties
|
||||
export let map: Store<MlMap>
|
||||
/***
|
||||
* Chooses a background-layer out of available options
|
||||
*/
|
||||
export let availableLayers: Store<RasterLayerPolygon[]>
|
||||
export let mapproperties: MapProperties
|
||||
export let map: Store<MlMap>
|
||||
|
||||
export let visible: Store<boolean> = undefined
|
||||
|
||||
let dispatch = createEventDispatcher<{appliedLayer}>()
|
||||
|
||||
export let favourite : UIEventSource<string> | undefined = undefined
|
||||
|
||||
export let visible: Store<boolean> = undefined
|
||||
|
||||
let rasterLayer = new UIEventSource<RasterLayerPolygon>(availableLayers.data?.[0])
|
||||
let hasLayers = true
|
||||
onDestroy(availableLayers.addCallbackAndRun(layers => {
|
||||
if (layers === undefined || layers.length === 0) {
|
||||
hasLayers = false
|
||||
return
|
||||
let dispatch = createEventDispatcher<{ appliedLayer }>()
|
||||
|
||||
export let favourite: UIEventSource<string> | undefined = undefined
|
||||
|
||||
let rasterLayer = new UIEventSource<RasterLayerPolygon>(availableLayers.data?.[0])
|
||||
let hasLayers = true
|
||||
onDestroy(
|
||||
availableLayers.addCallbackAndRun((layers) => {
|
||||
if (layers === undefined || layers.length === 0) {
|
||||
hasLayers = false
|
||||
return
|
||||
}
|
||||
hasLayers = true
|
||||
rasterLayer.setData(layers[0])
|
||||
})
|
||||
)
|
||||
|
||||
if (favourite) {
|
||||
onDestroy(
|
||||
favourite.addCallbackAndRunD((favourite) => {
|
||||
const fav = availableLayers.data?.find((l) => l.properties.id === favourite)
|
||||
if (!fav) {
|
||||
return
|
||||
}
|
||||
hasLayers = true
|
||||
rasterLayer.setData(layers[0])
|
||||
}))
|
||||
|
||||
if(favourite){
|
||||
onDestroy(favourite.addCallbackAndRunD(favourite => {
|
||||
const fav = availableLayers.data?.find(l => l.properties.id === favourite)
|
||||
if(!fav){
|
||||
return
|
||||
}
|
||||
rasterLayer.setData(fav)
|
||||
}))
|
||||
|
||||
onDestroy(rasterLayer.addCallbackAndRunD(selected => {
|
||||
favourite?.setData(selected.properties.id)
|
||||
}))
|
||||
}
|
||||
rasterLayer.setData(fav)
|
||||
})
|
||||
)
|
||||
|
||||
let rasterLayerOnMap = UIEventSource.feedFrom(rasterLayer)
|
||||
|
||||
if (visible) {
|
||||
onDestroy(visible?.addCallbackAndRunD(visible => {
|
||||
if (visible) {
|
||||
rasterLayerOnMap.setData(rasterLayer.data ?? availableLayers.data[0])
|
||||
} else {
|
||||
rasterLayerOnMap.setData(undefined)
|
||||
}
|
||||
}))
|
||||
}
|
||||
onDestroy(
|
||||
rasterLayer.addCallbackAndRunD((selected) => {
|
||||
favourite?.setData(selected.properties.id)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
let rasterLayerOnMap = UIEventSource.feedFrom(rasterLayer)
|
||||
|
||||
if (visible) {
|
||||
onDestroy(
|
||||
visible?.addCallbackAndRunD((visible) => {
|
||||
if (visible) {
|
||||
rasterLayerOnMap.setData(rasterLayer.data ?? availableLayers.data[0])
|
||||
} else {
|
||||
rasterLayerOnMap.setData(undefined)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if hasLayers}
|
||||
<div class="h-full w-full flex flex-col">
|
||||
<button on:click={() => {mapproperties.rasterLayer.setData(rasterLayer.data);
|
||||
dispatch("appliedLayer")
|
||||
}} class="w-full h-full m-0 p-0">
|
||||
<OverlayMap rasterLayer={rasterLayerOnMap} placedOverMap={map} placedOverMapProperties={mapproperties}
|
||||
{visible}/>
|
||||
</button>
|
||||
<select bind:value={$rasterLayer} class="w-full">
|
||||
{#each $availableLayers as availableLayer }
|
||||
<option value={availableLayer}>
|
||||
{availableLayer.properties.name}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div class="h-full w-full flex flex-col">
|
||||
<button
|
||||
on:click={() => {
|
||||
mapproperties.rasterLayer.setData(rasterLayer.data)
|
||||
dispatch("appliedLayer")
|
||||
}}
|
||||
class="w-full h-full m-0 p-0"
|
||||
>
|
||||
<OverlayMap
|
||||
rasterLayer={rasterLayerOnMap}
|
||||
placedOverMap={map}
|
||||
placedOverMapProperties={mapproperties}
|
||||
{visible}
|
||||
/>
|
||||
</button>
|
||||
<select bind:value={$rasterLayer} class="w-full">
|
||||
{#each $availableLayers as availableLayer}
|
||||
<option value={availableLayer}>
|
||||
{availableLayer.properties.name}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import {ImmutableStore, Store, UIEventSource} from "../../Logic/UIEventSource"
|
||||
import type {Map as MlMap} from "maplibre-gl"
|
||||
import {GeoJSONSource, Marker} from "maplibre-gl"
|
||||
import {ShowDataLayerOptions} from "./ShowDataLayerOptions"
|
||||
import {GeoOperations} from "../../Logic/GeoOperations"
|
||||
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import type { Map as MlMap } from "maplibre-gl"
|
||||
import { GeoJSONSource, Marker } from "maplibre-gl"
|
||||
import { ShowDataLayerOptions } from "./ShowDataLayerOptions"
|
||||
import { GeoOperations } from "../../Logic/GeoOperations"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import PointRenderingConfig from "../../Models/ThemeConfig/PointRenderingConfig"
|
||||
import {OsmTags} from "../../Models/OsmFeature"
|
||||
import {FeatureSource, FeatureSourceForLayer} from "../../Logic/FeatureSource/FeatureSource"
|
||||
import {BBox} from "../../Logic/BBox"
|
||||
import {Feature, Point} from "geojson"
|
||||
import { OsmTags } from "../../Models/OsmFeature"
|
||||
import { FeatureSource, FeatureSourceForLayer } from "../../Logic/FeatureSource/FeatureSource"
|
||||
import { BBox } from "../../Logic/BBox"
|
||||
import { Feature, Point } from "geojson"
|
||||
import LineRenderingConfig from "../../Models/ThemeConfig/LineRenderingConfig"
|
||||
import {Utils} from "../../Utils"
|
||||
import { Utils } from "../../Utils"
|
||||
import * as range_layer from "../../assets/layers/range/range.json"
|
||||
import {LayerConfigJson} from "../../Models/ThemeConfig/Json/LayerConfigJson"
|
||||
import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson"
|
||||
import PerLayerFeatureSourceSplitter from "../../Logic/FeatureSource/PerLayerFeatureSourceSplitter"
|
||||
import FilteredLayer from "../../Models/FilteredLayer"
|
||||
import SimpleFeatureSource from "../../Logic/FeatureSource/Sources/SimpleFeatureSource"
|
||||
|
@ -143,7 +143,7 @@ class PointRenderingLayer {
|
|||
} else {
|
||||
store = new ImmutableStore(<OsmTags>feature.properties)
|
||||
}
|
||||
const {html, iconAnchor} = this._config.RenderIcon(store, true)
|
||||
const { html, iconAnchor } = this._config.RenderIcon(store, true)
|
||||
html.SetClass("marker")
|
||||
if (this._onClick !== undefined) {
|
||||
html.SetClass("cursor-pointer")
|
||||
|
@ -177,7 +177,7 @@ class PointRenderingLayer {
|
|||
if (newloc[0] === oldLoc.lng && newloc[1] === oldLoc.lat) {
|
||||
return
|
||||
}
|
||||
marker.setLngLat({lon: newloc[0], lat: newloc[1]})
|
||||
marker.setLngLat({ lon: newloc[0], lat: newloc[1] })
|
||||
})
|
||||
}
|
||||
return marker
|
||||
|
@ -332,7 +332,7 @@ class LineRenderingLayer {
|
|||
map.on("click", polylayer, (e) => {
|
||||
console.log("Got polylayer click:", e)
|
||||
// polygon-layer-listener
|
||||
if(e.originalEvent["consumed"]){
|
||||
if (e.originalEvent["consumed"]) {
|
||||
// This is a polygon beneath a marker, we can ignore it
|
||||
return
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ class LineRenderingLayer {
|
|||
}
|
||||
if (this._fetchStore === undefined) {
|
||||
map.setFeatureState(
|
||||
{source: this._layername, id},
|
||||
{ source: this._layername, id },
|
||||
this.calculatePropsFor(feature.properties)
|
||||
)
|
||||
} else {
|
||||
|
@ -390,7 +390,7 @@ class LineRenderingLayer {
|
|||
this._listenerInstalledOn.add(id)
|
||||
tags.addCallbackAndRunD((properties) => {
|
||||
map.setFeatureState(
|
||||
{source: this._layername, id},
|
||||
{ source: this._layername, id },
|
||||
this.calculatePropsFor(properties)
|
||||
)
|
||||
})
|
||||
|
@ -462,9 +462,7 @@ export default class ShowDataLayer {
|
|||
})
|
||||
}
|
||||
|
||||
public destruct() {
|
||||
|
||||
}
|
||||
public destruct() {}
|
||||
|
||||
private zoomToCurrentFeatures(map: MlMap) {
|
||||
if (this._options.zoomToFeatures) {
|
||||
|
@ -472,20 +470,22 @@ export default class ShowDataLayer {
|
|||
const bbox = BBox.bboxAroundAll(features.map(BBox.get))
|
||||
map.resize()
|
||||
map.fitBounds(bbox.toLngLat(), {
|
||||
padding: {top: 10, bottom: 10, left: 10, right: 10},
|
||||
animate: false
|
||||
padding: { top: 10, bottom: 10, left: 10, right: 10 },
|
||||
animate: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private initDrawFeatures(map: MlMap) {
|
||||
let {features, doShowLayer, fetchStore, selectedElement, selectedLayer} = this._options
|
||||
let { features, doShowLayer, fetchStore, selectedElement, selectedLayer } = this._options
|
||||
const onClick =
|
||||
this._options.onClick ??
|
||||
(this._options.layer.title === undefined ? undefined : ((feature: Feature) => {
|
||||
selectedElement?.setData(feature)
|
||||
selectedLayer?.setData(this._options.layer)
|
||||
}))
|
||||
(this._options.layer.title === undefined
|
||||
? undefined
|
||||
: (feature: Feature) => {
|
||||
selectedElement?.setData(feature)
|
||||
selectedLayer?.setData(this._options.layer)
|
||||
})
|
||||
if (this._options.drawLines !== false) {
|
||||
for (let i = 0; i < this._options.layer.lineRendering.length; i++) {
|
||||
const lineRenderingConfig = this._options.layer.lineRendering[i]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue