OsmObjects can now be used as featureSource, load selected object immediately, zoom to selected object on open; fix #191

This commit is contained in:
Pieter Vander Vennet 2021-05-06 01:33:09 +02:00
parent 5ce4140510
commit a0c1bc2137
13 changed files with 205 additions and 98 deletions

View file

@ -185,6 +185,9 @@ export class InitUiElements {
// Reset the loading message once things are loaded // Reset the loading message once things are loaded
new CenterMessageBox().AttachTo("centermessage"); new CenterMessageBox().AttachTo("centermessage");
// At last, zoom to the needed location if the focus is on an element
} }
static LoadLayoutFromHash(userLayoutParam: UIEventSource<string>) { static LoadLayoutFromHash(userLayoutParam: UIEventSource<string>) {
@ -391,12 +394,18 @@ export class InitUiElements {
const updater = new LoadFromOverpass(state.locationControl, state.layoutToUse, state.leafletMap); const updater = new LoadFromOverpass(state.locationControl, state.layoutToUse, state.leafletMap);
State.state.layerUpdater = updater; State.state.layerUpdater = updater;
const source = new FeaturePipeline(state.filteredLayers, updater, state.layoutToUse, state.changes, state.locationControl); const source = new FeaturePipeline(state.filteredLayers,
updater,
state.osmApiFeatureSource,
state.layoutToUse,
state.changes,
state.locationControl,
state.selectedElement);
new ShowDataLayer(source.features, State.state.leafletMap, State.state.layoutToUse); new ShowDataLayer(source.features, State.state.leafletMap, State.state.layoutToUse);
new SelectedFeatureHandler(Hash.hash, State.state.selectedElement, source); const selectedFeatureHandler = new SelectedFeatureHandler(Hash.hash, State.state.selectedElement, source, State.state.osmApiFeatureSource);
selectedFeatureHandler.zoomToSelectedFeature(State.state.locationControl);
} }

View file

@ -1,8 +1,12 @@
import {UIEventSource} from "../UIEventSource"; import {UIEventSource} from "../UIEventSource";
import FeatureSource from "../FeatureSource/FeatureSource"; import FeatureSource from "../FeatureSource/FeatureSource";
import {OsmObject, OsmObjectMeta} from "../Osm/OsmObject";
import Loc from "../../Models/Loc";
import FeaturePipeline from "../FeatureSource/FeaturePipeline";
import OsmApiFeatureSource from "../FeatureSource/OsmApiFeatureSource";
/** /**
* Makes sure the hash shows the selected element and vice-versa * Makes sure the hash shows the selected element and vice-versa.
*/ */
export default class SelectedFeatureHandler { export default class SelectedFeatureHandler {
private readonly _featureSource: FeatureSource; private readonly _featureSource: FeatureSource;
@ -10,13 +14,16 @@ export default class SelectedFeatureHandler {
private readonly _selectedFeature: UIEventSource<any>; private readonly _selectedFeature: UIEventSource<any>;
private static readonly _no_trigger_on = ["welcome","copyright","layers"] private static readonly _no_trigger_on = ["welcome","copyright","layers"]
private readonly _osmApiSource: OsmApiFeatureSource;
constructor(hash: UIEventSource<string>, constructor(hash: UIEventSource<string>,
selectedFeature: UIEventSource<any>, selectedFeature: UIEventSource<any>,
featureSource: FeatureSource) { featureSource: FeaturePipeline,
osmApiSource: OsmApiFeatureSource) {
this._hash = hash; this._hash = hash;
this._selectedFeature = selectedFeature; this._selectedFeature = selectedFeature;
this._featureSource = featureSource; this._featureSource = featureSource;
this._osmApiSource = osmApiSource;
const self = this; const self = this;
hash.addCallback(h => { hash.addCallback(h => {
if (h === undefined || h === "") { if (h === undefined || h === "") {
@ -26,6 +33,8 @@ export default class SelectedFeatureHandler {
} }
}) })
hash.addCallbackAndRun(h => self.downloadFeature(h))
featureSource.features.addCallback(_ => self.selectFeature()); featureSource.features.addCallback(_ => self.selectFeature());
selectedFeature.addCallback(feature => { selectedFeature.addCallback(feature => {
@ -45,6 +54,32 @@ export default class SelectedFeatureHandler {
} }
// If a feature is selected via the hash, zoom there
public zoomToSelectedFeature(location: UIEventSource<Loc>){
const hash = this._hash.data;
if(hash === undefined || SelectedFeatureHandler._no_trigger_on.indexOf(hash) >= 0){
return; // No valid feature selected
}
// We should have a valid osm-ID and zoom to it
OsmObject.DownloadObject(hash, (element: OsmObject, meta: OsmObjectMeta) => {
const centerpoint = element.centerpoint();
console.log("Zooming to location for select point: ", centerpoint)
location.data.lat = centerpoint[0]
location.data.lon = centerpoint[1]
location.ping();
})
}
private downloadFeature(hash: string){
if(hash === undefined || hash === ""){
return;
}
if(SelectedFeatureHandler._no_trigger_on.indexOf(hash) >= 0){
return;
}
this._osmApiSource.load(hash)
}
private selectFeature(){ private selectFeature(){
const features = this._featureSource?.features?.data; const features = this._featureSource?.features?.data;
if(features === undefined){ if(features === undefined){

View file

@ -1,42 +0,0 @@
import {UIEventSource} from "../UIEventSource";
import {ElementStorage} from "../ElementStorage";
import {OsmObject, OsmObjectMeta} from "../Osm/OsmObject";
export default class UpdateTagsFromOsmAPI {
/***
* This actor downloads the element from the OSM-API and updates the corresponding tags in the UI-updater.
*/
constructor(idToDownload: UIEventSource<string>, allElements: ElementStorage, callback? : (element: OsmObject) => void) {
idToDownload.addCallbackAndRun(id => {
if (id === undefined) {
return;
}
OsmObject.DownloadObject(id, (element: OsmObject, meta: OsmObjectMeta) => {
console.debug("Updating tags from the OSM-API: ", element)
const tags = element.tags;
tags["_last_edit:contributor"] = meta["_last_edit:contributor"]
tags["_last_edit:contributor:uid"] = meta["_last_edit:contributor:uid"]
tags["_last_edit:changeset"] = meta["_last_edit:changeset"]
tags["_last_edit:timestamp"] = meta["_last_edit:timestamp"].toLocaleString()
tags["_version_number"] = meta._version_number
if (!allElements.has(id)) {
console.warn("Adding element by id")
allElements.addElementById(id, new UIEventSource<any>(tags))
} else {
// We merge
console.warn("merging by OSM API UPDATE")
allElements.addOrGetById(id, tags)
}
})
})
}
}

View file

@ -48,6 +48,7 @@ export class ElementStorage {
const keptKeys = es.data; const keptKeys = es.data;
// The element already exists // The element already exists
// We use the new feature to overwrite all the properties in the already existing eventsource // We use the new feature to overwrite all the properties in the already existing eventsource
console.log("Merging multiple instances of ", elementId)
let somethingChanged = false; let somethingChanged = false;
for (const k in newProperties) { for (const k in newProperties) {
const v = newProperties[k]; const v = newProperties[k];

View file

@ -18,27 +18,32 @@ export default class FeaturePipeline implements FeatureSource {
public features: UIEventSource<{ feature: any; freshness: Date }[]>; public features: UIEventSource<{ feature: any; freshness: Date }[]>;
public readonly name = "FeaturePipeline" public readonly name = "FeaturePipeline"
constructor(flayers: UIEventSource<{ isDisplayed: UIEventSource<boolean>, layerDef: LayerConfig }[]>, constructor(flayers: UIEventSource<{ isDisplayed: UIEventSource<boolean>, layerDef: LayerConfig }[]>,
updater: FeatureSource, updater: FeatureSource,
fromOsmApi: FeatureSource,
layout: UIEventSource<LayoutConfig>, layout: UIEventSource<LayoutConfig>,
newPoints: FeatureSource, newPoints: FeatureSource,
locationControl: UIEventSource<Loc>) { locationControl: UIEventSource<Loc>,
selectedElement: UIEventSource<any>) {
// first we metatag, then we save to get the metatags into storage too
// Note that we need to register before we do metatagging (as it expects the event sources)
const amendedOverpassSource = const amendedOverpassSource =
new RememberingSource( new RememberingSource(
new LocalStorageSaver( new LocalStorageSaver(
new MetaTaggingFeatureSource( // first we metatag, then we save to get the metatags into storage too new FeatureDuplicatorPerLayer(flayers,
new RegisteringFeatureSource( new MetaTaggingFeatureSource(
new FeatureDuplicatorPerLayer(flayers, new RegisteringFeatureSource(
updater) updater)
)), layout)); )), layout));
const geojsonSources: FeatureSource [] = GeoJsonSource const geojsonSources: FeatureSource [] = GeoJsonSource
.ConstructMultiSource(flayers.data, locationControl) .ConstructMultiSource(flayers.data, locationControl)
.map(geojsonSource => new RegisteringFeatureSource(new FeatureDuplicatorPerLayer(flayers, geojsonSource))); .map(geojsonSource => new RegisteringFeatureSource(new FeatureDuplicatorPerLayer(flayers, geojsonSource)));
const amendedLocalStorageSource = const amendedLocalStorageSource =
new RememberingSource(new RegisteringFeatureSource(new FeatureDuplicatorPerLayer(flayers, new LocalStorageSource(layout)) new RememberingSource(new RegisteringFeatureSource(new FeatureDuplicatorPerLayer(flayers, new LocalStorageSource(layout))
)); ));
@ -46,10 +51,16 @@ export default class FeaturePipeline implements FeatureSource {
newPoints = new MetaTaggingFeatureSource(new FeatureDuplicatorPerLayer(flayers, newPoints = new MetaTaggingFeatureSource(new FeatureDuplicatorPerLayer(flayers,
new RegisteringFeatureSource(newPoints))); new RegisteringFeatureSource(newPoints)));
const amendedOsmApiSource = new RememberingSource(
new FeatureDuplicatorPerLayer(flayers,
new MetaTaggingFeatureSource(
new RegisteringFeatureSource(fromOsmApi))));
const merged = const merged =
new FeatureSourceMerger([ new FeatureSourceMerger([
amendedOverpassSource, amendedOverpassSource,
amendedOsmApiSource,
amendedLocalStorageSource, amendedLocalStorageSource,
newPoints, newPoints,
...geojsonSources ...geojsonSources
@ -60,6 +71,7 @@ export default class FeaturePipeline implements FeatureSource {
new FilteringFeatureSource( new FilteringFeatureSource(
flayers, flayers,
locationControl, locationControl,
selectedElement,
merged merged
)); ));
this.features = source.features; this.features = source.features;

View file

@ -5,12 +5,14 @@ import Loc from "../../Models/Loc";
export default class FilteringFeatureSource implements FeatureSource { export default class FilteringFeatureSource implements FeatureSource {
public features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); public features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]);
public readonly name = "FilteringFeatureSource" public readonly name = "FilteringFeatureSource"
constructor(layers: UIEventSource<{ constructor(layers: UIEventSource<{
isDisplayed: UIEventSource<boolean>, isDisplayed: UIEventSource<boolean>,
layerDef: LayerConfig layerDef: LayerConfig
}[]>, }[]>,
location: UIEventSource<Loc>, location: UIEventSource<Loc>,
selectedElement: UIEventSource<any>,
upstream: FeatureSource) { upstream: FeatureSource) {
const self = this; const self = this;
@ -18,7 +20,7 @@ public readonly name = "FilteringFeatureSource"
function update() { function update() {
const layerDict = {}; const layerDict = {};
if(layers.data.length == 0){ if (layers.data.length == 0) {
throw "No layers defined!" throw "No layers defined!"
} }
for (const layer of layers.data) { for (const layer of layers.data) {
@ -32,6 +34,11 @@ public readonly name = "FilteringFeatureSource"
const newFeatures = features.filter(f => { const newFeatures = features.filter(f => {
const layerId = f.feature._matching_layer_id; const layerId = f.feature._matching_layer_id;
if(selectedElement.data === f.feature){
// This is the selected object - it gets a free pass even if zoom is not sufficient
return true;
}
if (layerId !== undefined) { if (layerId !== undefined) {
const layer: { const layer: {
isDisplayed: UIEventSource<boolean>, isDisplayed: UIEventSource<boolean>,
@ -41,16 +48,16 @@ public readonly name = "FilteringFeatureSource"
missingLayers.add(layerId) missingLayers.add(layerId)
return true; return true;
} }
const isShown = layer.layerDef.isShown const isShown = layer.layerDef.isShown
const tags = f.feature.properties; const tags = f.feature.properties;
if(isShown.IsKnown(tags)){ if (isShown.IsKnown(tags)) {
const result = layer.layerDef.isShown.GetRenderValue(f.feature.properties).txt; const result = layer.layerDef.isShown.GetRenderValue(f.feature.properties).txt;
if(result !== "yes"){ if (result !== "yes") {
return false; return false;
} }
} }
if (FilteringFeatureSource.showLayer(layer, location)) { if (FilteringFeatureSource.showLayer(layer, location)) {
return true; return true;
} }
@ -69,7 +76,7 @@ public readonly name = "FilteringFeatureSource"
}); });
console.log("Filtering layer source: input: ", upstream.features.data?.length, "output:", newFeatures.length) console.log("Filtering layer source: input: ", upstream.features.data?.length, "output:", newFeatures.length)
self.features.setData(newFeatures); self.features.setData(newFeatures);
if(missingLayers.size > 0){ if (missingLayers.size > 0) {
console.error("Some layers were not found: ", Array.from(missingLayers)) console.error("Some layers were not found: ", Array.from(missingLayers))
} }
} }
@ -86,7 +93,7 @@ public readonly name = "FilteringFeatureSource"
if (l.zoom < layer.layerDef.minzoom) { if (l.zoom < layer.layerDef.minzoom) {
continue; continue;
} }
if(l.zoom > layer.layerDef.maxzoom){ if (l.zoom > layer.layerDef.maxzoom) {
continue; continue;
} }
if (!layer.isDisplayed.data) { if (!layer.isDisplayed.data) {
@ -98,13 +105,13 @@ public readonly name = "FilteringFeatureSource"
}).addCallback(() => { }).addCallback(() => {
update(); update();
}); });
layers.addCallback(update); layers.addCallback(update);
const registered = new Set<UIEventSource<boolean>>(); const registered = new Set<UIEventSource<boolean>>();
layers.addCallbackAndRun(layers => { layers.addCallbackAndRun(layers => {
for (const layer of layers) { for (const layer of layers) {
if(registered.has(layer.isDisplayed)){ if (registered.has(layer.isDisplayed)) {
continue; continue;
} }
registered.add(layer.isDisplayed); registered.add(layer.isDisplayed);

View file

@ -0,0 +1,21 @@
import FeatureSource from "./FeatureSource";
import {UIEventSource} from "../UIEventSource";
import {OsmObject} from "../Osm/OsmObject";
export default class OsmApiFeatureSource implements FeatureSource {
public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]);
public readonly name: string = "OsmApiFeatureSource";
public load(id: string){
console.log("Updating from OSM API: ", id)
OsmObject.DownloadObject(id, (element, meta) => {
const geojson = element.asGeoJson();
console.warn(geojson)
geojson.id = geojson.properties.id;
this.features.setData([{feature:geojson, freshness: meta["_last_edit:timestamp"]}])
})
}
}

View file

@ -1,9 +1,7 @@
import LayerConfig from "../Customizations/JSON/LayerConfig"; import LayerConfig from "../Customizations/JSON/LayerConfig";
import SimpleMetaTagger from "./SimpleMetaTagger"; import SimpleMetaTagger from "./SimpleMetaTagger";
import {ExtraFunction} from "./ExtraFunction"; import {ExtraFunction} from "./ExtraFunction";
import State from "../State";
import {Relation} from "./Osm/ExtractRelations"; import {Relation} from "./Osm/ExtractRelations";
import {meta} from "@turf/turf";
interface Params { interface Params {

View file

@ -13,6 +13,9 @@ export abstract class OsmObject {
protected constructor(type: string, id: number) { protected constructor(type: string, id: number) {
this.id = id; this.id = id;
this.type = type; this.type = type;
this.tags = {
id: id
}
} }
static DownloadObject(id, continuation: ((element: OsmObject, meta: OsmObjectMeta) => void)) { static DownloadObject(id, continuation: ((element: OsmObject, meta: OsmObjectMeta) => void)) {
@ -20,7 +23,7 @@ export abstract class OsmObject {
const type = splitted[0]; const type = splitted[0];
const idN = splitted[1]; const idN = splitted[1];
const newContinuation = (element: OsmObject, meta :OsmObjectMeta) => { const newContinuation = (element: OsmObject, meta: OsmObjectMeta) => {
console.log("Received: ", element, "with meta", meta); console.log("Received: ", element, "with meta", meta);
continuation(element, meta); continuation(element, meta);
} }
@ -59,7 +62,12 @@ export abstract class OsmObject {
); );
} }
abstract SaveExtraData(element); // The centerpoint of the feature, as [lat, lon]
public abstract centerpoint(): [number, number];
public abstract asGeoJson(): any;
abstract SaveExtraData(element: any, allElements: any[]);
/** /**
* Generates the changeset-XML for tags * Generates the changeset-XML for tags
@ -78,12 +86,21 @@ export abstract class OsmObject {
Download(continuation: ((element: OsmObject, meta: OsmObjectMeta) => void)) { Download(continuation: ((element: OsmObject, meta: OsmObjectMeta) => void)) {
const self = this; const self = this;
$.getJSON("https://www.openstreetmap.org/api/0.6/" + this.type + "/" + this.id, const full = this.type !== "way" ? "" : "/full";
function (data) { const url = "https://www.openstreetmap.org/api/0.6/" + this.type + "/" + this.id + full;
const element = data.elements[0]; $.getJSON(url, function (data) {
const element = data.elements[data.elements.length - 1];
self.tags = element.tags; self.tags = element.tags;
const tgs = self.tags;
tgs["_last_edit:contributor"] = element.user
tgs["_last_edit:contributor:uid"] = element.uid
tgs["_last_edit:changeset"] = element.changeset
tgs["_last_edit:timestamp"] = element.timestamp
tgs["_version_number"] = element.version
tgs["id"] = self.type+"/"+self.id;
self.version = element.version; self.version = element.version;
self.SaveExtraData(element); self.SaveExtraData(element, data.elements);
continuation(self, { continuation(self, {
"_last_edit:contributor": element.user, "_last_edit:contributor": element.user,
"_last_edit:contributor:uid": element.uid, "_last_edit:contributor:uid": element.uid,
@ -135,21 +152,36 @@ export class OsmNode extends OsmObject {
ChangesetXML(changesetId: string): string { ChangesetXML(changesetId: string): string {
let tags = this.TagsXML(); let tags = this.TagsXML();
let change = return ' <node id="' + this.id + '" changeset="' + changesetId + '" ' + this.VersionXML() + ' lat="' + this.lat + '" lon="' + this.lon + '">\n' +
' <node id="' + this.id + '" changeset="' + changesetId + '" ' + this.VersionXML() + ' lat="' + this.lat + '" lon="' + this.lon + '">\n' +
tags + tags +
' </node>\n'; ' </node>\n';
return change;
} }
SaveExtraData(element) { SaveExtraData(element) {
this.lat = element.lat; this.lat = element.lat;
this.lon = element.lon; this.lon = element.lon;
} }
centerpoint(): [number, number] {
return [this.lat, this.lon];
}
asGeoJson() {
return {
"type": "Feature",
"properties": this.tags,
"geometry": {
"type": "Point",
"coordinates": [
this.lon,
this.lat
]
}
}
}
} }
export interface OsmObjectMeta{ export interface OsmObjectMeta {
"_last_edit:contributor": string, "_last_edit:contributor": string,
"_last_edit:contributor:uid": number, "_last_edit:contributor:uid": number,
"_last_edit:changeset": number, "_last_edit:changeset": number,
@ -161,12 +193,19 @@ export interface OsmObjectMeta{
export class OsmWay extends OsmObject { export class OsmWay extends OsmObject {
nodes: number[]; nodes: number[];
coordinates: [number, number][] = []
lat: number;
lon: number;
constructor(id) { constructor(id) {
super("way", id); super("way", id);
} }
centerpoint(): [number, number] {
return [this.lat, this.lon];
}
ChangesetXML(changesetId: string): string { ChangesetXML(changesetId: string): string {
let tags = this.TagsXML(); let tags = this.TagsXML();
let nds = ""; let nds = "";
@ -174,18 +213,40 @@ export class OsmWay extends OsmObject {
nds += ' <nd ref="' + this.nodes[node] + '"/>\n'; nds += ' <nd ref="' + this.nodes[node] + '"/>\n';
} }
let change = return ' <way id="' + this.id + '" changeset="' + changesetId + '" ' + this.VersionXML() + '>\n' +
' <way id="' + this.id + '" changeset="' + changesetId + '" ' + this.VersionXML() + '>\n' +
nds + nds +
tags + tags +
' </way>\n'; ' </way>\n';
return change;
} }
SaveExtraData(element) { SaveExtraData(element, allNodes) {
console.log("Way-extras: ", allNodes)
for (const node of allNodes) {
if (node.type === "node") {
const n = new OsmNode(node.id);
n.SaveExtraData(node)
const cp = n.centerpoint();
this.coordinates.push(cp);
}
}
let count = this.coordinates.length;
this.lat = this.coordinates.map(c => c[0]).reduce((a, b) => a + b, 0) / count;
this.lon = this.coordinates.map(c => c[1]).reduce((a, b) => a + b, 0) / count;
this.nodes = element.nodes; this.nodes = element.nodes;
} }
asGeoJson() {
return {
"type": "Feature",
"properties": this.tags,
"geometry": {
"type": "LineString",
"coordinates": this.coordinates.map(c => [c[1], c[0]])
}
}
}
} }
export class OsmRelation extends OsmObject { export class OsmRelation extends OsmObject {
@ -197,24 +258,29 @@ export class OsmRelation extends OsmObject {
} }
centerpoint(): [number, number] {
return [0, 0]; // TODO
}
ChangesetXML(changesetId: string): string { ChangesetXML(changesetId: string): string {
let members = ""; let members = "";
for (const memberI in this.members) { for (const member of this.members) {
const member = this.members[memberI];
members += ' <member type="' + member.type + '" ref="' + member.ref + '" role="' + member.role + '"/>\n'; members += ' <member type="' + member.type + '" ref="' + member.ref + '" role="' + member.role + '"/>\n';
} }
let tags = this.TagsXML(); let tags = this.TagsXML();
let change = return ' <relation id="' + this.id + '" changeset="' + changesetId + '" ' + this.VersionXML() + '>\n' +
' <relation id="' + this.id + '" changeset="' + changesetId + '" ' + this.VersionXML() + '>\n' +
members + members +
tags + tags +
' </relation>\n'; ' </relation>\n';
return change;
} }
SaveExtraData(element) { SaveExtraData(element) {
this.members = element.members; this.members = element.members;
} }
asGeoJson() {
throw "Not Implemented"
}
} }

View file

@ -7,7 +7,6 @@ import {Utils} from "../Utils";
import opening_hours from "opening_hours"; import opening_hours from "opening_hours";
import {UIElement} from "../UI/UIElement"; import {UIElement} from "../UI/UIElement";
import Combine from "../UI/Base/Combine"; import Combine from "../UI/Base/Combine";
import UpdateTagsFromOsmAPI from "./Actors/UpdateTagsFromOsmAPI";
const cardinalDirections = { const cardinalDirections = {

View file

@ -2,7 +2,7 @@ import { Utils } from "../Utils";
export default class Constants { export default class Constants {
public static vNumber = "0.7.0c"; public static vNumber = "0.7.1";
// The user journey states thresholds when a new feature gets unlocked // The user journey states thresholds when a new feature gets unlocked
public static userJourney = { public static userJourney = {

View file

@ -18,7 +18,7 @@ import LayerConfig from "./Customizations/JSON/LayerConfig";
import TitleHandler from "./Logic/Actors/TitleHandler"; import TitleHandler from "./Logic/Actors/TitleHandler";
import PendingChangesUploader from "./Logic/Actors/PendingChangesUploader"; import PendingChangesUploader from "./Logic/Actors/PendingChangesUploader";
import {Relation} from "./Logic/Osm/ExtractRelations"; import {Relation} from "./Logic/Osm/ExtractRelations";
import UpdateTagsFromOsmAPI from "./Logic/Actors/UpdateTagsFromOsmAPI"; import OsmApiFeatureSource from "./Logic/FeatureSource/OsmApiFeatureSource";
/** /**
* Contains the global state: a bunch of UI-event sources * Contains the global state: a bunch of UI-event sources
@ -58,6 +58,8 @@ export default class State {
public favouriteLayers: UIEventSource<string[]>; public favouriteLayers: UIEventSource<string[]>;
public layerUpdater: UpdateFromOverpass; public layerUpdater: UpdateFromOverpass;
public osmApiFeatureSource : OsmApiFeatureSource = new OsmApiFeatureSource();
public filteredLayers: UIEventSource<{ public filteredLayers: UIEventSource<{
@ -253,8 +255,6 @@ export default class State {
new TitleHandler(this.layoutToUse, this.selectedElement, this.allElements); new TitleHandler(this.layoutToUse, this.selectedElement, this.allElements);
new UpdateTagsFromOsmAPI(this.selectedElement.map(el => el?.properties?.id), this.allElements)
} }
private static asFloat(source: UIEventSource<string>): UIEventSource<number> { private static asFloat(source: UIEventSource<string>): UIEventSource<number> {

View file

@ -1,4 +1,3 @@
import {VerticalCombine} from "../Base/VerticalCombine";
import {UIElement} from "../UIElement"; import {UIElement} from "../UIElement";
import {VariableUiElement} from "../Base/VariableUIElement"; import {VariableUiElement} from "../Base/VariableUIElement";
import LayoutConfig from "../../Customizations/JSON/LayoutConfig"; import LayoutConfig from "../../Customizations/JSON/LayoutConfig";
@ -53,15 +52,17 @@ export default class MoreScreen extends UIElement {
if(path === ""){ if(path === ""){
path = "." path = "."
} }
const params = `z=${currentLocation.zoom ?? 1}&lat=${currentLocation.lat ?? 0}&lon=${currentLocation.lon ?? 0}`
let linkText = let linkText =
`${path}/${layout.id.toLowerCase()}?z=${currentLocation.zoom}&lat=${currentLocation.lat}&lon=${currentLocation.lon}` `${path}/${layout.id.toLowerCase()}?${params}`
if (location.hostname === "localhost" || location.hostname === "127.0.0.1") { if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
linkText = `${path}/index.html?layout=${layout.id}&z=${currentLocation.zoom}&lat=${currentLocation.lat}&lon=${currentLocation.lon}` linkText = `${path}/index.html?layout=${layout.id}&${params}`
} }
if (customThemeDefinition) { if (customThemeDefinition) {
linkText = `${path}/?userlayout=${layout.id}&z=${currentLocation.zoom}&lat=${currentLocation.lat}&lon=${currentLocation.lon}#${customThemeDefinition}` linkText = `${path}/?userlayout=${layout.id}&${params}#${customThemeDefinition}`
} }