diff --git a/src/Logic/Osm/OsmObject.ts b/src/Logic/Osm/OsmObject.ts index 563a9e1ba5..c74f59fc86 100644 --- a/src/Logic/Osm/OsmObject.ts +++ b/src/Logic/Osm/OsmObject.ts @@ -31,7 +31,7 @@ export abstract class OsmObject { const objects: OsmObject[] = [] const allNodes: Map = new Map() - for (const element of elements) { + for (const element of elements ?? []) { const type = element.type const idN = element.id let osmObject: OsmObject = null diff --git a/src/Logic/Osm/OsmObjectDownloader.ts b/src/Logic/Osm/OsmObjectDownloader.ts index 45c3fa70dd..97681d4803 100644 --- a/src/Logic/Osm/OsmObjectDownloader.ts +++ b/src/Logic/Osm/OsmObjectDownloader.ts @@ -244,7 +244,7 @@ export default class OsmObjectDownloader { return "deleted" } // A full query might contain more than just the requested object (e.g. nodes that are part of a way, where we only want the way) - const parsed = OsmObject.ParseObjects(rawData["content"].elements) + const parsed = OsmObject.ParseObjects(rawData?.["content"]?.elements) // Let us fetch the object we need for (const osmObject of parsed) { if (osmObject.type !== type) { @@ -256,6 +256,6 @@ export default class OsmObjectDownloader { // Found the one! return osmObject } - throw "PANIC: requested object is not part of the response" + throw `PANIC: requested object ${type}/${idN} is not part of the response` } } diff --git a/src/Models/ThemeViewState/WithLayoutSourceState.ts b/src/Models/ThemeViewState/WithLayoutSourceState.ts index 4e6e184213..0a35aca70a 100644 --- a/src/Models/ThemeViewState/WithLayoutSourceState.ts +++ b/src/Models/ThemeViewState/WithLayoutSourceState.ts @@ -9,6 +9,7 @@ import { FeatureSource, IndexedFeatureSource } from "../../Logic/FeatureSource/F import { Tag } from "../../Logic/Tags/Tag" import Hotkeys from "../../UI/Base/Hotkeys" import Translations from "../../UI/i18n/Translations" +import { Feature } from "geojson" export class WithLayoutSourceState extends WithSelectedElementState { readonly layerState: LayerState @@ -127,4 +128,10 @@ export class WithLayoutSourceState extends WithSelectedElementState { this.featureProperties.trackFeature(feature) this.selectedElement.setData(feature) } + + protected setSelectedElement(feature: Feature) { + // The given feature might be a partial one from the cache + feature = this.indexedFeatures.featuresById.data?.get(feature.properties.id) ?? feature + super.setSelectedElement(feature) + } } diff --git a/src/Models/ThemeViewState/WithSpecialLayers.ts b/src/Models/ThemeViewState/WithSpecialLayers.ts index 8e707a0190..52546d5cf6 100644 --- a/src/Models/ThemeViewState/WithSpecialLayers.ts +++ b/src/Models/ThemeViewState/WithSpecialLayers.ts @@ -18,7 +18,7 @@ import { Store, UIEventSource } from "../../Logic/UIEventSource" import NearbyFeatureSource from "../../Logic/FeatureSource/Sources/NearbyFeatureSource" import { SummaryTileSource, - SummaryTileSourceRewriter, + SummaryTileSourceRewriter } from "../../Logic/FeatureSource/TiledFeatureSource/SummaryTileSource" import { ShowDataLayerOptions } from "../../UI/Map/ShowDataLayerOptions" @@ -121,7 +121,7 @@ export class WithSpecialLayers extends WithChangesState { new ShowDataLayer(this.map, { features: source, - layer: new LayerConfig(summaryLayer, "summaryLayer"), + layer: new LayerConfig(summaryLayer, "summaryLayer"), // doShowLayer: this.mapProperties.zoom.map((z) => z < maxzoom), selectedElement: this.selectedElement, }) @@ -147,7 +147,7 @@ export class WithSpecialLayers extends WithChangesState { private drawLastClick() { const source = this.lastClickObject const lastClickLayerConfig = new LayerConfig( - last_click_layerconfig, + last_click_layerconfig, "last_click" ) const lastClickFiltered = @@ -185,7 +185,7 @@ export class WithSpecialLayers extends WithChangesState { const src = new StaticFeatureSource( this.selectedElement.map((f) => (f === undefined ? [] : [f])) ) - ShowDataLayer.showMultipleLayers(this.map, src, this.theme.layers) + ShowDataLayer.showMultipleLayers(this.map, src, this.theme.layers, { prefix: "selected_element_" }) } private drawSpecialLayers() { diff --git a/src/UI/Map/ShowDataLayer.ts b/src/UI/Map/ShowDataLayer.ts index 9916344737..1fcbd20575 100644 --- a/src/UI/Map/ShowDataLayer.ts +++ b/src/UI/Map/ShowDataLayer.ts @@ -277,7 +277,7 @@ class LineRenderingLayer { updateNeededSrc.set(false) } }) - features.features.addCallbackAndRunD(() => { + features.features.addCallbackAndRunD(async (feats) => { console.log("New features!", this._layername, features.features.data.length) updateNeededSrc.set(true) }) @@ -377,6 +377,7 @@ class LineRenderingLayer { private async update(features: Feature[]) { const map = this._map + await this.awaitStyleLoaded() const src = map.getSource(this._layername) { // Add source to the map or update the feature source @@ -550,7 +551,7 @@ export default class ShowDataLayer { options: ShowDataLayerOptions & { layer: LayerConfig drawMarkers?: true | boolean - drawLines?: true | boolean + drawLines?: true | boolean, } ) { this._options = options @@ -626,23 +627,20 @@ export default class ShowDataLayer { } private initDrawFeatures(map: MlMap) { - const { features, doShowLayer, fetchStore, selectedElement } = this._options + const { features, doShowLayer, fetchStore, selectedElement, layer, drawLines, drawMarkers } = this._options let onClick = this._options.onClick - if (!onClick && selectedElement) { - onClick = - this._options.layer.title === undefined - ? undefined - : (feature: Feature) => { - selectedElement?.setData(feature) - } + if (!onClick && selectedElement && layer.title !== undefined) { + onClick = (feature: Feature) => { + selectedElement?.setData(feature) + } } - if (this._options.drawLines !== false) { - for (let i = 0; i < this._options.layer.lineRendering.length; i++) { - const lineRenderingConfig = this._options.layer.lineRendering[i] + if (drawLines !== false) { + for (let i = 0; i < layer.lineRendering.length; i++) { + const lineRenderingConfig = layer.lineRendering[i] const l = new LineRenderingLayer( map, features, - "mapcomplete_" + this._options.layer.id + "_linerendering_" + i, + "mapcomplete_" + (this._options.prefix ?? "") + layer.id + "_linerendering_" + i, lineRenderingConfig, doShowLayer, fetchStore, @@ -651,11 +649,11 @@ export default class ShowDataLayer { this.onDestroy.push(l.destruct) } } - if (this._options.drawMarkers !== false) { - for (const pointRenderingConfig of this._options.layer.mapRendering) { + if (drawMarkers !== false) { + for (const pointRenderingConfig of layer.mapRendering) { new PointRenderingLayer( map, - this._options.layer, + layer, features, pointRenderingConfig, this._options.metaTags, diff --git a/src/UI/Map/ShowDataLayerOptions.ts b/src/UI/Map/ShowDataLayerOptions.ts index bbd7135518..e848ead218 100644 --- a/src/UI/Map/ShowDataLayerOptions.ts +++ b/src/UI/Map/ShowDataLayerOptions.ts @@ -1,6 +1,5 @@ import { FeatureSource } from "../../Logic/FeatureSource/FeatureSource" import { Store, UIEventSource } from "../../Logic/UIEventSource" -import LayerConfig from "../../Models/ThemeConfig/LayerConfig" import { Feature } from "geojson" export interface ShowDataLayerOptions { @@ -31,4 +30,6 @@ export interface ShowDataLayerOptions { onClick?: (feature: Feature) => void metaTags?: Store> + + prefix?: string }