UX: immediately download a feature that has the ID via the hash to display it faster

This commit is contained in:
Pieter Vander Vennet 2025-08-18 14:00:42 +02:00
parent ccdcb86044
commit 20f4f6b869
3 changed files with 29 additions and 18 deletions

View file

@ -2,7 +2,7 @@ import { Utils } from "../../Utils"
import polygon_features from "../../assets/polygon-features.json"
import { OsmFeature, OsmId, OsmTags, WayId } from "../../Models/OsmFeature"
import OsmToGeoJson from "osmtogeojson"
import { Feature, LineString, Polygon } from "geojson"
import { Feature, LineString, Point, Polygon } from "geojson"
import Constants from "../../Models/Constants"
export abstract class OsmObject {
@ -131,7 +131,7 @@ export abstract class OsmObject {
*/
public abstract centerpoint(): [number, number]
public abstract asGeoJson(): any
public abstract asGeoJson(): OsmFeature
abstract SaveExtraData(element: any, allElements: OsmObject[] | any)
@ -228,7 +228,7 @@ ${tags} </node>
return [this.lat, this.lon]
}
asGeoJson(): OsmFeature {
asGeoJson(): Feature<Point, OsmTags> {
return {
type: "Feature",
properties: this.tags,
@ -305,7 +305,7 @@ ${nds}${tags} </way>
this.nodes = element.nodes
}
public asGeoJson(): Feature<Polygon | LineString> & { properties: { id: WayId } } {
public asGeoJson(): Feature<Polygon | LineString, OsmTags> & { properties: { id: WayId } } {
const coordinates: [number, number][] | [number, number][][] = this.coordinates.map(
([lat, lon]) => [lon, lat]
)
@ -384,7 +384,7 @@ ${members}${tags} </relation>
this.geojson = geojson
}
asGeoJson(): any {
asGeoJson(): OsmFeature {
if (this.geojson !== undefined) {
return this.geojson
}

View file

@ -4,13 +4,17 @@ import { AndroidPolyfill } from "./AndroidPolyfill"
import { IndexedFeatureSource } from "../FeatureSource/FeatureSource"
import { Feature } from "geojson"
import { Store, UIEventSource } from "../UIEventSource"
import ThemeViewState from "../../Models/ThemeViewState"
import OsmObjectDownloader from "../Osm/OsmObjectDownloader"
import ThemeSource from "../FeatureSource/Sources/ThemeSource"
export default class ThemeViewStateHashActor {
private readonly _state: {
private readonly _state: Readonly<{
indexedFeatures: IndexedFeatureSource
selectedElement: UIEventSource<Feature>
guistate: MenuState
}
guistate: MenuState,
osmObjectDownloader: OsmObjectDownloader
}>
private isUpdatingHash = false
public static readonly documentation = [
@ -35,12 +39,13 @@ export default class ThemeViewStateHashActor {
* As such, we use a change in the hash to close the appropriate windows
*
*/
constructor(state: {
constructor(state: Readonly<{
featureSwitches: { featureSwitchBackToThemeOverview: Store<boolean> }
indexedFeatures: IndexedFeatureSource
indexedFeatures: IndexedFeatureSource & ThemeSource
selectedElement: UIEventSource<Feature>
guistate: MenuState
}) {
guistate: MenuState,
osmObjectDownloader: OsmObjectDownloader
}> ) {
this._state = state
AndroidPolyfill.onBackButton(() => this.back(), {
returnToIndex: state.featureSwitches.featureSwitchBackToThemeOverview,
@ -50,6 +55,17 @@ export default class ThemeViewStateHashActor {
const containsMenu = this.loadStateFromHash(hashOnLoad)
// First of all, try to recover the selected element
if (!containsMenu && hashOnLoad?.length > 0) {
if (hashOnLoad.startsWith("node/") || hashOnLoad.startsWith("way/") || hashOnLoad.startsWith("relation/")) {
// This is an OSM-element. Let's download it and add it to the indexedFeatures
console.log("Directly downloading item from hash")
state.osmObjectDownloader.DownloadObjectAsync(hashOnLoad)
.then(osmObj => {
if (osmObj === "deleted") {
return
}
state.indexedFeatures.addItem(osmObj.asGeoJson())
})
}
state.indexedFeatures.featuresById.addCallbackAndRunD(() => {
// once that we have found a matching element, we can be sure the indexedFeaturesource was popuplated and that the job is done
return this.loadSelectedElementFromHash(hashOnLoad)

View file

@ -51,12 +51,7 @@ export class WithImageState extends WithGuiState implements SpecialVisualization
* Setup various services for which no reference are needed
*/
private initActors() {
new ThemeViewStateHashActor({
featureSwitches: this.featureSwitches,
selectedElement: this.selectedElement,
indexedFeatures: this.indexedFeatures,
guistate: this.guistate,
})
new ThemeViewStateHashActor(this)
new PendingChangesUploader(this.changes, this.selectedElement, this.imageUploadManager)
}
}