UX: attempt to fix #2394

This commit is contained in:
Pieter Vander Vennet 2025-05-04 02:37:57 +02:00
parent 4604fc62e5
commit 156493ef06
6 changed files with 31 additions and 25 deletions

View file

@ -31,7 +31,7 @@ export abstract class OsmObject {
const objects: OsmObject[] = [] const objects: OsmObject[] = []
const allNodes: Map<number, OsmNode> = new Map<number, OsmNode>() const allNodes: Map<number, OsmNode> = new Map<number, OsmNode>()
for (const element of elements) { for (const element of elements ?? []) {
const type = element.type const type = element.type
const idN = element.id const idN = element.id
let osmObject: OsmObject = null let osmObject: OsmObject = null

View file

@ -244,7 +244,7 @@ export default class OsmObjectDownloader {
return "deleted" 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) // 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 // Let us fetch the object we need
for (const osmObject of parsed) { for (const osmObject of parsed) {
if (osmObject.type !== type) { if (osmObject.type !== type) {
@ -256,6 +256,6 @@ export default class OsmObjectDownloader {
// Found the one! // Found the one!
return osmObject return osmObject
} }
throw "PANIC: requested object is not part of the response" throw `PANIC: requested object ${type}/${idN} is not part of the response`
} }
} }

View file

@ -9,6 +9,7 @@ import { FeatureSource, IndexedFeatureSource } from "../../Logic/FeatureSource/F
import { Tag } from "../../Logic/Tags/Tag" import { Tag } from "../../Logic/Tags/Tag"
import Hotkeys from "../../UI/Base/Hotkeys" import Hotkeys from "../../UI/Base/Hotkeys"
import Translations from "../../UI/i18n/Translations" import Translations from "../../UI/i18n/Translations"
import { Feature } from "geojson"
export class WithLayoutSourceState extends WithSelectedElementState { export class WithLayoutSourceState extends WithSelectedElementState {
readonly layerState: LayerState readonly layerState: LayerState
@ -127,4 +128,10 @@ export class WithLayoutSourceState extends WithSelectedElementState {
this.featureProperties.trackFeature(feature) this.featureProperties.trackFeature(feature)
this.selectedElement.setData(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)
}
} }

View file

@ -18,7 +18,7 @@ import { Store, UIEventSource } from "../../Logic/UIEventSource"
import NearbyFeatureSource from "../../Logic/FeatureSource/Sources/NearbyFeatureSource" import NearbyFeatureSource from "../../Logic/FeatureSource/Sources/NearbyFeatureSource"
import { import {
SummaryTileSource, SummaryTileSource,
SummaryTileSourceRewriter, SummaryTileSourceRewriter
} from "../../Logic/FeatureSource/TiledFeatureSource/SummaryTileSource" } from "../../Logic/FeatureSource/TiledFeatureSource/SummaryTileSource"
import { ShowDataLayerOptions } from "../../UI/Map/ShowDataLayerOptions" import { ShowDataLayerOptions } from "../../UI/Map/ShowDataLayerOptions"
@ -121,7 +121,7 @@ export class WithSpecialLayers extends WithChangesState {
new ShowDataLayer(this.map, { new ShowDataLayer(this.map, {
features: source, features: source,
layer: new LayerConfig(<LayerConfigJson>summaryLayer, "summaryLayer"), layer: new LayerConfig(<LayerConfigJson><unknown>summaryLayer, "summaryLayer"),
// doShowLayer: this.mapProperties.zoom.map((z) => z < maxzoom), // doShowLayer: this.mapProperties.zoom.map((z) => z < maxzoom),
selectedElement: this.selectedElement, selectedElement: this.selectedElement,
}) })
@ -147,7 +147,7 @@ export class WithSpecialLayers extends WithChangesState {
private drawLastClick() { private drawLastClick() {
const source = this.lastClickObject const source = this.lastClickObject
const lastClickLayerConfig = new LayerConfig( const lastClickLayerConfig = new LayerConfig(
<LayerConfigJson>last_click_layerconfig, <LayerConfigJson><unknown>last_click_layerconfig,
"last_click" "last_click"
) )
const lastClickFiltered = const lastClickFiltered =
@ -185,7 +185,7 @@ export class WithSpecialLayers extends WithChangesState {
const src = new StaticFeatureSource( const src = new StaticFeatureSource(
this.selectedElement.map((f) => (f === undefined ? [] : [f])) 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() { private drawSpecialLayers() {

View file

@ -277,7 +277,7 @@ class LineRenderingLayer {
updateNeededSrc.set(false) updateNeededSrc.set(false)
} }
}) })
features.features.addCallbackAndRunD(() => { features.features.addCallbackAndRunD(async (feats) => {
console.log("New features!", this._layername, features.features.data.length) console.log("New features!", this._layername, features.features.data.length)
updateNeededSrc.set(true) updateNeededSrc.set(true)
}) })
@ -377,6 +377,7 @@ class LineRenderingLayer {
private async update(features: Feature[]) { private async update(features: Feature[]) {
const map = this._map const map = this._map
await this.awaitStyleLoaded()
const src = <GeoJSONSource>map.getSource(this._layername) const src = <GeoJSONSource>map.getSource(this._layername)
{ {
// Add source to the map or update the feature source // Add source to the map or update the feature source
@ -550,7 +551,7 @@ export default class ShowDataLayer {
options: ShowDataLayerOptions & { options: ShowDataLayerOptions & {
layer: LayerConfig layer: LayerConfig
drawMarkers?: true | boolean drawMarkers?: true | boolean
drawLines?: true | boolean drawLines?: true | boolean,
} }
) { ) {
this._options = options this._options = options
@ -626,23 +627,20 @@ export default class ShowDataLayer {
} }
private initDrawFeatures(map: MlMap) { 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 let onClick = this._options.onClick
if (!onClick && selectedElement) { if (!onClick && selectedElement && layer.title !== undefined) {
onClick = onClick = (feature: Feature) => {
this._options.layer.title === undefined selectedElement?.setData(feature)
? undefined }
: (feature: Feature) => {
selectedElement?.setData(feature)
}
} }
if (this._options.drawLines !== false) { if (drawLines !== false) {
for (let i = 0; i < this._options.layer.lineRendering.length; i++) { for (let i = 0; i < layer.lineRendering.length; i++) {
const lineRenderingConfig = this._options.layer.lineRendering[i] const lineRenderingConfig = layer.lineRendering[i]
const l = new LineRenderingLayer( const l = new LineRenderingLayer(
map, map,
features, features,
"mapcomplete_" + this._options.layer.id + "_linerendering_" + i, "mapcomplete_" + (this._options.prefix ?? "") + layer.id + "_linerendering_" + i,
lineRenderingConfig, lineRenderingConfig,
doShowLayer, doShowLayer,
fetchStore, fetchStore,
@ -651,11 +649,11 @@ export default class ShowDataLayer {
this.onDestroy.push(l.destruct) this.onDestroy.push(l.destruct)
} }
} }
if (this._options.drawMarkers !== false) { if (drawMarkers !== false) {
for (const pointRenderingConfig of this._options.layer.mapRendering) { for (const pointRenderingConfig of layer.mapRendering) {
new PointRenderingLayer( new PointRenderingLayer(
map, map,
this._options.layer, layer,
features, features,
pointRenderingConfig, pointRenderingConfig,
this._options.metaTags, this._options.metaTags,

View file

@ -1,6 +1,5 @@
import { FeatureSource } from "../../Logic/FeatureSource/FeatureSource" import { FeatureSource } from "../../Logic/FeatureSource/FeatureSource"
import { Store, UIEventSource } from "../../Logic/UIEventSource" import { Store, UIEventSource } from "../../Logic/UIEventSource"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import { Feature } from "geojson" import { Feature } from "geojson"
export interface ShowDataLayerOptions { export interface ShowDataLayerOptions {
@ -31,4 +30,6 @@ export interface ShowDataLayerOptions {
onClick?: (feature: Feature) => void onClick?: (feature: Feature) => void
metaTags?: Store<Record<string, string>> metaTags?: Store<Record<string, string>>
prefix?: string
} }