diff --git a/assets/layers/item_with_image/camera.svg b/assets/layers/item_with_image/camera.svg new file mode 100644 index 0000000000..a29853276f --- /dev/null +++ b/assets/layers/item_with_image/camera.svg @@ -0,0 +1,64 @@ + + + Adwaita Icon Template + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/layers/item_with_image/camera.svg.license b/assets/layers/item_with_image/camera.svg.license new file mode 100644 index 0000000000..0d0e69f2ed --- /dev/null +++ b/assets/layers/item_with_image/camera.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: https://gitlab.gnome.org/jimmac +SPDX-License-Identifier: GPL3 \ No newline at end of file diff --git a/assets/layers/item_with_image/item_with_image.json b/assets/layers/item_with_image/item_with_image.json new file mode 100644 index 0000000000..27c6ac1b3e --- /dev/null +++ b/assets/layers/item_with_image/item_with_image.json @@ -0,0 +1,47 @@ +{ + "id": "item_with_image", + "description": "All items with an image. All alone, not a layer which is relevant for any MapComplete theme, as it is a random collection of items. However, when put into the databank, this allows to quickly fetch (the URL of) pictures nearby a different object, to quickly link this", + "minzoom": 14, + "source": { + "osmTags": { + "or": [ + "image~*", + "image:0~*", + "image:1~*", + "image:2~*", + "image:3~*", + "image:4~*", + "image:5~*" + ] + } + }, + "tagRenderings": [ + "images" + ], + "title": { + "render": { + "en": "POI with image" + }, + "mappings": [{ + "if": "name~*", + "then": {"*": "name"} + }] + }, + "name": { + "en": "Items with at least one image" + }, + "lineRendering": [], + "pointRendering": [ + { + "marker": [ + { + "icon": "./assets/layers/item_with_image/camera.svg" + } + ], + "location": [ + "centroid", + "point" + ] + } + ] +} diff --git a/assets/layers/item_with_image/license_info.json b/assets/layers/item_with_image/license_info.json new file mode 100644 index 0000000000..a5dbb52044 --- /dev/null +++ b/assets/layers/item_with_image/license_info.json @@ -0,0 +1,12 @@ +[ + { + "path": "camera.svg", + "license": "GPL3", + "authors": [ + "https://gitlab.gnome.org/jimmac" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:GNOME_Photos_icon_2018.svg" + ] + } +] \ No newline at end of file diff --git a/assets/themes/items_with_image/items_with_image.json b/assets/themes/items_with_image/items_with_image.json new file mode 100644 index 0000000000..17ca1a320f --- /dev/null +++ b/assets/themes/items_with_image/items_with_image.json @@ -0,0 +1,14 @@ +{ + "id": "items_with_image", + "hideFromOverview": true, + "title": { + "en": "All items with images" + }, + "description": { + "en": "A map showing all items on OSM which have an image. This theme is a very bad fit for MapComplete as someone is not able to directly add a picture. However, this theme is mostly here to include this all into the database, which'll allow this to quickly fetch images nearby for other features" + }, + "icon": "./assets/layers/item_with_image/camera.svg", + "layers": [ + "item_with_image" + ] +} diff --git a/assets/themes/mapcomplete-changes/mapcomplete-changes.json b/assets/themes/mapcomplete-changes/mapcomplete-changes.json index 2ff55d9804..9d03f8832c 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.json @@ -318,6 +318,10 @@ "if": "theme=indoors", "then": "./assets/layers/entrance/entrance.svg" }, + { + "if": "theme=items_with_image", + "then": "./assets/layers/item_with_image/camera.svg" + }, { "if": "theme=kerbs_and_crossings", "then": "./assets/layers/kerbs/KerbIcon.svg" diff --git a/src/Models/ThemeConfig/Conversion/Conversion.ts b/src/Models/ThemeConfig/Conversion/Conversion.ts index 7603e56850..d9c4eeecec 100644 --- a/src/Models/ThemeConfig/Conversion/Conversion.ts +++ b/src/Models/ThemeConfig/Conversion/Conversion.ts @@ -156,7 +156,7 @@ export class On extends DesugaringStep { convert(json: T, context: ConversionContext): T { const key = this.key - const value: P = json[key] + const value: P = json?.[key] if (value === undefined || value === null) { return json } diff --git a/src/Models/ThemeConfig/Conversion/PrepareTheme.ts b/src/Models/ThemeConfig/Conversion/PrepareTheme.ts index 0eccdcf14b..92585607d7 100644 --- a/src/Models/ThemeConfig/Conversion/PrepareTheme.ts +++ b/src/Models/ThemeConfig/Conversion/PrepareTheme.ts @@ -366,7 +366,7 @@ class AddDependencyLayersToTheme extends DesugaringStep { themeId: string ): { config: LayerConfigJson; reason: string }[] { const dependenciesToAdd: { config: LayerConfigJson; reason: string }[] = [] - const loadedLayerIds: Set = new Set(alreadyLoaded.map((l) => l.id)) + const loadedLayerIds: Set = new Set(alreadyLoaded.map((l) => l?.id)) // Verify cross-dependencies let unmetDependencies: { diff --git a/src/UI/Map/RasterLayerHandler.ts b/src/UI/Map/RasterLayerHandler.ts index 1effc62596..7123ca769c 100644 --- a/src/UI/Map/RasterLayerHandler.ts +++ b/src/UI/Map/RasterLayerHandler.ts @@ -71,7 +71,7 @@ class SingleBackgroundHandler { this.fadeOut() } else { this._deactivationTime = undefined - this.enable() + await this.enable() this.fadeIn() } } @@ -85,10 +85,23 @@ class SingleBackgroundHandler { } } - private enable() { + private async enable(){ + let ttl = 15 + await this.awaitStyleIsLoaded() + while(!this.tryEnable() && ttl > 0){ + ttl --; + await Utils.waitFor(250) + } + } + + /** + * Returns 'false' if should be attempted again + * @private + */ + private tryEnable(): boolean { const map: MLMap = this._map.data if (!map) { - return + return true } const background = this._targetLayer.properties console.debug("Enabling", background.id) @@ -101,8 +114,7 @@ class SingleBackgroundHandler { try { map.addSource(background.id, RasterLayerHandler.prepareWmsSource(background)) } catch (e) { - console.error("Could not add source", e) - return + return false } } if (!map.getLayer(background.id)) { @@ -126,6 +138,7 @@ class SingleBackgroundHandler { map.setPaintProperty(background.id, "raster-opacity", o) }) } + return true } private fadeOut() {