forked from MapComplete/MapComplete
		
	Performance: lazily download ELI when needed instead of bundling this in the download
This commit is contained in:
		
							parent
							
								
									8c779fe09b
								
							
						
					
					
						commit
						68f8432db7
					
				
					 14 changed files with 257 additions and 183 deletions
				
			
		|  | @ -1,6 +1,6 @@ | |||
| { | ||||
|   "name": "mapcomplete", | ||||
|   "version": "0.45.0", | ||||
|   "version": "0.45.1", | ||||
|   "repository": "https://github.com/pietervdvn/MapComplete", | ||||
|   "description": "A small website to edit OSM easily", | ||||
|   "bugs": "https://github.com/pietervdvn/MapComplete/issues", | ||||
|  |  | |||
|  | @ -99,8 +99,17 @@ class DownloadEli extends Script { | |||
| 
 | ||||
|         const contents = | ||||
|             '{"type":"FeatureCollection",\n  "features": [\n' + | ||||
|             keptLayers.map((l) => JSON.stringify(l)).join(",\n") + | ||||
|             keptLayers.filter(l => l.properties.id !== "Bing").map((l) => JSON.stringify(l)).join(",\n") + | ||||
|             "\n]}" | ||||
| 
 | ||||
|         const bing = keptLayers.find(l => l.properties.id === "Bing") | ||||
|         if(bing){ | ||||
|             const pth = target.replace(/.json$/, ".bing.json") | ||||
|             fs.writeFileSync(pth, JSON.stringify(bing), { encoding: "utf8" }) | ||||
|             console.log("Written", pth) | ||||
|         }else{ | ||||
|             console.log("No bing entry found") | ||||
|         } | ||||
|         fs.writeFileSync(target, contents, { encoding: "utf8" }) | ||||
|         console.log("Written", keptLayers.length + ", entries to the ELI") | ||||
|     } | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import { Store, UIEventSource } from "../UIEventSource" | ||||
| import { Utils } from "../../Utils" | ||||
| import { RasterLayerPolygon, RasterLayerUtils } from "../../Models/RasterLayers" | ||||
| import { AvailableRasterLayers, RasterLayerPolygon, RasterLayerUtils } from "../../Models/RasterLayers" | ||||
| 
 | ||||
| /** | ||||
|  * When a user pans around on the map, they might pan out of the range of the current background raster layer. | ||||
|  | @ -9,12 +9,24 @@ import { RasterLayerPolygon, RasterLayerUtils } from "../../Models/RasterLayers" | |||
| export default class BackgroundLayerResetter { | ||||
|     constructor( | ||||
|         currentBackgroundLayer: UIEventSource<RasterLayerPolygon | undefined>, | ||||
|         availableLayers: Store<RasterLayerPolygon[]> | ||||
|         availableLayers: {store: Store<RasterLayerPolygon[]>} | ||||
|     ) { | ||||
|         if (Utils.runningFromConsole) { | ||||
|             return | ||||
|         } | ||||
| 
 | ||||
|         currentBackgroundLayer.addCallbackAndRunD(l => { | ||||
|             if(l.geometry !== undefined && AvailableRasterLayers.globalLayers.find(global => global.properties.id !== l.properties.id)){ | ||||
|                 BackgroundLayerResetter.installHandler(currentBackgroundLayer, availableLayers.store) | ||||
|                 return true // unregister
 | ||||
|             } | ||||
|         }) | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static installHandler( currentBackgroundLayer: UIEventSource<RasterLayerPolygon | undefined>, | ||||
|                                    availableLayers: Store<RasterLayerPolygon[]> | ||||
|     ){ | ||||
|         // 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
 | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import { Store, UIEventSource } from "../UIEventSource" | ||||
| import { RasterLayerPolygon } from "../../Models/RasterLayers" | ||||
| import { AvailableRasterLayers, RasterLayerPolygon } from "../../Models/RasterLayers" | ||||
| 
 | ||||
| /** | ||||
|  * Selects the appropriate raster layer as background for the given query parameter, theme setting, user preference or default value. | ||||
|  | @ -8,7 +8,7 @@ import { RasterLayerPolygon } from "../../Models/RasterLayers" | |||
|  */ | ||||
| export class PreferredRasterLayerSelector { | ||||
|     private readonly _rasterLayerSetting: UIEventSource<RasterLayerPolygon> | ||||
|     private readonly _availableLayers: Store<RasterLayerPolygon[]> | ||||
|     private readonly _availableLayers: { store: Store<RasterLayerPolygon[]> } | ||||
|     private readonly _preferredBackgroundLayer: UIEventSource< | ||||
|         string | "photo" | "map" | "osmbasedmap" | undefined | ||||
|     > | ||||
|  | @ -16,11 +16,11 @@ export class PreferredRasterLayerSelector { | |||
| 
 | ||||
|     constructor( | ||||
|         rasterLayerSetting: UIEventSource<RasterLayerPolygon>, | ||||
|         availableLayers: Store<RasterLayerPolygon[]>, | ||||
|         availableLayers: { store: Store<RasterLayerPolygon[]> }, | ||||
|         queryParameter: UIEventSource<string>, | ||||
|         preferredBackgroundLayer: UIEventSource< | ||||
|             string | "photo" | "map" | "osmbasedmap" | undefined | ||||
|         > | ||||
|         >, | ||||
|     ) { | ||||
|         this._rasterLayerSetting = rasterLayerSetting | ||||
|         this._availableLayers = availableLayers | ||||
|  | @ -47,7 +47,13 @@ export class PreferredRasterLayerSelector { | |||
| 
 | ||||
|         this._preferredBackgroundLayer.addCallbackD((_) => self.updateLayer()) | ||||
| 
 | ||||
|         this._availableLayers.addCallbackD((_) => self.updateLayer()) | ||||
|         rasterLayerSetting.addCallbackAndRunD(layer => { | ||||
|             if (AvailableRasterLayers.globalLayers.find(l => l.id === layer.properties.id)) { | ||||
|                 return | ||||
|             } | ||||
|             this._availableLayers.store.addCallbackD((_) => self.updateLayer()) | ||||
|             return true // unregister
 | ||||
|         }) | ||||
|         self.updateLayer() | ||||
|     } | ||||
| 
 | ||||
|  | @ -58,9 +64,17 @@ export class PreferredRasterLayerSelector { | |||
|     private updateLayer() { | ||||
|         // What is the ID of the layer we have to (try to) load?
 | ||||
|         const targetLayerId = this._queryParameter.data ?? this._preferredBackgroundLayer.data | ||||
|         const available = this._availableLayers.data | ||||
|         if (targetLayerId === undefined || targetLayerId === "default") { | ||||
|             return | ||||
|         } | ||||
|         const global = AvailableRasterLayers.globalLayers.find(l => l.properties.id === targetLayerId) | ||||
|         if (global) { | ||||
|             this._rasterLayerSetting.setData(global) | ||||
|             return | ||||
|         } | ||||
|         const isCategory = | ||||
|             targetLayerId === "photo" || targetLayerId === "osmbasedmap" || targetLayerId === "map" | ||||
|         const available = this._availableLayers.store.data | ||||
|         const foundLayer = isCategory | ||||
|             ? available.find((l) => l.properties.category === targetLayerId) | ||||
|             : available.find((l) => l.properties.id === targetLayerId) | ||||
|  |  | |||
|  | @ -1,17 +1,33 @@ | |||
| import { Feature, Polygon } from "geojson" | ||||
| import * as editorlayerindex from "../assets/editor-layer-index.json" | ||||
| import * as globallayers from "../assets/global-raster-layers.json" | ||||
| import * as bingJson from "../assets/editor-layer-index.bing.json" | ||||
| 
 | ||||
| import { BBox } from "../Logic/BBox" | ||||
| import { Store, Stores } from "../Logic/UIEventSource" | ||||
| import { Store, Stores, UIEventSource } from "../Logic/UIEventSource" | ||||
| import { GeoOperations } from "../Logic/GeoOperations" | ||||
| import { RasterLayerProperties } from "./RasterLayerProperties" | ||||
| import Constants from "./Constants" | ||||
| import { Utils } from "../Utils" | ||||
| 
 | ||||
| export type EditorLayerIndex = (Feature<Polygon, EditorLayerIndexProperties> & | ||||
|     RasterLayerPolygon)[] | ||||
| 
 | ||||
| export class AvailableRasterLayers { | ||||
|     public static EditorLayerIndex: (Feature<Polygon, EditorLayerIndexProperties> & | ||||
|         RasterLayerPolygon)[] = (<any>editorlayerindex.features).filter( | ||||
|         (l) => l.properties.id !== "Bing" | ||||
|     ) | ||||
|     private static _editorLayerIndex: EditorLayerIndex = undefined | ||||
|     private static _editorLayerIndexStore: UIEventSource<EditorLayerIndex> = new UIEventSource<EditorLayerIndex>(undefined) | ||||
| 
 | ||||
|     public static async editorLayerIndex(): Promise<EditorLayerIndex> { | ||||
|         if(AvailableRasterLayers._editorLayerIndex !== undefined){ | ||||
|             return AvailableRasterLayers._editorLayerIndex | ||||
|         } | ||||
|         console.debug("Downloading ELI") | ||||
|         const eli = await Utils.downloadJson<{ features: EditorLayerIndex }>("./src/assets/editor-layer-index.json") | ||||
|         this._editorLayerIndex = eli.features.filter(l => l.properties.id !== "Bing") | ||||
|         this._editorLayerIndexStore.set(this._editorLayerIndex) | ||||
|         return this._editorLayerIndex | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     public static globalLayers: RasterLayerPolygon[] = globallayers.layers | ||||
|         .filter( | ||||
|             (properties) => | ||||
|  | @ -25,9 +41,7 @@ export class AvailableRasterLayers { | |||
|                     geometry: BBox.global.asGeometry(), | ||||
|                 } | ||||
|         ) | ||||
|     public static bing: RasterLayerPolygon = (<any>editorlayerindex.features).find( | ||||
|         (l) => l.properties.id === "Bing" | ||||
|     ) | ||||
|     public static bing = <RasterLayerPolygon> bingJson | ||||
|     public static readonly osmCartoProperties: RasterLayerProperties = { | ||||
|         id: "osm", | ||||
|         name: "OpenStreetMap", | ||||
|  | @ -56,17 +70,30 @@ export class AvailableRasterLayers { | |||
|             return l.properties.id === "protomaps.sunny" | ||||
|         }) | ||||
| 
 | ||||
|     public static layersAvailableAt( | ||||
|     public static layersAvailableAt( location: Store<{ lon: number; lat: number }>, | ||||
|                                      enableBing?: Store<boolean>): {store: Store<RasterLayerPolygon[]> } { | ||||
|         const store = {store: undefined} | ||||
|         Utils.AddLazyProperty(store, "store", () => AvailableRasterLayers._layersAvailableAt(location, enableBing)) | ||||
|         return store | ||||
|     } | ||||
| 
 | ||||
|     private static _layersAvailableAt( | ||||
|         location: Store<{ lon: number; lat: number }>, | ||||
|         enableBing?: Store<boolean> | ||||
|     ): Store<RasterLayerPolygon[]> { | ||||
| 
 | ||||
|         this.editorLayerIndex() // start the download
 | ||||
|         const availableLayersBboxes = Stores.ListStabilized( | ||||
|             location.mapD((loc) => { | ||||
|                 const eli = AvailableRasterLayers._editorLayerIndexStore.data | ||||
|                 if(!eli){ | ||||
|                     return [] | ||||
|                 } | ||||
|                 const lonlat: [number, number] = [loc.lon, loc.lat] | ||||
|                 return AvailableRasterLayers.EditorLayerIndex.filter((eliPolygon) => | ||||
|                 return eli.filter((eliPolygon) => | ||||
|                     BBox.get(eliPolygon).contains(lonlat) | ||||
|                 ) | ||||
|             }) | ||||
|             }, [AvailableRasterLayers._editorLayerIndexStore]) | ||||
|         ) | ||||
|         return Stores.ListStabilized( | ||||
|             availableLayersBboxes.map( | ||||
|  | @ -100,14 +127,6 @@ export class AvailableRasterLayers { | |||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     public static allIds(): Set<string> { | ||||
|         const all: string[] = [] | ||||
|         all.push(...AvailableRasterLayers.globalLayers.map((l) => l.properties.id)) | ||||
|         all.push(...AvailableRasterLayers.EditorLayerIndex.map((l) => l.properties.id)) | ||||
|         all.push(this.osmCarto.properties.id) | ||||
|         all.push(this.defaultBackgroundLayer.properties.id) | ||||
|         return new Set<string>(all) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export class RasterLayerUtils { | ||||
|  |  | |||
|  | @ -8,7 +8,6 @@ import { Utils } from "../../../Utils" | |||
| import { DetectDuplicatePresets, DoesImageExist, ValidateLanguageCompleteness } from "./Validation" | ||||
| 
 | ||||
| export class ValidateTheme extends DesugaringStep<LayoutConfigJson> { | ||||
|     private static readonly _availableLayers = AvailableRasterLayers.allIds() | ||||
|     /** | ||||
|      * The paths where this layer is originally saved. Triggers some extra checks | ||||
|      * @private | ||||
|  | @ -150,6 +149,8 @@ export class ValidateTheme extends DesugaringStep<LayoutConfigJson> { | |||
|         } | ||||
| 
 | ||||
|         if (json.defaultBackgroundId) { | ||||
|             /* | ||||
|             TODO re-enable this check | ||||
|             const backgroundId = json.defaultBackgroundId | ||||
| 
 | ||||
|             const isCategory = | ||||
|  | @ -165,7 +166,7 @@ export class ValidateTheme extends DesugaringStep<LayoutConfigJson> { | |||
|                             .slice(0, 5) | ||||
|                             .join(", ")}`,
 | ||||
|                     ) | ||||
|             } | ||||
|             }*/ | ||||
|         } | ||||
| 
 | ||||
|         for (let i = 0; i < theme.layers.length; i++) { | ||||
|  |  | |||
|  | @ -19,8 +19,6 @@ import { Utils } from "../../Utils" | |||
| import { TagsFilter } from "../../Logic/Tags/TagsFilter" | ||||
| import FilterConfigJson from "./Json/FilterConfigJson" | ||||
| import { Overpass } from "../../Logic/Osm/Overpass" | ||||
| import { ImmutableStore } from "../../Logic/UIEventSource" | ||||
| import { OsmTags } from "../OsmFeature" | ||||
| import Constants from "../Constants" | ||||
| import { QuestionableTagRenderingConfigJson } from "./Json/QuestionableTagRenderingConfigJson" | ||||
| import MarkdownUtils from "../../Utils/MarkdownUtils" | ||||
|  |  | |||
|  | @ -2,11 +2,7 @@ import LayoutConfig from "./ThemeConfig/LayoutConfig" | |||
| import { SpecialVisualizationState } from "../UI/SpecialVisualization" | ||||
| import { Changes } from "../Logic/Osm/Changes" | ||||
| import { Store, UIEventSource } from "../Logic/UIEventSource" | ||||
| import { | ||||
|     FeatureSource, | ||||
|     IndexedFeatureSource, | ||||
|     WritableFeatureSource, | ||||
| } from "../Logic/FeatureSource/FeatureSource" | ||||
| import { FeatureSource, IndexedFeatureSource, WritableFeatureSource } from "../Logic/FeatureSource/FeatureSource" | ||||
| import { OsmConnection } from "../Logic/Osm/OsmConnection" | ||||
| import { ExportableMap, MapProperties } from "./MapProperties" | ||||
| import LayerState from "../Logic/State/LayerState" | ||||
|  | @ -50,9 +46,7 @@ import BackgroundLayerResetter from "../Logic/Actors/BackgroundLayerResetter" | |||
| import SaveFeatureSourceToLocalStorage from "../Logic/FeatureSource/Actors/SaveFeatureSourceToLocalStorage" | ||||
| import BBoxFeatureSource from "../Logic/FeatureSource/Sources/TouchesBboxFeatureSource" | ||||
| import ThemeViewStateHashActor from "../Logic/Web/ThemeViewStateHashActor" | ||||
| import NoElementsInViewDetector, { | ||||
|     FeatureViewState, | ||||
| } from "../Logic/Actors/NoElementsInViewDetector" | ||||
| import NoElementsInViewDetector, { FeatureViewState } from "../Logic/Actors/NoElementsInViewDetector" | ||||
| import FilteredLayer from "./FilteredLayer" | ||||
| import { PreferredRasterLayerSelector } from "../Logic/Actors/PreferredRasterLayerSelector" | ||||
| import { ImageUploadManager } from "../Logic/ImageProviders/ImageUploadManager" | ||||
|  | @ -122,7 +116,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | |||
|     readonly perLayer: ReadonlyMap<string, GeoIndexedStoreForLayer> | ||||
|     readonly perLayerFiltered: ReadonlyMap<string, FilteringFeatureSource> | ||||
| 
 | ||||
|     readonly availableLayers: Store<RasterLayerPolygon[]> | ||||
|     readonly availableLayers:  {store: Store<RasterLayerPolygon[]>} | ||||
|     readonly userRelatedState: UserRelatedState | ||||
|     readonly geolocation: GeoLocationHandler | ||||
|     readonly geolocationControl: GeolocationControlState | ||||
|  | @ -153,7 +147,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | |||
|     public readonly visualFeedback: UIEventSource<boolean> = new UIEventSource<boolean>(false) | ||||
|     public readonly toCacheSavers: ReadonlyMap<string, SaveFeatureSourceToLocalStorage> | ||||
| 
 | ||||
|     public readonly nearbyImageSearcher | ||||
|     public readonly nearbyImageSearcher: CombinedFetcher | ||||
| 
 | ||||
|     constructor(layout: LayoutConfig, mvtAvailableLayers: Set<string>) { | ||||
|         Utils.initDomPurify() | ||||
|  | @ -375,9 +369,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | |||
|         longAgo.setTime(new Date().getTime() - 5 * 365 * 24 * 60 * 60 * 1000) | ||||
|         this.nearbyImageSearcher = new CombinedFetcher(50, longAgo, this.indexedFeatures) | ||||
| 
 | ||||
|         this.featureSummary = this.setupSummaryLayer( | ||||
|             new LayerConfig(<LayerConfigJson>summaryLayer, "summaryLayer", true) | ||||
|         ) | ||||
|         this.featureSummary = this.setupSummaryLayer() | ||||
|         this.toCacheSavers = layout.enableCache ? this.initSaveToLocalStorage() : undefined | ||||
|         this.initActors() | ||||
|         this.drawSpecialLayers() | ||||
|  | @ -647,7 +639,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | |||
|                 } | ||||
|             ) | ||||
|             const setLayerCategory = (category: EliCategory) => { | ||||
|                 const available = this.availableLayers.data | ||||
|                 const available = this.availableLayers.store.data | ||||
|                 const current = this.mapProperties.rasterLayer | ||||
|                 const best = RasterLayerUtils.SelectBestLayerAccordingTo( | ||||
|                     available, | ||||
|  | @ -696,7 +688,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | |||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     private setupSummaryLayer(summaryLayerConfig: LayerConfig): SummaryTileSourceRewriter { | ||||
|     private setupSummaryLayer(): SummaryTileSourceRewriter { | ||||
|         /** | ||||
|          * MaxZoom for the summary layer | ||||
|          */ | ||||
|  | @ -723,8 +715,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | |||
|             } | ||||
|         ) | ||||
| 
 | ||||
|         const src = new SummaryTileSourceRewriter(summaryTileSource, this.layerState.filteredLayers) | ||||
|         return src | ||||
|         return new SummaryTileSourceRewriter(summaryTileSource, this.layerState.filteredLayers) | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ class SingleBackgroundHandler { | |||
|     constructor( | ||||
|         map: Store<MLMap>, | ||||
|         targetLayer: RasterLayerPolygon, | ||||
|         background: UIEventSource<RasterLayerPolygon | undefined> | ||||
|         background: UIEventSource<RasterLayerPolygon | undefined>, | ||||
|     ) { | ||||
|         this._targetLayer = targetLayer | ||||
|         this._map = map | ||||
|  | @ -57,10 +57,15 @@ class SingleBackgroundHandler { | |||
|             "Removing raster layer", | ||||
|             this._targetLayer.properties.id, | ||||
|             "map moved and not been used for", | ||||
|             SingleBackgroundHandler.DEACTIVATE_AFTER | ||||
|             SingleBackgroundHandler.DEACTIVATE_AFTER, | ||||
|         ) | ||||
|         if (map.getLayer(<string>this._targetLayer.properties.id)) { | ||||
|             map.removeLayer(<string>this._targetLayer.properties.id) | ||||
|         try { | ||||
| 
 | ||||
|             if (map.getLayer(<string>this._targetLayer.properties.id)) { | ||||
|                 map.removeLayer(<string>this._targetLayer.properties.id) | ||||
|             } | ||||
|         } catch (e) { | ||||
|             console.warn("Could not (try to) remove the raster layer", e) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -152,7 +157,7 @@ class SingleBackgroundHandler { | |||
|                             "raster-opacity": 0, | ||||
|                         }, | ||||
|                     }, | ||||
|                     addLayerBeforeId | ||||
|                     addLayerBeforeId, | ||||
|                 ) | ||||
|                 this.opacity.addCallbackAndRun((o) => { | ||||
|                     try { | ||||
|  | @ -170,14 +175,14 @@ class SingleBackgroundHandler { | |||
|     private fadeOut() { | ||||
|         Stores.Chronic( | ||||
|             8, | ||||
|             () => this.opacity.data > 0 && this._deactivationTime !== undefined | ||||
|             () => this.opacity.data > 0 && this._deactivationTime !== undefined, | ||||
|         ).addCallback((_) => this.opacity.setData(Math.max(0, this.opacity.data - this.fadeStep))) | ||||
|     } | ||||
| 
 | ||||
|     private fadeIn() { | ||||
|         Stores.Chronic( | ||||
|             8, | ||||
|             () => this.opacity.data < 1.0 && this._deactivationTime === undefined | ||||
|             () => this.opacity.data < 1.0 && this._deactivationTime === undefined, | ||||
|         ).addCallback((_) => this.opacity.setData(Math.min(1.0, this.opacity.data + this.fadeStep))) | ||||
|     } | ||||
| } | ||||
|  | @ -195,7 +200,7 @@ export default class RasterLayerHandler { | |||
|     } | ||||
| 
 | ||||
|     public static prepareSource( | ||||
|         layer: RasterLayerProperties | ||||
|         layer: RasterLayerProperties, | ||||
|     ): RasterSourceSpecification | VectorSourceSpecification { | ||||
|         if (layer.type === "vector") { | ||||
|             const vs: VectorSourceSpecification = { | ||||
|  |  | |||
|  | @ -12,11 +12,13 @@ | |||
|   import Translations from "../i18n/Translations" | ||||
|   import Tr from "../Base/Tr.svelte" | ||||
|   import TitledPanel from "../Base/TitledPanel.svelte" | ||||
|   import Loading from "../Base/Loading.svelte" | ||||
| 
 | ||||
|   export let availableLayers: Store<RasterLayerPolygon[]> | ||||
|   export let availableLayers: {store: Store<RasterLayerPolygon[]>} | ||||
|   export let mapproperties: MapProperties | ||||
|   export let userstate: UserRelatedState | ||||
|   export let map: Store<MlMap> | ||||
|   let _availableLayers = availableLayers.store | ||||
|   /** | ||||
|    * Used to toggle the background layers on/off | ||||
|    */ | ||||
|  | @ -32,8 +34,8 @@ | |||
| 
 | ||||
|   function availableForCategory(type: CategoryType): Store<RasterLayerPolygon[]> { | ||||
|     const keywords = categories[type] | ||||
|     return availableLayers.mapD((available) => | ||||
|       available.filter((layer) => keywords.indexOf(<EliCategory>layer.properties.category) >= 0) | ||||
|     return _availableLayers.mapD((available) => | ||||
|       available.filter((layer) => keywords.indexOf(<EliCategory>layer.properties.category) >= 0), | ||||
|     ) | ||||
|   } | ||||
| 
 | ||||
|  | @ -53,39 +55,42 @@ | |||
| 
 | ||||
| <TitledPanel> | ||||
|   <Tr slot="title" t={Translations.t.general.backgroundMap} /> | ||||
| 
 | ||||
|   <div class="grid h-full w-full grid-cols-1 gap-2 md:grid-cols-2"> | ||||
|     <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> | ||||
|   {#if $_availableLayers?.length < 1} | ||||
|     <Loading /> | ||||
|   {:else } | ||||
|     <div class="grid h-full w-full grid-cols-1 gap-2 md:grid-cols-2"> | ||||
|       <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> | ||||
|   {/if} | ||||
| </TitledPanel> | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ | |||
|   /*** | ||||
|    * Chooses a background-layer out of available options | ||||
|    */ | ||||
|   export let availableLayers: Store<RasterLayerPolygon[]> | ||||
|   export let availableLayers: RasterLayerPolygon[] | ||||
|   export let mapproperties: MapProperties | ||||
|   export let map: Store<MlMap> | ||||
| 
 | ||||
|  | @ -19,34 +19,26 @@ | |||
| 
 | ||||
|   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]) | ||||
|     }) | ||||
|   ) | ||||
|   let rasterLayer = new UIEventSource<RasterLayerPolygon>(availableLayers[0]) | ||||
|   let rasterLayerId = rasterLayer.sync(l => l?.properties?.id, [], id => availableLayers.find(l => l.properties.id === id)) | ||||
|   rasterLayer.setData(availableLayers[0]) | ||||
|   $: rasterLayer.setData(availableLayers[0]) | ||||
| 
 | ||||
|   if (favourite) { | ||||
|     onDestroy( | ||||
|       favourite.addCallbackAndRunD((favourite) => { | ||||
|         const fav = availableLayers.data?.find((l) => l.properties.id === favourite) | ||||
|         const fav = availableLayers?.find((l) => l.properties.id === favourite) | ||||
|         if (!fav) { | ||||
|           return | ||||
|         } | ||||
|         rasterLayer.setData(fav) | ||||
|       }) | ||||
|       }), | ||||
|     ) | ||||
| 
 | ||||
|     onDestroy( | ||||
|       rasterLayer.addCallbackAndRunD((selected) => { | ||||
|         favourite?.setData(selected.properties.id) | ||||
|       }) | ||||
|       }), | ||||
|     ) | ||||
|   } | ||||
| 
 | ||||
|  | @ -56,13 +48,14 @@ | |||
|     onDestroy( | ||||
|       visible?.addCallbackAndRunD((visible) => { | ||||
|         if (visible) { | ||||
|           rasterLayerOnMap.setData(rasterLayer.data ?? availableLayers.data[0]) | ||||
|           rasterLayerOnMap.setData(rasterLayer.data ?? availableLayers[0]) | ||||
|         } else { | ||||
|           rasterLayerOnMap.setData(undefined) | ||||
|         } | ||||
|       }) | ||||
|       }), | ||||
|     ) | ||||
|   } | ||||
| 
 | ||||
|   function apply() { | ||||
|     mapproperties.rasterLayer.setData(rasterLayer.data) | ||||
|     dispatch("appliedLayer") | ||||
|  | @ -75,7 +68,7 @@ | |||
|   } | ||||
| </script> | ||||
| 
 | ||||
| {#if hasLayers} | ||||
| {#if availableLayers?.length > 0} | ||||
|   <form class="flex h-full w-full flex-col" on:submit|preventDefault={() => {}}> | ||||
|     <button | ||||
|       tabindex="-1" | ||||
|  | @ -92,9 +85,9 @@ | |||
|         /> | ||||
|       </span> | ||||
|     </button> | ||||
|     <select bind:value={$rasterLayer} class="w-full" on:keydown={handleKeyPress}> | ||||
|       {#each $availableLayers as availableLayer} | ||||
|         <option value={availableLayer}> | ||||
|     <select bind:value={$rasterLayerId} class="w-full" on:keydown={handleKeyPress}> | ||||
|       {#each availableLayers as availableLayer} | ||||
|         <option value={availableLayer.properties.id}> | ||||
|           {availableLayer.properties.name} | ||||
|         </option> | ||||
|       {/each} | ||||
|  |  | |||
|  | @ -88,8 +88,6 @@ export interface SpecialVisualizationState { | |||
|         readonly language: UIEventSource<string> | ||||
|     } | ||||
| 
 | ||||
|     readonly availableLayers: Store<RasterLayerPolygon[]> | ||||
| 
 | ||||
|     readonly imageUploadManager: ImageUploadManager | ||||
| 
 | ||||
|     readonly previewedImage: UIEventSource<ProvidedImage> | ||||
|  |  | |||
							
								
								
									
										1
									
								
								src/assets/editor-layer-index.bing.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/assets/editor-layer-index.bing.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {"properties":{"name":"Bing Maps Aerial","id":"Bing","url":"https://ecn.t0.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=14634&pr=odbl&n=f","type":"bing","category":"photo","min_zoom":1,"max_zoom":22},"type":"Feature","geometry":null} | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue