forked from MapComplete/MapComplete
refactoring(maplibre): add RasterLayer info, add background switch, add default global layers
This commit is contained in:
parent
703d561324
commit
4f2bbf4b54
14 changed files with 1103 additions and 472 deletions
|
@ -1,51 +0,0 @@
|
|||
import BaseLayer from "../../Models/BaseLayer"
|
||||
import { ImmutableStore, Store, UIEventSource } from "../UIEventSource"
|
||||
import Loc from "../../Models/Loc"
|
||||
|
||||
export interface AvailableBaseLayersObj {
|
||||
readonly osmCarto: BaseLayer
|
||||
layerOverview: BaseLayer[]
|
||||
|
||||
AvailableLayersAt(location: Store<Loc>): Store<BaseLayer[]>
|
||||
|
||||
SelectBestLayerAccordingTo(
|
||||
location: Store<Loc>,
|
||||
preferedCategory: Store<string | string[]>
|
||||
): Store<BaseLayer>
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates which layers are available at the current location
|
||||
* Changes the basemap
|
||||
*/
|
||||
export default class AvailableBaseLayers {
|
||||
public static layerOverview: BaseLayer[]
|
||||
public static osmCarto: BaseLayer
|
||||
|
||||
private static implementation: AvailableBaseLayersObj
|
||||
|
||||
static AvailableLayersAt(location: Store<Loc>): Store<BaseLayer[]> {
|
||||
return (
|
||||
AvailableBaseLayers.implementation?.AvailableLayersAt(location) ??
|
||||
new ImmutableStore<BaseLayer[]>([])
|
||||
)
|
||||
}
|
||||
|
||||
static SelectBestLayerAccordingTo(
|
||||
location: Store<Loc>,
|
||||
preferedCategory: UIEventSource<string | string[]>
|
||||
): Store<BaseLayer> {
|
||||
return (
|
||||
AvailableBaseLayers.implementation?.SelectBestLayerAccordingTo(
|
||||
location,
|
||||
preferedCategory
|
||||
) ?? new ImmutableStore<BaseLayer>(undefined)
|
||||
)
|
||||
}
|
||||
|
||||
public static implement(backend: AvailableBaseLayersObj) {
|
||||
AvailableBaseLayers.layerOverview = backend.layerOverview
|
||||
AvailableBaseLayers.osmCarto = backend.osmCarto
|
||||
AvailableBaseLayers.implementation = backend
|
||||
}
|
||||
}
|
|
@ -1,309 +0,0 @@
|
|||
import BaseLayer from "../../Models/BaseLayer"
|
||||
import { Store, Stores } from "../UIEventSource"
|
||||
import Loc from "../../Models/Loc"
|
||||
import { GeoOperations } from "../GeoOperations"
|
||||
import * as editorlayerindex from "../../assets/editor-layer-index.json"
|
||||
import * as L from "leaflet"
|
||||
import { TileLayer } from "leaflet"
|
||||
import * as X from "leaflet-providers"
|
||||
import { Utils } from "../../Utils"
|
||||
import { AvailableBaseLayersObj } from "./AvailableBaseLayers"
|
||||
import { BBox } from "../BBox"
|
||||
|
||||
export default class AvailableBaseLayersImplementation implements AvailableBaseLayersObj {
|
||||
public readonly osmCarto: BaseLayer = {
|
||||
id: "osm",
|
||||
name: "OpenStreetMap",
|
||||
layer: () =>
|
||||
AvailableBaseLayersImplementation.CreateBackgroundLayer(
|
||||
"osm",
|
||||
"OpenStreetMap",
|
||||
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
||||
"OpenStreetMap",
|
||||
"https://openStreetMap.org/copyright",
|
||||
19,
|
||||
false,
|
||||
false
|
||||
),
|
||||
feature: null,
|
||||
max_zoom: 19,
|
||||
min_zoom: 0,
|
||||
isBest: true, // Of course, OpenStreetMap is the best map!
|
||||
category: "osmbasedmap",
|
||||
}
|
||||
|
||||
public readonly layerOverview = AvailableBaseLayersImplementation.LoadRasterIndex().concat(
|
||||
AvailableBaseLayersImplementation.LoadProviderIndex()
|
||||
)
|
||||
public readonly globalLayers = this.layerOverview.filter(
|
||||
(layer) => layer.feature?.geometry === undefined || layer.feature?.geometry === null
|
||||
)
|
||||
public readonly localLayers = this.layerOverview.filter(
|
||||
(layer) => layer.feature?.geometry !== undefined && layer.feature?.geometry !== null
|
||||
)
|
||||
|
||||
private static LoadRasterIndex(): BaseLayer[] {
|
||||
const layers: BaseLayer[] = []
|
||||
// @ts-ignore
|
||||
const features = editorlayerindex.features
|
||||
for (const i in features) {
|
||||
const layer = features[i]
|
||||
const props = layer.properties
|
||||
|
||||
if (props.type === "bing") {
|
||||
// A lot of work to implement - see https://github.com/pietervdvn/MapComplete/issues/648
|
||||
continue
|
||||
}
|
||||
|
||||
if (props.id === "MAPNIK") {
|
||||
// Already added by default
|
||||
continue
|
||||
}
|
||||
|
||||
if (props.overlay) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (props.url.toLowerCase().indexOf("apikey") > 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (props.max_zoom < 19) {
|
||||
// We want users to zoom to level 19 when adding a point
|
||||
// If they are on a layer which hasn't enough precision, they can not zoom far enough. This is confusing, so we don't use this layer
|
||||
continue
|
||||
}
|
||||
|
||||
if (props.name === undefined) {
|
||||
console.warn("Editor layer index: name not defined on ", props)
|
||||
continue
|
||||
}
|
||||
|
||||
const leafletLayer: () => TileLayer = () =>
|
||||
AvailableBaseLayersImplementation.CreateBackgroundLayer(
|
||||
props.id,
|
||||
props.name,
|
||||
props.url,
|
||||
props.name,
|
||||
props.license_url,
|
||||
props.max_zoom,
|
||||
props.type.toLowerCase() === "wms",
|
||||
props.type.toLowerCase() === "wmts"
|
||||
)
|
||||
|
||||
// Note: if layer.geometry is null, there is global coverage for this layer
|
||||
layers.push({
|
||||
id: props.id,
|
||||
max_zoom: props.max_zoom ?? 19,
|
||||
min_zoom: props.min_zoom ?? 1,
|
||||
name: props.name,
|
||||
layer: leafletLayer,
|
||||
feature: layer.geometry !== null ? layer : null,
|
||||
isBest: props.best ?? false,
|
||||
category: props.category,
|
||||
})
|
||||
}
|
||||
return layers
|
||||
}
|
||||
|
||||
private static LoadProviderIndex(): BaseLayer[] {
|
||||
// @ts-ignore
|
||||
X // Import X to make sure the namespace is not optimized away
|
||||
function l(id: string, name: string): BaseLayer {
|
||||
try {
|
||||
const layer: any = L.tileLayer.provider(id, undefined)
|
||||
return {
|
||||
feature: null,
|
||||
id: id,
|
||||
name: name,
|
||||
layer: () =>
|
||||
L.tileLayer.provider(id, {
|
||||
maxNativeZoom: layer.options?.maxZoom,
|
||||
maxZoom: Math.max(layer.options?.maxZoom ?? 19, 21),
|
||||
}),
|
||||
min_zoom: 1,
|
||||
max_zoom: layer.options.maxZoom,
|
||||
category: "osmbasedmap",
|
||||
isBest: false,
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Could not find provided layer", name, e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const layers = [
|
||||
l("Stamen.TonerLite", "Toner Lite (by Stamen)"),
|
||||
l("Stamen.TonerBackground", "Toner Background - no labels (by Stamen)"),
|
||||
l("Stamen.Watercolor", "Watercolor (by Stamen)"),
|
||||
l("CartoDB.Positron", "Positron (by CartoDB)"),
|
||||
l("CartoDB.PositronNoLabels", "Positron - no labels (by CartoDB)"),
|
||||
l("CartoDB.Voyager", "Voyager (by CartoDB)"),
|
||||
l("CartoDB.VoyagerNoLabels", "Voyager - no labels (by CartoDB)"),
|
||||
l("CartoDB.DarkMatter", "Dark Matter (by CartoDB)"),
|
||||
l("CartoDB.DarkMatterNoLabels", "Dark Matter - no labels (by CartoDB)"),
|
||||
]
|
||||
return Utils.NoNull(layers)
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a layer from the editor-layer-index into a tilelayer usable by leaflet
|
||||
*/
|
||||
private static CreateBackgroundLayer(
|
||||
id: string,
|
||||
name: string,
|
||||
url: string,
|
||||
attribution: string,
|
||||
attributionUrl: string,
|
||||
maxZoom: number,
|
||||
isWms: boolean,
|
||||
isWMTS?: boolean
|
||||
): TileLayer {
|
||||
url = url.replace("{zoom}", "{z}").replace("&BBOX={bbox}", "").replace("&bbox={bbox}", "")
|
||||
|
||||
const subdomainsMatch = url.match(/{switch:[^}]*}/)
|
||||
let domains: string[] = []
|
||||
if (subdomainsMatch !== null) {
|
||||
let domainsStr = subdomainsMatch[0].substr("{switch:".length)
|
||||
domainsStr = domainsStr.substr(0, domainsStr.length - 1)
|
||||
domains = domainsStr.split(",")
|
||||
url = url.replace(/{switch:[^}]*}/, "{s}")
|
||||
}
|
||||
|
||||
if (isWms) {
|
||||
url = url.replace("&SRS={proj}", "")
|
||||
url = url.replace("&srs={proj}", "")
|
||||
const paramaters = [
|
||||
"format",
|
||||
"layers",
|
||||
"version",
|
||||
"service",
|
||||
"request",
|
||||
"styles",
|
||||
"transparent",
|
||||
"version",
|
||||
]
|
||||
const urlObj = new URL(url)
|
||||
|
||||
const isUpper = urlObj.searchParams["LAYERS"] !== null
|
||||
const options = {
|
||||
maxZoom: Math.max(maxZoom ?? 19, 21),
|
||||
maxNativeZoom: maxZoom ?? 19,
|
||||
attribution: attribution + " | ",
|
||||
subdomains: domains,
|
||||
uppercase: isUpper,
|
||||
transparent: false,
|
||||
}
|
||||
|
||||
for (const paramater of paramaters) {
|
||||
let p = paramater
|
||||
if (isUpper) {
|
||||
p = paramater.toUpperCase()
|
||||
}
|
||||
options[paramater] = urlObj.searchParams.get(p)
|
||||
}
|
||||
|
||||
if (options.transparent === null) {
|
||||
options.transparent = false
|
||||
}
|
||||
|
||||
return L.tileLayer.wms(urlObj.protocol + "//" + urlObj.host + urlObj.pathname, options)
|
||||
}
|
||||
|
||||
if (attributionUrl) {
|
||||
attribution = `<a href='${attributionUrl}' target='_blank'>${attribution}</a>`
|
||||
}
|
||||
|
||||
return L.tileLayer(url, {
|
||||
attribution: attribution,
|
||||
maxZoom: Math.max(21, maxZoom ?? 19),
|
||||
maxNativeZoom: maxZoom ?? 19,
|
||||
minZoom: 1,
|
||||
// @ts-ignore
|
||||
wmts: isWMTS ?? false,
|
||||
subdomains: domains,
|
||||
})
|
||||
}
|
||||
|
||||
public AvailableLayersAt(location: Store<Loc>): Store<BaseLayer[]> {
|
||||
return Stores.ListStabilized(
|
||||
location.map((currentLocation) => {
|
||||
if (currentLocation === undefined) {
|
||||
return this.layerOverview
|
||||
}
|
||||
return this.CalculateAvailableLayersAt(currentLocation?.lon, currentLocation?.lat)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
public SelectBestLayerAccordingTo(
|
||||
location: Store<Loc>,
|
||||
preferedCategory: Store<string | string[]>
|
||||
): Store<BaseLayer> {
|
||||
return this.AvailableLayersAt(location).map(
|
||||
(available) => {
|
||||
// First float all 'best layers' to the top
|
||||
available.sort((a, b) => {
|
||||
if (a.isBest && b.isBest) {
|
||||
return 0
|
||||
}
|
||||
if (!a.isBest) {
|
||||
return 1
|
||||
}
|
||||
|
||||
return -1
|
||||
})
|
||||
|
||||
if (preferedCategory.data === undefined) {
|
||||
return available[0]
|
||||
}
|
||||
|
||||
let prefered: string[]
|
||||
if (typeof preferedCategory.data === "string") {
|
||||
prefered = [preferedCategory.data]
|
||||
} else {
|
||||
prefered = preferedCategory.data
|
||||
}
|
||||
|
||||
prefered.reverse(/*New list, inplace reverse is fine*/)
|
||||
for (const category of prefered) {
|
||||
//Then sort all 'photo'-layers to the top. Stability of the sorting will force a 'best' photo layer on top
|
||||
available.sort((a, b) => {
|
||||
if (a.category === category && b.category === category) {
|
||||
return 0
|
||||
}
|
||||
if (a.category !== category) {
|
||||
return 1
|
||||
}
|
||||
|
||||
return -1
|
||||
})
|
||||
}
|
||||
return available[0]
|
||||
},
|
||||
[preferedCategory]
|
||||
)
|
||||
}
|
||||
|
||||
private CalculateAvailableLayersAt(lon: number, lat: number): BaseLayer[] {
|
||||
const availableLayers = [this.osmCarto]
|
||||
if (lon === undefined || lat === undefined) {
|
||||
return availableLayers.concat(this.globalLayers)
|
||||
}
|
||||
const lonlat: [number, number] = [lon, lat]
|
||||
for (const layerOverviewItem of this.localLayers) {
|
||||
const layer = layerOverviewItem
|
||||
const bbox = BBox.get(layer.feature)
|
||||
|
||||
if (!bbox.contains(lonlat)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (GeoOperations.inside(lonlat, layer.feature)) {
|
||||
availableLayers.push(layer)
|
||||
}
|
||||
}
|
||||
|
||||
return availableLayers.concat(this.globalLayers)
|
||||
}
|
||||
}
|
|
@ -1,49 +1,42 @@
|
|||
import { UIEventSource } from "../UIEventSource"
|
||||
import BaseLayer from "../../Models/BaseLayer"
|
||||
import AvailableBaseLayers from "./AvailableBaseLayers"
|
||||
import Loc from "../../Models/Loc"
|
||||
import { Store, UIEventSource } from "../UIEventSource"
|
||||
import { Utils } from "../../Utils"
|
||||
import {
|
||||
AvailableRasterLayers,
|
||||
RasterLayerPolygon,
|
||||
RasterLayerUtils,
|
||||
} from "../../Models/RasterLayers"
|
||||
|
||||
/**
|
||||
* Sets the current background layer to a layer that is actually available
|
||||
* When a user pans around on the map, they might pan out of the range of the current background raster layer.
|
||||
* This actor will then quickly select a (best) raster layer of the same category which is available
|
||||
*/
|
||||
export default class BackgroundLayerResetter {
|
||||
constructor(
|
||||
currentBackgroundLayer: UIEventSource<BaseLayer>,
|
||||
location: UIEventSource<Loc>,
|
||||
availableLayers: UIEventSource<BaseLayer[]>,
|
||||
defaultLayerId: string = undefined
|
||||
currentBackgroundLayer: UIEventSource<RasterLayerPolygon>,
|
||||
availableLayers: Store<RasterLayerPolygon[]>
|
||||
) {
|
||||
if (Utils.runningFromConsole) {
|
||||
return
|
||||
}
|
||||
|
||||
defaultLayerId = defaultLayerId ?? AvailableBaseLayers.osmCarto.id
|
||||
// Change the baseLayer back to OSM if we go out of the current range of the layer
|
||||
availableLayers.addCallbackAndRunD((availableLayers) => {
|
||||
// We only check on move/on change of the availableLayers
|
||||
const currentBgPolygon: RasterLayerPolygon | undefined = currentBackgroundLayer.data
|
||||
|
||||
// Change the baselayer back to OSM if we go out of the current range of the layer
|
||||
availableLayers.addCallbackAndRun((availableLayers) => {
|
||||
let defaultLayer = undefined
|
||||
const currentLayer = currentBackgroundLayer.data.id
|
||||
for (const availableLayer of availableLayers) {
|
||||
if (availableLayer.id === currentLayer) {
|
||||
if (availableLayer.max_zoom < location.data.zoom) {
|
||||
break
|
||||
}
|
||||
|
||||
if (availableLayer.min_zoom > location.data.zoom) {
|
||||
break
|
||||
}
|
||||
if (availableLayer.id === defaultLayerId) {
|
||||
defaultLayer = availableLayer
|
||||
}
|
||||
return // All good - the current layer still works!
|
||||
}
|
||||
if (availableLayers.findIndex((available) => currentBgPolygon == available) >= 0) {
|
||||
// Still available!
|
||||
return
|
||||
}
|
||||
|
||||
// Oops, we panned out of range for this layer!
|
||||
console.log(
|
||||
"AvailableBaseLayers-actor: detected that the current bounds aren't sufficient anymore - reverting to OSM standard"
|
||||
// What is the 'best' map of the same category which is available?
|
||||
const availableInSameCat = RasterLayerUtils.SelectBestLayerAccordingTo(
|
||||
availableLayers,
|
||||
currentBgPolygon?.properties?.category ?? "osmbasedmap"
|
||||
)
|
||||
currentBackgroundLayer.setData(defaultLayer ?? AvailableBaseLayers.osmCarto)
|
||||
console.log("Selecting a different layer:", availableInSameCat.properties.id)
|
||||
currentBackgroundLayer.setData(availableInSameCat ?? AvailableRasterLayers.osmCarto)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
export default interface BaseLayer {
|
||||
id: string
|
||||
name: string
|
||||
layer: () => any /*leaflet.TileLayer - not importing as it breaks scripts*/
|
||||
max_zoom: number
|
||||
min_zoom: number
|
||||
feature: any
|
||||
isBest?: boolean
|
||||
category?: "map" | "osmbasedmap" | "photo" | "historicphoto" | string
|
||||
}
|
276
Models/RasterLayers.ts
Normal file
276
Models/RasterLayers.ts
Normal file
|
@ -0,0 +1,276 @@
|
|||
import { Feature, Polygon } from "geojson"
|
||||
import * as editorlayerindex from "../assets/editor-layer-index.json"
|
||||
import * as globallayers from "../assets/global-raster-layers.json"
|
||||
import { BBox } from "../Logic/BBox"
|
||||
|
||||
export class AvailableRasterLayers {
|
||||
public static EditorLayerIndex: (Feature<Polygon, EditorLayerIndexProperties> &
|
||||
RasterLayerPolygon)[] = <any>editorlayerindex.features
|
||||
public static globalLayers: RasterLayerPolygon[] = globallayers.layers.map(
|
||||
(properties) =>
|
||||
<RasterLayerPolygon>{
|
||||
type: "Feature",
|
||||
properties,
|
||||
geometry: BBox.global.asGeometry(),
|
||||
}
|
||||
)
|
||||
public static readonly osmCartoProperties: RasterLayerProperties = {
|
||||
id: "osm",
|
||||
name: "OpenStreetMap",
|
||||
url: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
||||
attribution: {
|
||||
text: "OpenStreetMap",
|
||||
url: "https://openStreetMap.org/copyright",
|
||||
},
|
||||
best: true,
|
||||
max_zoom: 19,
|
||||
min_zoom: 0,
|
||||
category: "osmbasedmap",
|
||||
}
|
||||
|
||||
public static readonly osmCarto: RasterLayerPolygon = {
|
||||
type: "Feature",
|
||||
properties: AvailableRasterLayers.osmCartoProperties,
|
||||
geometry: BBox.global.asGeometry(),
|
||||
}
|
||||
}
|
||||
|
||||
export class RasterLayerUtils {
|
||||
public static SelectBestLayerAccordingTo(
|
||||
available: RasterLayerPolygon[],
|
||||
preferredCategory: string | string[]
|
||||
): RasterLayerPolygon {
|
||||
available = [...available]
|
||||
|
||||
if (preferredCategory === undefined) {
|
||||
return available[0]
|
||||
}
|
||||
|
||||
let prefered: string[]
|
||||
if (typeof preferredCategory === "string") {
|
||||
prefered = [preferredCategory]
|
||||
} else {
|
||||
prefered = preferredCategory
|
||||
}
|
||||
|
||||
for (let i = prefered.length - 1; i >= 0; i--) {
|
||||
const category = prefered[i]
|
||||
//Then sort all layers of the preferred type to the top. Stability of the sorting will force a 'best' photo layer on top
|
||||
available.sort((ap, bp) => {
|
||||
const a = ap.properties
|
||||
const b = bp.properties
|
||||
if (a.category === category && b.category === category) {
|
||||
return 0
|
||||
}
|
||||
if (a.category !== category) {
|
||||
return 1
|
||||
}
|
||||
|
||||
return -1
|
||||
})
|
||||
}
|
||||
const best = available.find((l) => l.properties.best)
|
||||
if (best) {
|
||||
return best
|
||||
}
|
||||
return available[0]
|
||||
}
|
||||
}
|
||||
|
||||
export type RasterLayerPolygon = Feature<Polygon, RasterLayerProperties>
|
||||
|
||||
export interface RasterLayerProperties {
|
||||
/**
|
||||
* The name of the imagery source
|
||||
*/
|
||||
readonly name: string
|
||||
|
||||
readonly id: string
|
||||
|
||||
readonly url: string
|
||||
readonly category?:
|
||||
| string
|
||||
| "photo"
|
||||
| "map"
|
||||
| "historicmap"
|
||||
| "osmbasedmap"
|
||||
| "historicphoto"
|
||||
| "qa"
|
||||
| "elevation"
|
||||
| "other"
|
||||
|
||||
readonly attribution?: {
|
||||
readonly url?: string
|
||||
readonly text?: string
|
||||
readonly html?: string
|
||||
readonly required?: boolean
|
||||
}
|
||||
|
||||
readonly min_zoom?: number
|
||||
readonly max_zoom?: number
|
||||
|
||||
readonly best?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about a raster tile layer
|
||||
*
|
||||
* Based on the spec here https://github.com/osmlab/editor-layer-index/blob/gh-pages/schema.json
|
||||
* which was then converted with http://borischerny.com/json-schema-to-typescript-browser/
|
||||
*/
|
||||
export interface EditorLayerIndexProperties extends RasterLayerProperties {
|
||||
/**
|
||||
* The name of the imagery source
|
||||
*/
|
||||
readonly name: string
|
||||
/**
|
||||
* Whether the imagery name should be translated
|
||||
*/
|
||||
readonly i18n?: boolean
|
||||
readonly type: "tms" | "wms" | "bing" | "scanex" | "wms_endpoint" | "wmts"
|
||||
/**
|
||||
* A rough categorisation of different types of layers. See https://github.com/osmlab/editor-layer-index/blob/gh-pages/CONTRIBUTING.md#categories for a description of the individual categories.
|
||||
*/
|
||||
readonly category?:
|
||||
| "photo"
|
||||
| "map"
|
||||
| "historicmap"
|
||||
| "osmbasedmap"
|
||||
| "historicphoto"
|
||||
| "qa"
|
||||
| "elevation"
|
||||
| "other"
|
||||
/**
|
||||
* A URL template for imagery tiles
|
||||
*/
|
||||
readonly url: string
|
||||
readonly min_zoom?: number
|
||||
readonly max_zoom?: number
|
||||
/**
|
||||
* explicit/implicit permission by the owner for use in OSM
|
||||
*/
|
||||
readonly permission_osm?: "explicit" | "implicit" | "no"
|
||||
/**
|
||||
* A URL for the license or permissions for the imagery
|
||||
*/
|
||||
readonly license_url?: string
|
||||
/**
|
||||
* A URL for the privacy policy of the operator or false if there is no existing privacy policy for tis imagery.
|
||||
*/
|
||||
readonly privacy_policy_url?: string | boolean
|
||||
/**
|
||||
* A unique identifier for the source; used in imagery_used changeset tag
|
||||
*/
|
||||
readonly id: string
|
||||
/**
|
||||
* A short English-language description of the source
|
||||
*/
|
||||
readonly description?: string
|
||||
/**
|
||||
* The ISO 3166-1 alpha-2 two letter country code in upper case. Use ZZ for unknown or multiple.
|
||||
*/
|
||||
readonly country_code?: string
|
||||
/**
|
||||
* Whether this imagery should be shown in the default world-wide menu
|
||||
*/
|
||||
readonly default?: boolean
|
||||
/**
|
||||
* Whether this imagery is the best source for the region
|
||||
*/
|
||||
readonly best?: boolean
|
||||
/**
|
||||
* The age of the oldest imagery or data in the source, as an RFC3339 date or leading portion of one
|
||||
*/
|
||||
readonly start_date?: string
|
||||
/**
|
||||
* The age of the newest imagery or data in the source, as an RFC3339 date or leading portion of one
|
||||
*/
|
||||
readonly end_date?: string
|
||||
/**
|
||||
* HTTP header to check for information if the tile is invalid
|
||||
*/
|
||||
readonly no_tile_header?: {
|
||||
/**
|
||||
* This interface was referenced by `undefined`'s JSON-Schema definition
|
||||
* via the `patternProperty` "^.*$".
|
||||
*/
|
||||
[k: string]: string[] | null
|
||||
}
|
||||
/**
|
||||
* 'true' if tiles are transparent and can be overlaid on another source
|
||||
*/
|
||||
readonly overlay?: boolean & string
|
||||
readonly available_projections?: string[]
|
||||
readonly attribution?: {
|
||||
readonly url?: string
|
||||
readonly text?: string
|
||||
readonly html?: string
|
||||
readonly required?: boolean
|
||||
}
|
||||
/**
|
||||
* A URL for an image, that can be displayed in the list of imagery layers next to the name
|
||||
*/
|
||||
readonly icon?: string
|
||||
/**
|
||||
* A link to an EULA text that has to be accepted by the user, before the imagery source is added. Can contain {lang} to be replaced by a current user language wiki code (like FR:) or an empty string for the default English text.
|
||||
*/
|
||||
readonly eula?: string
|
||||
/**
|
||||
* A URL for an image, that is displayed in the mapview for attribution
|
||||
*/
|
||||
readonly "logo-image"?: string
|
||||
/**
|
||||
* Customized text for the terms of use link (default is "Background Terms of Use")
|
||||
*/
|
||||
readonly "terms-of-use-text"?: string
|
||||
/**
|
||||
* Specify a checksum for tiles, which aren't real tiles. `type` is the digest type and can be MD5, SHA-1, SHA-256, SHA-384 and SHA-512, value is the hex encoded checksum in lower case. To create a checksum save the tile as file and upload it to e.g. https://defuse.ca/checksums.htm.
|
||||
*/
|
||||
readonly "no-tile-checksum"?: string
|
||||
/**
|
||||
* header-name attribute specifies a header returned by tile server, that will be shown as `metadata-key` attribute in Show Tile Info dialog
|
||||
*/
|
||||
readonly "metadata-header"?: string
|
||||
/**
|
||||
* Set to `true` if imagery source is properly aligned and does not need imagery offset adjustments. This is used for OSM based sources too.
|
||||
*/
|
||||
readonly "valid-georeference"?: boolean
|
||||
/**
|
||||
* Size of individual tiles delivered by a TMS service
|
||||
*/
|
||||
readonly "tile-size"?: number
|
||||
/**
|
||||
* Whether tiles status can be accessed by appending /status to the tile URL and can be submitted for re-rendering by appending /dirty.
|
||||
*/
|
||||
readonly "mod-tile-features"?: string
|
||||
/**
|
||||
* HTTP headers to be sent to server. It has two attributes header-name and header-value. May be specified multiple times.
|
||||
*/
|
||||
readonly "custom-http-headers"?: {
|
||||
readonly "header-name"?: string
|
||||
readonly "header-value"?: string
|
||||
}
|
||||
/**
|
||||
* Default layer to open (when using WMS_ENDPOINT type). Contains list of layer tag with two attributes - name and style, e.g. `"default-layers": ["layer": { name="Basisdata_NP_Basiskart_JanMayen_WMTS_25829" "style":"default" } ]` (not allowed in `mirror` attribute)
|
||||
*/
|
||||
readonly "default-layers"?: {
|
||||
layer?: {
|
||||
"layer-name"?: string
|
||||
"layer-style"?: string
|
||||
[k: string]: unknown
|
||||
}
|
||||
[k: string]: unknown
|
||||
}[]
|
||||
/**
|
||||
* format to use when connecting tile server (when using WMS_ENDPOINT type)
|
||||
*/
|
||||
readonly format?: string
|
||||
/**
|
||||
* If `true` transparent tiles will be requested from WMS server
|
||||
*/
|
||||
readonly transparent?: boolean & string
|
||||
/**
|
||||
* minimum expiry time for tiles in seconds. The larger the value, the longer entry in cache will be considered valid
|
||||
*/
|
||||
readonly "minimum-tile-expire"?: number
|
||||
}
|
|
@ -11,7 +11,6 @@ import { BBox } from "../../Logic/BBox"
|
|||
import "leaflet-polylineoffset"
|
||||
import { SimpleMapScreenshoter } from "leaflet-simple-map-screenshoter"
|
||||
import BackgroundMapSwitch from "../BigComponents/BackgroundMapSwitch"
|
||||
import AvailableBaseLayersImplementation from "../../Logic/Actors/AvailableBaseLayersImplementation"
|
||||
import ShowDataLayer from "../ShowDataLayer/ShowDataLayer"
|
||||
import ShowDataLayerImplementation from "../ShowDataLayer/ShowDataLayerImplementation"
|
||||
import FilteredLayer from "../../Models/FilteredLayer"
|
||||
|
@ -127,7 +126,6 @@ export default class MinimapImplementation extends BaseUIElement implements Mini
|
|||
}
|
||||
|
||||
public static initialize() {
|
||||
AvailableBaseLayers.implement(new AvailableBaseLayersImplementation())
|
||||
Minimap.createMiniMap = (options) => new MinimapImplementation(options)
|
||||
ShowDataLayer.actualContstructor = (options) => new ShowDataLayerImplementation(options)
|
||||
StrayClickHandler.construct = (
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
import { DropDown } from "../Input/DropDown"
|
||||
import Translations from "../i18n/Translations"
|
||||
import State from "../../State"
|
||||
import BaseLayer from "../../Models/BaseLayer"
|
||||
import { VariableUiElement } from "../Base/VariableUIElement"
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
|
||||
export default class BackgroundSelector extends VariableUiElement {
|
||||
constructor(state: { availableBackgroundLayers?: Store<BaseLayer[]> }) {
|
||||
const available = state.availableBackgroundLayers?.map((available) => {
|
||||
if (available === undefined) {
|
||||
return undefined
|
||||
}
|
||||
const baseLayers: { value: BaseLayer; shown: string }[] = []
|
||||
for (const i in available) {
|
||||
if (!available.hasOwnProperty(i)) {
|
||||
continue
|
||||
}
|
||||
const layer: BaseLayer = available[i]
|
||||
baseLayers.push({ value: layer, shown: layer.name ?? "id:" + layer.id })
|
||||
}
|
||||
return baseLayers
|
||||
})
|
||||
|
||||
super(
|
||||
available?.map((baseLayers) => {
|
||||
if (baseLayers === undefined || baseLayers.length <= 1) {
|
||||
return undefined
|
||||
}
|
||||
return new DropDown(
|
||||
Translations.t.general.backgroundMap.Clone(),
|
||||
baseLayers,
|
||||
State.state.backgroundLayer,
|
||||
{
|
||||
select_class: "bg-indigo-100 p-1 rounded hover:bg-indigo-200 w-full",
|
||||
}
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
172
UI/Map/MapLibreAdaptor.ts
Normal file
172
UI/Map/MapLibreAdaptor.ts
Normal file
|
@ -0,0 +1,172 @@
|
|||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import type { Map as MLMap } from "maplibre-gl"
|
||||
import {
|
||||
EditorLayerIndexProperties,
|
||||
RasterLayerPolygon,
|
||||
RasterLayerProperties,
|
||||
} from "../../Models/RasterLayers"
|
||||
import { Utils } from "../../Utils"
|
||||
import Loc from "../../Models/Loc"
|
||||
|
||||
export class MapLibreAdaptor {
|
||||
private readonly _maplibreMap: Store<MLMap>
|
||||
private readonly _backgroundLayer?: Store<RasterLayerPolygon>
|
||||
|
||||
private _currentRasterLayer: string = undefined
|
||||
|
||||
constructor(
|
||||
maplibreMap: Store<MLMap>,
|
||||
state?: {
|
||||
// availableBackgroundLayers: Store<BaseLayer[]>
|
||||
/**
|
||||
* The current background layer
|
||||
*/
|
||||
readonly backgroundLayer?: Store<RasterLayerPolygon>
|
||||
readonly locationControl?: UIEventSource<Loc>
|
||||
}
|
||||
) {
|
||||
this._maplibreMap = maplibreMap
|
||||
this._backgroundLayer = state.backgroundLayer
|
||||
|
||||
const self = this
|
||||
this._backgroundLayer?.addCallback((_) => self.setBackground())
|
||||
|
||||
maplibreMap.addCallbackAndRunD((map) => {
|
||||
map.on("load", () => {
|
||||
self.setBackground()
|
||||
})
|
||||
if (state.locationControl) {
|
||||
self.MoveMapToCurrentLoc(state.locationControl.data)
|
||||
map.on("moveend", () => {
|
||||
const dt = state.locationControl.data
|
||||
dt.lon = map.getCenter().lng
|
||||
dt.lat = map.getCenter().lat
|
||||
dt.zoom = map.getZoom()
|
||||
state.locationControl.ping()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
state.locationControl.addCallbackAndRunD((loc) => {
|
||||
self.MoveMapToCurrentLoc(loc)
|
||||
})
|
||||
}
|
||||
|
||||
private MoveMapToCurrentLoc(loc: Loc) {
|
||||
const map = this._maplibreMap.data
|
||||
if (map === undefined || loc === undefined) {
|
||||
return
|
||||
}
|
||||
if (map.getZoom() !== loc.zoom) {
|
||||
map.setZoom(loc.zoom)
|
||||
}
|
||||
const center = map.getCenter()
|
||||
if (center.lng !== loc.lon || center.lat !== loc.lat) {
|
||||
map.setCenter({ lng: loc.lon, lat: loc.lat })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares an ELI-URL to be compatible with mapbox
|
||||
*/
|
||||
private static prepareWmsURL(url: string, size: number = 256) {
|
||||
// ELI: LAYERS=OGWRGB13_15VL&STYLES=&FORMAT=image/jpeg&CRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}&VERSION=1.3.0&SERVICE=WMS&REQUEST=GetMap
|
||||
// PROD: SERVICE=WMS&REQUEST=GetMap&LAYERS=OGWRGB13_15VL&STYLES=&FORMAT=image/jpeg&TRANSPARENT=false&VERSION=1.3.0&WIDTH=256&HEIGHT=256&CRS=EPSG:3857&BBOX=488585.4847988467,6590094.830634755,489196.9810251281,6590706.32686104
|
||||
|
||||
const toReplace = {
|
||||
"{bbox}": "{bbox-epsg-3857}",
|
||||
"{proj}": "EPSG:3857",
|
||||
"{width}": "" + size,
|
||||
"{height}": "" + size,
|
||||
"{zoom}": "{z}",
|
||||
}
|
||||
|
||||
for (const key in toReplace) {
|
||||
url = url.replace(new RegExp(key), toReplace[key])
|
||||
}
|
||||
|
||||
const subdomains = url.match(/\{switch:([a-zA-Z0-9,]*)}/)
|
||||
if (subdomains !== null) {
|
||||
console.log("Found a switch:", subdomains)
|
||||
const options = subdomains[1].split(",")
|
||||
const option = options[Math.floor(Math.random() * options.length)]
|
||||
url = url.replace(subdomains[0], option)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
private async awaitStyleIsLoaded(): Promise<void> {
|
||||
const map = this._maplibreMap.data
|
||||
if (map === undefined) {
|
||||
return
|
||||
}
|
||||
while (!map.isStyleLoaded()) {
|
||||
await Utils.waitFor(250)
|
||||
}
|
||||
}
|
||||
|
||||
private removeCurrentLayer(map: MLMap) {
|
||||
if (this._currentRasterLayer) {
|
||||
// hide the previous layer
|
||||
console.log("Removing previous layer", this._currentRasterLayer)
|
||||
map.removeLayer(this._currentRasterLayer)
|
||||
map.removeSource(this._currentRasterLayer)
|
||||
}
|
||||
}
|
||||
|
||||
private async setBackground() {
|
||||
const map = this._maplibreMap.data
|
||||
if (map === undefined) {
|
||||
return
|
||||
}
|
||||
const background: RasterLayerProperties = this._backgroundLayer?.data?.properties
|
||||
if (background !== undefined && this._currentRasterLayer === background.id) {
|
||||
// already the correct background layer, nothing to do
|
||||
return
|
||||
}
|
||||
await this.awaitStyleIsLoaded()
|
||||
|
||||
if (background !== this._backgroundLayer?.data?.properties) {
|
||||
// User selected another background in the meantime... abort
|
||||
return
|
||||
}
|
||||
|
||||
if (background !== undefined && this._currentRasterLayer === background.id) {
|
||||
// already the correct background layer, nothing to do
|
||||
return
|
||||
}
|
||||
if (background === undefined) {
|
||||
// no background to set
|
||||
this.removeCurrentLayer(map)
|
||||
this._currentRasterLayer = undefined
|
||||
return
|
||||
}
|
||||
|
||||
map.addSource(background.id, {
|
||||
type: "raster",
|
||||
// use the tiles option to specify a 256WMS tile source URL
|
||||
// https://maplibre.org/maplibre-gl-js-docs/style-spec/sources/
|
||||
tiles: [MapLibreAdaptor.prepareWmsURL(background.url, background["tile-size"] ?? 256)],
|
||||
tileSize: background["tile-size"] ?? 256,
|
||||
minzoom: background["min_zoom"] ?? 1,
|
||||
maxzoom: background["max_zoom"] ?? 25,
|
||||
// scheme: background["type"] === "tms" ? "tms" : "xyz",
|
||||
})
|
||||
|
||||
map.addLayer(
|
||||
{
|
||||
id: background.id,
|
||||
type: "raster",
|
||||
source: background.id,
|
||||
paint: {},
|
||||
},
|
||||
background.category === "osmbasedmap" || background.category === "map"
|
||||
? undefined
|
||||
: "aeroway_fill"
|
||||
)
|
||||
await this.awaitStyleIsLoaded()
|
||||
this.removeCurrentLayer(map)
|
||||
this._currentRasterLayer = background?.id
|
||||
}
|
||||
}
|
43
UI/Map/MaplibreMap.svelte
Normal file
43
UI/Map/MaplibreMap.svelte
Normal file
|
@ -0,0 +1,43 @@
|
|||
<script lang="ts">
|
||||
/**
|
||||
* The 'MaplibreMap' maps various event sources onto MapLibre.
|
||||
*
|
||||
* 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 type Loc from "../../Models/Loc";
|
||||
import { UIEventSource } from "../../Logic/UIEventSource";
|
||||
|
||||
|
||||
/**
|
||||
* 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>
|
||||
|
||||
let center = {};
|
||||
|
||||
onMount(() => {
|
||||
$map.on("load", function() {
|
||||
$map.resize();
|
||||
});
|
||||
});
|
||||
const styleUrl = "https://api.maptiler.com/maps/streets/style.json?key=GvoVAJgu46I5rZapJuAy";
|
||||
</script>
|
||||
<main>
|
||||
<Map bind:center={center}
|
||||
bind:map={$map}
|
||||
controls="true"
|
||||
id="map" location={{lng: 0, lat: 0, zoom: 0}} maxzoom=24 style={styleUrl} />
|
||||
</main>
|
||||
|
||||
<style>
|
||||
main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
18
UI/Map/RasterLayerPicker.svelte
Normal file
18
UI/Map/RasterLayerPicker.svelte
Normal file
|
@ -0,0 +1,18 @@
|
|||
<script lang="ts">
|
||||
import type { Readable, Writable } from "svelte/store";
|
||||
import type { RasterLayerPolygon } from "../../Models/RasterLayers";
|
||||
|
||||
/***
|
||||
* Chooses a background-layer out of available options
|
||||
*/
|
||||
export let availableLayers: Readable<RasterLayerPolygon[]>
|
||||
export let value: Writable<RasterLayerPolygon>
|
||||
</script>
|
||||
|
||||
<select bind:value={$value}>
|
||||
{#each $availableLayers as availableLayer }
|
||||
<option value={availableLayer}>
|
||||
{availableLayer.properties.name}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
97
assets/global-raster-layers.json
Normal file
97
assets/global-raster-layers.json
Normal file
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
"layers": [
|
||||
{
|
||||
"id": "Stamen.TonerLite",
|
||||
"name": "Toner Lite (by Stamen)",
|
||||
"url": "https://stamen-tiles-{switch:a,b,c,d}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.png",
|
||||
"category": "osmbasedmap",
|
||||
"attribution": {
|
||||
"html": "Map tiles by <a href=\"http://stamen.com\">Stamen Design</a>, <a href=\"http://creativecommons.org/licenses/by/3.0\">CC BY 3.0</a> — Map data {attribution.OpenStreetMap}"
|
||||
},
|
||||
"min_zoom": 0,
|
||||
"max_zoom": 20
|
||||
},
|
||||
{
|
||||
"id": "Stamen.TonerBackground",
|
||||
"name": "Toner Background - no labels (by Stamen)",
|
||||
"category": "osmbasedmap",
|
||||
"url": "https://stamen-tiles-{switch:a,b,c,d}.a.ssl.fastly.net/toner-background/{z}/{x}/{y}.png",
|
||||
"attribution": {
|
||||
"html": "Map tiles by <a href=\"http://stamen.com\">Stamen Design</a>, <a href=\"http://creativecommons.org/licenses/by/3.0\">CC BY 3.0</a> — Map data {attribution.OpenStreetMap}"
|
||||
},
|
||||
"min_zoom": 0,
|
||||
"max_zoom": 20
|
||||
},
|
||||
{
|
||||
"id": "Stamen.Watercolor",
|
||||
"name": "Watercolor (by Stamen)",
|
||||
"category": "osmbasedmap",
|
||||
"url": "https://stamen-tiles-{switch:a,b,c,d}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.png",
|
||||
"attribution": {
|
||||
"html": "Map tiles by <a href=\"http://stamen.com\">Stamen Design</a>, <a href=\"http://creativecommons.org/licenses/by/3.0\">CC BY 3.0</a> — Map data {attribution.OpenStreetMap}"
|
||||
},
|
||||
"min_zoom": 0,
|
||||
"max_zoom": 20
|
||||
},
|
||||
{
|
||||
"id": "CartoDB.Positron",
|
||||
"name": "Positron (by CartoDB)",
|
||||
"url": "https://{switch:a,b,c,d}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png",
|
||||
"attribution": {
|
||||
"html": "<a href=\"https://carto.com/attributions\">CARTO</a>"
|
||||
},
|
||||
"max_zoom": 20,
|
||||
"category": "osmbasedmap"
|
||||
},
|
||||
{
|
||||
"id": "CartoDB.PositronNoLabels",
|
||||
"name": "Positron - no labels (by CartoDB)",
|
||||
"url": "https://{switch:a,b,c,d}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
|
||||
"category": "osmbasedmap",
|
||||
"attribution": {
|
||||
"html": "<a href=\"https://carto.com/attributions\">CARTO</a>"
|
||||
},
|
||||
"max_zoom": 20
|
||||
},
|
||||
{
|
||||
"id": "CartoDB.Voyager",
|
||||
"name": "Voyager (by CartoDB)",
|
||||
"url": "https://{switch:a,b,c,d}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png",
|
||||
"category": "osmbasedmap",
|
||||
"attribution": {
|
||||
"html": "<a href=\"https://carto.com/attributions\">CARTO</a>"
|
||||
},
|
||||
"max_zoom": 20
|
||||
},
|
||||
{
|
||||
"id": "CartoDB.VoyagerNoLabels",
|
||||
"name": "Voyager - no labels (by CartoDB)",
|
||||
"url": "https://{switch:a,b,c,d}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png",
|
||||
"category": "osmbasedmap",
|
||||
"attribution": {
|
||||
"html": "<a href=\"https://carto.com/attributions\">CARTO</a>"
|
||||
},
|
||||
"max_zoom": 20
|
||||
},
|
||||
{
|
||||
"id": "CartoDB.DarkMatter",
|
||||
"name": "Dark Matter (by CartoDB)",
|
||||
"url": "https://{switch:a,b,c,d}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
|
||||
"category": "osmbasedmap",
|
||||
"attribution": {
|
||||
"html": "<a href=\"https://carto.com/attributions\">CARTO</a>"
|
||||
},
|
||||
"max_zoom": 20
|
||||
},
|
||||
{
|
||||
"id": "CartoDB.DarkMatterNoLabels",
|
||||
"name": "Dark Matter - no labels (by CartoDB)",
|
||||
"url": "https://{switch:a,b,c,d}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
|
||||
"category": "osmbasedmap",
|
||||
"attribution": {
|
||||
"html": "<a href=\"https://carto.com/attributions\">CARTO</a>"
|
||||
},
|
||||
"max_zoom": 20
|
||||
}
|
||||
]
|
||||
}
|
418
package-lock.json
generated
418
package-lock.json
generated
|
@ -9,6 +9,7 @@
|
|||
"version": "0.25.1",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@onsvisual/svelte-maps": "^1.1.6",
|
||||
"@rollup/plugin-typescript": "^11.0.0",
|
||||
"@turf/boolean-intersects": "^6.5.0",
|
||||
"@turf/buffer": "^6.5.0",
|
||||
|
@ -37,6 +38,7 @@
|
|||
"libphonenumber-js": "^1.10.8",
|
||||
"lz-string": "^1.4.4",
|
||||
"mangrove-reviews-typescript": "^1.1.0",
|
||||
"maplibre-gl": "^2.4.0",
|
||||
"opening_hours": "^3.6.0",
|
||||
"osm-auth": "^1.0.2",
|
||||
"osmtogeojson": "^3.0.0-beta.5",
|
||||
|
@ -1799,6 +1801,24 @@
|
|||
"geojson-rewind": "geojson-rewind"
|
||||
}
|
||||
},
|
||||
"node_modules/@mapbox/jsonlint-lines-primitives": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
|
||||
"integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@mapbox/mapbox-gl-supported": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz",
|
||||
"integrity": "sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ=="
|
||||
},
|
||||
"node_modules/@mapbox/point-geometry": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
|
||||
"integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ=="
|
||||
},
|
||||
"node_modules/@mapbox/sphericalmercator": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/sphericalmercator/-/sphericalmercator-1.2.0.tgz",
|
||||
|
@ -1810,6 +1830,32 @@
|
|||
"xyz": "bin/xyz.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@mapbox/tiny-sdf": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz",
|
||||
"integrity": "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA=="
|
||||
},
|
||||
"node_modules/@mapbox/unitbezier": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz",
|
||||
"integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw=="
|
||||
},
|
||||
"node_modules/@mapbox/vector-tile": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz",
|
||||
"integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==",
|
||||
"dependencies": {
|
||||
"@mapbox/point-geometry": "~0.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@mapbox/whoots-js": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz",
|
||||
"integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
|
@ -1842,6 +1888,16 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@onsvisual/svelte-maps": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@onsvisual/svelte-maps/-/svelte-maps-1.1.6.tgz",
|
||||
"integrity": "sha512-qrt/Z7SvOLzPdz+q3vL6VEVQp3ayavmPE7Rqbtbhicq3JFx/l/1W2VS8ryHgFGXi5nuuZtAzxW7/p8ZM0L/VOw==",
|
||||
"peerDependencies": {
|
||||
"maplibre-gl": "^2.4.0",
|
||||
"pmtiles": "^2.7.0",
|
||||
"svelte": "^3.32.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/service-worker": {
|
||||
"version": "2.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/service-worker/-/service-worker-2.8.2.tgz",
|
||||
|
@ -3572,8 +3628,7 @@
|
|||
"node_modules/@types/geojson": {
|
||||
"version": "7946.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
|
||||
"integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==",
|
||||
"devOptional": true
|
||||
"integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA=="
|
||||
},
|
||||
"node_modules/@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.4",
|
||||
|
@ -3642,6 +3697,21 @@
|
|||
"integrity": "sha512-j6G1e8DULJx3ONf6NdR5JiR2ZY3K3PaaqiEuKYkLQO0Czfi1AzrtjfnfCROyWGeDd5IVMKCwsgSmMip9OWijow==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/mapbox__point-geometry": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.2.tgz",
|
||||
"integrity": "sha512-D0lgCq+3VWV85ey1MZVkE8ZveyuvW5VAfuahVTQRpXFQTxw03SuIf1/K4UQ87MMIXVKzpFjXFiFMZzLj2kU+iA=="
|
||||
},
|
||||
"node_modules/@types/mapbox__vector-tile": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.0.tgz",
|
||||
"integrity": "sha512-kDwVreQO5V4c8yAxzZVQLE5tyWF+IPToAanloQaSnwfXmIcJ7cyOrv8z4Ft4y7PsLYmhWXmON8MBV8RX0Rgr8g==",
|
||||
"dependencies": {
|
||||
"@types/geojson": "*",
|
||||
"@types/mapbox__point-geometry": "*",
|
||||
"@types/pbf": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.11.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
|
||||
|
@ -3656,6 +3726,11 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/pbf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.2.tgz",
|
||||
"integrity": "sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ=="
|
||||
},
|
||||
"node_modules/@types/prompt-sync": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/prompt-sync/-/prompt-sync-4.2.0.tgz",
|
||||
|
@ -4811,6 +4886,11 @@
|
|||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/csscolorparser": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
|
||||
"integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w=="
|
||||
},
|
||||
"node_modules/cssesc": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||
|
@ -5975,6 +6055,11 @@
|
|||
"quickselect": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/geojson-vt": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz",
|
||||
"integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg=="
|
||||
},
|
||||
"node_modules/geojson2svg": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/geojson2svg/-/geojson2svg-1.3.3.tgz",
|
||||
|
@ -6037,6 +6122,11 @@
|
|||
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/gl-matrix": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz",
|
||||
"integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
|
@ -6076,6 +6166,30 @@
|
|||
"process": "^0.11.10"
|
||||
}
|
||||
},
|
||||
"node_modules/global-prefix": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
|
||||
"integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
|
||||
"dependencies": {
|
||||
"ini": "^1.3.5",
|
||||
"kind-of": "^6.0.2",
|
||||
"which": "^1.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/global-prefix/node_modules/which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"which": "bin/which"
|
||||
}
|
||||
},
|
||||
"node_modules/globals": {
|
||||
"version": "11.12.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||
|
@ -6487,8 +6601,7 @@
|
|||
"node_modules/ini": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
||||
"dev": true
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
|
||||
},
|
||||
"node_modules/inquirer": {
|
||||
"version": "8.2.0",
|
||||
|
@ -7144,6 +7257,14 @@
|
|||
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-1.0.1.tgz",
|
||||
"integrity": "sha512-Y75c18KdvLKRmqHc0u2WUYud1vEj54i+8SNBxsowr6LJJsnNUJ8KK8cH7uHDpC5U66NNlieEzVxeWipZaYfN0w=="
|
||||
},
|
||||
"node_modules/kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/kleur": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
|
||||
|
@ -7382,6 +7503,43 @@
|
|||
"typescript": "^4.9.4"
|
||||
}
|
||||
},
|
||||
"node_modules/maplibre-gl": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-2.4.0.tgz",
|
||||
"integrity": "sha512-csNFylzntPmHWidczfgCZpvbTSmhaWvLRj9e1ezUDBEPizGgshgm3ea1T5TCNEEBq0roauu7BPuRZjA3wO4KqA==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@mapbox/geojson-rewind": "^0.5.2",
|
||||
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
|
||||
"@mapbox/mapbox-gl-supported": "^2.0.1",
|
||||
"@mapbox/point-geometry": "^0.1.0",
|
||||
"@mapbox/tiny-sdf": "^2.0.5",
|
||||
"@mapbox/unitbezier": "^0.0.1",
|
||||
"@mapbox/vector-tile": "^1.3.1",
|
||||
"@mapbox/whoots-js": "^3.1.0",
|
||||
"@types/geojson": "^7946.0.10",
|
||||
"@types/mapbox__point-geometry": "^0.1.2",
|
||||
"@types/mapbox__vector-tile": "^1.3.0",
|
||||
"@types/pbf": "^3.0.2",
|
||||
"csscolorparser": "~1.0.3",
|
||||
"earcut": "^2.2.4",
|
||||
"geojson-vt": "^3.2.1",
|
||||
"gl-matrix": "^3.4.3",
|
||||
"global-prefix": "^3.0.0",
|
||||
"murmurhash-js": "^1.0.0",
|
||||
"pbf": "^3.2.1",
|
||||
"potpack": "^1.0.2",
|
||||
"quickselect": "^2.0.0",
|
||||
"supercluster": "^7.1.5",
|
||||
"tinyqueue": "^2.0.3",
|
||||
"vt-pbf": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/maplibre-gl/node_modules/quickselect": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
|
||||
"integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
|
||||
},
|
||||
"node_modules/merge2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
|
@ -7667,6 +7825,11 @@
|
|||
"resolved": "https://registry.npmjs.org/multigeojson/-/multigeojson-0.0.1.tgz",
|
||||
"integrity": "sha512-FbCR4K9xp+0lbcHmJk1TLjXW+l82VcEhDDIU7g3DWm47WyGSpuGX8lJx58pOPa61T0b1zQUJVjllPJ6eXe54lg=="
|
||||
},
|
||||
"node_modules/murmurhash-js": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz",
|
||||
"integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw=="
|
||||
},
|
||||
"node_modules/mute-stream": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
|
||||
|
@ -8195,6 +8358,21 @@
|
|||
"pathe": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pmtiles": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pmtiles/-/pmtiles-2.7.0.tgz",
|
||||
"integrity": "sha512-/0WERHBKCt9P8dlQaROQd1CE/J1sqYhdGkDgOROaxCjnpm/U+guWNNxZPPduUy6Wu7wQtPghA7sS4t0T18FKAA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fflate": "^0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/pmtiles/node_modules/fflate": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz",
|
||||
"integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/point-in-polygon": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/point-in-polygon/-/point-in-polygon-1.1.0.tgz",
|
||||
|
@ -8220,6 +8398,11 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/potpack": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz",
|
||||
"integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="
|
||||
},
|
||||
"node_modules/prebuild-install": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
|
||||
|
@ -9466,6 +9649,19 @@
|
|||
"resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.9.0.tgz",
|
||||
"integrity": "sha512-vMJ8Byp1uIPoj+wb9c1AdK4jpkSKVAywgHX0lqY7zt6+EWRRC3Z+0Ucfjy/0yxTVO1hwwchZe4uoFNqrIC24+A=="
|
||||
},
|
||||
"node_modules/supercluster": {
|
||||
"version": "7.1.5",
|
||||
"resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.5.tgz",
|
||||
"integrity": "sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg==",
|
||||
"dependencies": {
|
||||
"kdbush": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/supercluster/node_modules/kdbush": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz",
|
||||
"integrity": "sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew=="
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
|
@ -9493,7 +9689,6 @@
|
|||
"version": "3.55.1",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.55.1.tgz",
|
||||
"integrity": "sha512-S+87/P0Ve67HxKkEV23iCdAh/SX1xiSfjF1HOglno/YTbSTW7RniICMCofWGdJJbdjw3S+0PfFb1JtGfTXE0oQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
|
@ -11446,6 +11641,16 @@
|
|||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vt-pbf": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz",
|
||||
"integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==",
|
||||
"dependencies": {
|
||||
"@mapbox/point-geometry": "0.1.0",
|
||||
"@mapbox/vector-tile": "^1.3.1",
|
||||
"pbf": "^3.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/w3c-xmlserializer": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
|
||||
|
@ -13036,11 +13241,49 @@
|
|||
"minimist": "^1.2.6"
|
||||
}
|
||||
},
|
||||
"@mapbox/jsonlint-lines-primitives": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
|
||||
"integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ=="
|
||||
},
|
||||
"@mapbox/mapbox-gl-supported": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz",
|
||||
"integrity": "sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ=="
|
||||
},
|
||||
"@mapbox/point-geometry": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
|
||||
"integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ=="
|
||||
},
|
||||
"@mapbox/sphericalmercator": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/sphericalmercator/-/sphericalmercator-1.2.0.tgz",
|
||||
"integrity": "sha512-ZTOuuwGuMOJN+HEmG/68bSEw15HHaMWmQ5gdTsWdWsjDe56K1kGvLOK6bOSC8gWgIvEO0w6un/2Gvv1q5hJSkQ=="
|
||||
},
|
||||
"@mapbox/tiny-sdf": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz",
|
||||
"integrity": "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA=="
|
||||
},
|
||||
"@mapbox/unitbezier": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz",
|
||||
"integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw=="
|
||||
},
|
||||
"@mapbox/vector-tile": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz",
|
||||
"integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==",
|
||||
"requires": {
|
||||
"@mapbox/point-geometry": "~0.1.0"
|
||||
}
|
||||
},
|
||||
"@mapbox/whoots-js": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz",
|
||||
"integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q=="
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
|
@ -13064,6 +13307,12 @@
|
|||
"fastq": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"@onsvisual/svelte-maps": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@onsvisual/svelte-maps/-/svelte-maps-1.1.6.tgz",
|
||||
"integrity": "sha512-qrt/Z7SvOLzPdz+q3vL6VEVQp3ayavmPE7Rqbtbhicq3JFx/l/1W2VS8ryHgFGXi5nuuZtAzxW7/p8ZM0L/VOw==",
|
||||
"requires": {}
|
||||
},
|
||||
"@parcel/service-worker": {
|
||||
"version": "2.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/service-worker/-/service-worker-2.8.2.tgz",
|
||||
|
@ -14417,8 +14666,7 @@
|
|||
"@types/geojson": {
|
||||
"version": "7946.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
|
||||
"integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==",
|
||||
"devOptional": true
|
||||
"integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA=="
|
||||
},
|
||||
"@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.4",
|
||||
|
@ -14486,6 +14734,21 @@
|
|||
"integrity": "sha512-j6G1e8DULJx3ONf6NdR5JiR2ZY3K3PaaqiEuKYkLQO0Czfi1AzrtjfnfCROyWGeDd5IVMKCwsgSmMip9OWijow==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/mapbox__point-geometry": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.2.tgz",
|
||||
"integrity": "sha512-D0lgCq+3VWV85ey1MZVkE8ZveyuvW5VAfuahVTQRpXFQTxw03SuIf1/K4UQ87MMIXVKzpFjXFiFMZzLj2kU+iA=="
|
||||
},
|
||||
"@types/mapbox__vector-tile": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.0.tgz",
|
||||
"integrity": "sha512-kDwVreQO5V4c8yAxzZVQLE5tyWF+IPToAanloQaSnwfXmIcJ7cyOrv8z4Ft4y7PsLYmhWXmON8MBV8RX0Rgr8g==",
|
||||
"requires": {
|
||||
"@types/geojson": "*",
|
||||
"@types/mapbox__point-geometry": "*",
|
||||
"@types/pbf": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "18.11.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
|
||||
|
@ -14500,6 +14763,11 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/pbf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.2.tgz",
|
||||
"integrity": "sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ=="
|
||||
},
|
||||
"@types/prompt-sync": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/prompt-sync/-/prompt-sync-4.2.0.tgz",
|
||||
|
@ -15382,6 +15650,11 @@
|
|||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"csscolorparser": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
|
||||
"integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w=="
|
||||
},
|
||||
"cssesc": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||
|
@ -16288,6 +16561,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"geojson-vt": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz",
|
||||
"integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg=="
|
||||
},
|
||||
"geojson2svg": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/geojson2svg/-/geojson2svg-1.3.3.tgz",
|
||||
|
@ -16335,6 +16613,11 @@
|
|||
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
|
||||
"dev": true
|
||||
},
|
||||
"gl-matrix": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz",
|
||||
"integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
|
@ -16365,6 +16648,26 @@
|
|||
"process": "^0.11.10"
|
||||
}
|
||||
},
|
||||
"global-prefix": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
|
||||
"integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
|
||||
"requires": {
|
||||
"ini": "^1.3.5",
|
||||
"kind-of": "^6.0.2",
|
||||
"which": "^1.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
"version": "11.12.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||
|
@ -16668,8 +16971,7 @@
|
|||
"ini": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
||||
"dev": true
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
|
||||
},
|
||||
"inquirer": {
|
||||
"version": "8.2.0",
|
||||
|
@ -17149,6 +17451,11 @@
|
|||
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-1.0.1.tgz",
|
||||
"integrity": "sha512-Y75c18KdvLKRmqHc0u2WUYud1vEj54i+8SNBxsowr6LJJsnNUJ8KK8cH7uHDpC5U66NNlieEzVxeWipZaYfN0w=="
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
|
||||
},
|
||||
"kleur": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
|
||||
|
@ -17335,6 +17642,44 @@
|
|||
"typescript": "^4.9.4"
|
||||
}
|
||||
},
|
||||
"maplibre-gl": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-2.4.0.tgz",
|
||||
"integrity": "sha512-csNFylzntPmHWidczfgCZpvbTSmhaWvLRj9e1ezUDBEPizGgshgm3ea1T5TCNEEBq0roauu7BPuRZjA3wO4KqA==",
|
||||
"requires": {
|
||||
"@mapbox/geojson-rewind": "^0.5.2",
|
||||
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
|
||||
"@mapbox/mapbox-gl-supported": "^2.0.1",
|
||||
"@mapbox/point-geometry": "^0.1.0",
|
||||
"@mapbox/tiny-sdf": "^2.0.5",
|
||||
"@mapbox/unitbezier": "^0.0.1",
|
||||
"@mapbox/vector-tile": "^1.3.1",
|
||||
"@mapbox/whoots-js": "^3.1.0",
|
||||
"@types/geojson": "^7946.0.10",
|
||||
"@types/mapbox__point-geometry": "^0.1.2",
|
||||
"@types/mapbox__vector-tile": "^1.3.0",
|
||||
"@types/pbf": "^3.0.2",
|
||||
"csscolorparser": "~1.0.3",
|
||||
"earcut": "^2.2.4",
|
||||
"geojson-vt": "^3.2.1",
|
||||
"gl-matrix": "^3.4.3",
|
||||
"global-prefix": "^3.0.0",
|
||||
"murmurhash-js": "^1.0.0",
|
||||
"pbf": "^3.2.1",
|
||||
"potpack": "^1.0.2",
|
||||
"quickselect": "^2.0.0",
|
||||
"supercluster": "^7.1.5",
|
||||
"tinyqueue": "^2.0.3",
|
||||
"vt-pbf": "^3.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"quickselect": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
|
||||
"integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"merge2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
|
@ -17547,6 +17892,11 @@
|
|||
"resolved": "https://registry.npmjs.org/multigeojson/-/multigeojson-0.0.1.tgz",
|
||||
"integrity": "sha512-FbCR4K9xp+0lbcHmJk1TLjXW+l82VcEhDDIU7g3DWm47WyGSpuGX8lJx58pOPa61T0b1zQUJVjllPJ6eXe54lg=="
|
||||
},
|
||||
"murmurhash-js": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz",
|
||||
"integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw=="
|
||||
},
|
||||
"mute-stream": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
|
||||
|
@ -17945,6 +18295,23 @@
|
|||
"pathe": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"pmtiles": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pmtiles/-/pmtiles-2.7.0.tgz",
|
||||
"integrity": "sha512-/0WERHBKCt9P8dlQaROQd1CE/J1sqYhdGkDgOROaxCjnpm/U+guWNNxZPPduUy6Wu7wQtPghA7sS4t0T18FKAA==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"fflate": "^0.7.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"fflate": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz",
|
||||
"integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==",
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"point-in-polygon": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/point-in-polygon/-/point-in-polygon-1.1.0.tgz",
|
||||
|
@ -17967,6 +18334,11 @@
|
|||
"util-deprecate": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"potpack": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz",
|
||||
"integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="
|
||||
},
|
||||
"prebuild-install": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
|
||||
|
@ -18902,6 +19274,21 @@
|
|||
"resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.9.0.tgz",
|
||||
"integrity": "sha512-vMJ8Byp1uIPoj+wb9c1AdK4jpkSKVAywgHX0lqY7zt6+EWRRC3Z+0Ucfjy/0yxTVO1hwwchZe4uoFNqrIC24+A=="
|
||||
},
|
||||
"supercluster": {
|
||||
"version": "7.1.5",
|
||||
"resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.5.tgz",
|
||||
"integrity": "sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg==",
|
||||
"requires": {
|
||||
"kdbush": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"kdbush": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz",
|
||||
"integrity": "sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
|
@ -18919,8 +19306,7 @@
|
|||
"svelte": {
|
||||
"version": "3.55.1",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.55.1.tgz",
|
||||
"integrity": "sha512-S+87/P0Ve67HxKkEV23iCdAh/SX1xiSfjF1HOglno/YTbSTW7RniICMCofWGdJJbdjw3S+0PfFb1JtGfTXE0oQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-S+87/P0Ve67HxKkEV23iCdAh/SX1xiSfjF1HOglno/YTbSTW7RniICMCofWGdJJbdjw3S+0PfFb1JtGfTXE0oQ=="
|
||||
},
|
||||
"svelte-check": {
|
||||
"version": "3.0.3",
|
||||
|
@ -20360,6 +20746,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"vt-pbf": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz",
|
||||
"integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==",
|
||||
"requires": {
|
||||
"@mapbox/point-geometry": "0.1.0",
|
||||
"@mapbox/vector-tile": "^1.3.1",
|
||||
"pbf": "^3.2.1"
|
||||
}
|
||||
},
|
||||
"w3c-xmlserializer": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
"not op_mini all"
|
||||
],
|
||||
"dependencies": {
|
||||
"@onsvisual/svelte-maps": "^1.1.6",
|
||||
"@rollup/plugin-typescript": "^11.0.0",
|
||||
"@turf/boolean-intersects": "^6.5.0",
|
||||
"@turf/buffer": "^6.5.0",
|
||||
|
@ -89,6 +90,7 @@
|
|||
"libphonenumber-js": "^1.10.8",
|
||||
"lz-string": "^1.4.4",
|
||||
"mangrove-reviews-typescript": "^1.1.0",
|
||||
"maplibre-gl": "^2.4.0",
|
||||
"opening_hours": "^3.6.0",
|
||||
"osm-auth": "^1.0.2",
|
||||
"osmtogeojson": "^3.0.0-beta.5",
|
||||
|
|
81
test.ts
81
test.ts
|
@ -1,25 +1,72 @@
|
|||
import ContactLink from "./UI/BigComponents/ContactLink.svelte"
|
||||
import SvelteUIElement from "./UI/Base/SvelteUIElement"
|
||||
import { Utils } from "./Utils"
|
||||
import List from "./UI/Base/List"
|
||||
import MaplibreMap from "./UI/Map/MaplibreMap.svelte"
|
||||
import { Store, Stores, UIEventSource } from "./Logic/UIEventSource"
|
||||
import { MapLibreAdaptor } from "./UI/Map/MapLibreAdaptor"
|
||||
import {
|
||||
EditorLayerIndexProperties,
|
||||
RasterLayerPolygon,
|
||||
RasterLayerProperties,
|
||||
} from "./Models/RasterLayers"
|
||||
import type { Map as MlMap } from "maplibre-gl"
|
||||
import { AvailableRasterLayers } from "./Models/RasterLayers"
|
||||
import Loc from "./Models/Loc"
|
||||
import { BBox } from "./Logic/BBox"
|
||||
import { GeoOperations } from "./Logic/GeoOperations"
|
||||
import { Tiles } from "./Models/TileRange"
|
||||
import { Stores } from "./Logic/UIEventSource"
|
||||
import RasterLayerPicker from "./UI/Map/RasterLayerPicker.svelte"
|
||||
import BackgroundLayerResetter from "./Logic/Actors/BackgroundLayerResetter"
|
||||
|
||||
async function main() {
|
||||
const location: [number, number] = [3.21, 51.2]
|
||||
const t = Tiles.embedded_tile(location[1], location[0], 6)
|
||||
const url = `https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/community_index/tile_${t.z}_${t.x}_${t.y}.geojson`
|
||||
const be = Stores.FromPromise(Utils.downloadJson(url)).mapD(
|
||||
(data) => data.features.find((f) => GeoOperations.inside(location, f)).properties
|
||||
const mlmap = new UIEventSource<MlMap>(undefined)
|
||||
const locationControl = new UIEventSource<Loc>({
|
||||
zoom: 14,
|
||||
lat: 51.1,
|
||||
lon: 3.1,
|
||||
})
|
||||
new SvelteUIElement(MaplibreMap, {
|
||||
map: mlmap,
|
||||
})
|
||||
.SetClass("border border-black")
|
||||
.SetStyle("height: 50vh; width: 90%; margin: 1%")
|
||||
.AttachTo("maindiv")
|
||||
const bg = new UIEventSource<RasterLayerPolygon>(undefined)
|
||||
new MapLibreAdaptor(mlmap, {
|
||||
backgroundLayer: bg,
|
||||
locationControl,
|
||||
})
|
||||
|
||||
const availableLayersBboxes = Stores.ListStabilized(
|
||||
locationControl.mapD((loc) => {
|
||||
const lonlat: [number, number] = [loc.lon, loc.lat]
|
||||
return AvailableRasterLayers.EditorLayerIndex.filter((eliPolygon) =>
|
||||
BBox.get(eliPolygon).contains(lonlat)
|
||||
)
|
||||
})
|
||||
)
|
||||
new SvelteUIElement(ContactLink, { country: be }).AttachTo("maindiv")
|
||||
/*
|
||||
const links = data.features
|
||||
.filter((f) => GeoOperations.inside(location, f))
|
||||
.map((f) => new SvelteUIElement(ContactLink, { country: f.properties }))
|
||||
new List(links).AttachTo("maindiv")
|
||||
//*/
|
||||
const availableLayers: Store<RasterLayerPolygon[]> = Stores.ListStabilized(
|
||||
availableLayersBboxes.map((eliPolygons) => {
|
||||
const loc = locationControl.data
|
||||
const lonlat: [number, number] = [loc.lon, loc.lat]
|
||||
const matching: RasterLayerPolygon[] = eliPolygons.filter((eliPolygon) => {
|
||||
if (eliPolygon.geometry === null) {
|
||||
return true // global ELI-layer
|
||||
}
|
||||
return GeoOperations.inside(lonlat, eliPolygon)
|
||||
})
|
||||
matching.unshift(AvailableRasterLayers.osmCarto)
|
||||
matching.push(...AvailableRasterLayers.globalLayers)
|
||||
return matching
|
||||
})
|
||||
)
|
||||
|
||||
availableLayers.map((a) =>
|
||||
console.log(
|
||||
"Availabe layers at current location:",
|
||||
a.map((al) => al.properties.id)
|
||||
)
|
||||
)
|
||||
|
||||
new BackgroundLayerResetter(bg, availableLayers)
|
||||
new SvelteUIElement(RasterLayerPicker, { availableLayers, value: bg }).AttachTo("extradiv")
|
||||
}
|
||||
|
||||
main().then((_) => {})
|
||||
|
|
Loading…
Reference in a new issue