Performance improvements, add clock

This commit is contained in:
Pieter Vander Vennet 2020-12-05 03:22:17 +01:00
parent c2b1f6643b
commit efd7631837
21 changed files with 2947 additions and 105 deletions

View file

@ -42,10 +42,14 @@ export class ElementStorage {
}
}
getElement(elementId): UIEventSource<any> {
getEventSourceById(elementId): UIEventSource<any> {
if (elementId in this._elements) {
return this._elements[elementId];
}
console.log("Can not find eventsource with id ", elementId);
console.error("Can not find eventsource with id ", elementId);
}
getEventSourceFor(feature): UIEventSource<any> {
return this.getEventSourceById(feature.properties.id);
}
}

View file

@ -7,6 +7,7 @@ import {UIElement} from "../UI/UIElement";
import State from "../State";
import LayerConfig from "../Customizations/JSON/LayerConfig";
import Hash from "./Web/Hash";
import LazyElement from "../UI/Base/LazyElement";
/***
* A filtered layer is a layer which offers a 'set-data' function
@ -78,7 +79,7 @@ export class FilteredLayer {
const tags = TagUtils.proprtiesToKV(feature.properties);
const matches = this.filters.matches(tags);
if (matches) {
selfFeatures.push(feature);
selfFeatures.push(feature);
}
if (!matches || this.layerDef.passAllFeatures) {
leftoverFeatures.push(feature);
@ -130,14 +131,13 @@ export class FilteredLayer {
let self = this;
this._geolayer = L.geoJSON(data, {
style: feature => {
const tagsSource = State.state.allElements.getElement(feature.properties.id);
const tagsSource = State.state.allElements.getEventSourceFor(feature);
return self.layerDef.GenerateLeafletStyle(tagsSource, self._showOnPopup !== undefined);
},
pointToLayer: function (feature, latLng) {
// Point to layer converts the 'point' to a layer object - as the geojson layer natively cannot handle points
// Click handling is done in the next step
const tagSource = State.state.allElements.getElement(feature.properties.id);
const tagSource = State.state.allElements.getEventSourceFor(feature);
const style = self.layerDef.GenerateLeafletStyle(tagSource, self._showOnPopup !== undefined);
let marker;
@ -169,10 +169,9 @@ export class FilteredLayer {
closeOnEscapeKey: true,
}, layer);
let uiElement: UIElement;
const eventSource = State.state.allElements.addOrGetElement(feature);
uiElement = self._showOnPopup(eventSource, feature);
const eventSource = State.state.allElements.getEventSourceFor(feature);
let uiElement: LazyElement = new LazyElement(() => self._showOnPopup(eventSource, feature));
popup.setContent(uiElement.Render());
layer.bindPopup(popup);
// We first render the UIelement (which'll still need an update later on...)
@ -181,11 +180,16 @@ export class FilteredLayer {
layer.on("click", (e) => {
// We set the element as selected...
uiElement.Activate();
State.state.selectedElement.setData(feature);
uiElement.Update();
});
if (feature.properties.id.replace(/\//g, "_") === Hash.Get().data) {
// This element is in the URL, so this is a share link
// We already open it
uiElement.Activate();
popup.setContent(uiElement.Render());
const center = GeoOperations.centerpoint(feature).geometry.coordinates;
popup.setLatLng({lat: center[1], lng: center[0]});
popup.openOn(State.state.bm.map);

View file

@ -1,11 +1,9 @@
import {GeoOperations} from "./GeoOperations";
import CodeGrid from "./Web/CodeGrid";
import State from "../State";
import opening_hours from "opening_hours";
import {And, Or, Tag} from "./Tags";
import {Utils} from "../Utils";
import CountryCoder from "latlon2country/lib/countryCoder";
import CountryCoder from "latlon2country"
class SimpleMetaTagger {
private _f: (feature: any, index: number) => void;
@ -62,57 +60,60 @@ export default class MetaTagging {
})
);
private static country = new SimpleMetaTagger(
["_country"], "",
((feature, index) => {
["_country"], "The country code of the property (with latlon2country)",
(feature, index) => {
const coder = new CountryCoder("https://pietervdvn.github.io/latlon2country/");
const centerPoint = GeoOperations.centerpoint(feature);
let centerPoint: any = GeoOperations.centerpoint(feature);
const lat = centerPoint.geometry.coordinates[1];
const lon = centerPoint.geometry.coordinates[0]
// But the codegrid SHOULD be a number!
coder.CountryCodeFor(lon, lat, (countries) => {
feature.properties["_country"] = countries[0];
console.log("Country is ",countries.join(";"))
coder.GetCountryCodeFor(lon, lat, (countries) => {
feature.properties["_country"] = countries[0].trim().toLowerCase();
const tagsSource = State.state.allElements.getEventSourceFor(feature);
tagsSource.ping();
});
})
}
)
private static isOpen = new SimpleMetaTagger(
["_isOpen", "_isOpen:description"],
"If 'opening_hours' is present, it will add the current state of the feature (being 'yes' or 'no')",
(feature => {
const tagsSource = State.state.allElements.addOrGetElement(feature);
tagsSource.addCallback(tags => {
if (tags["opening_hours"] !== undefined && tags["_country"] !== undefined) {
if (tags._isOpen !== undefined) {
// Already defined
return;
}
const oh = new opening_hours(tags["opening_hours"], {
lat: tags._lat,
lon: tags._lon,
address: {
country_code: tags._country.toLowerCase()
}
}, {tag_key: "opening_hours"});
const updateTags = () => {
tags["_isOpen"] = oh.getState() ? "yes" : "no";
const comment = oh.getComment();
if (comment) {
tags["_isOpen:description"] = comment;
}
const nextChange = oh.getNextChange() as Date;
if (nextChange !== undefined) {
window.setTimeout(
updateTags,
(nextChange.getTime() - (new Date()).getTime())
)
}
}
updateTags();
const tagsSource = State.state.allElements.getEventSourceFor(feature);
tagsSource.addCallbackAndRun(tags => {
if (tags.opening_hours === undefined || tags._country === undefined) {
return;
}
const oh = new opening_hours(tags["opening_hours"], {
lat: tags._lat,
lon: tags._lon,
address: {
country_code: tags._country.toLowerCase()
}
}, {tag_key: "opening_hours"});
// AUtomatically triggered on the next change
const updateTags = () => {
const oldValueIsOpen = tags["_isOpen"];
tags["_isOpen"] = oh.getState() ? "yes" : "no";
const comment = oh.getComment();
if (comment) {
tags["_isOpen:description"] = comment;
}
if (oldValueIsOpen !== tags._isOpen) {
tagsSource.ping();
}
const nextChange = oh.getNextChange() as Date;
if (nextChange !== undefined) {
window.setTimeout(
updateTags,
(nextChange.getTime() - (new Date()).getTime())
)
}
}
updateTags();
})
})

View file

@ -18,7 +18,7 @@ export class Changes {
if (changes.length == 0) {
return;
}
const eventSource = tags ?? State.state?.allElements.getElement(elementId);
const eventSource = tags ?? State.state?.allElements.getEventSourceById(elementId);
const elementTags = eventSource.data;
const pending : {elementId:string, key: string, value: string}[] = [];
for (const change of changes) {

View file

@ -181,7 +181,7 @@ export class ChangesetHandler {
continue;
}
console.log("Rewriting id: ", oldId, "-->", newId);
const element = allElements.getElement("node/" + oldId);
const element = allElements.getEventSourceById("node/" + oldId);
element.data.id = "node/" + newId;
allElements.addElementById("node/" + newId, element);
element.ping();

View file

@ -96,17 +96,20 @@ export class UpdateFromOverpass {
const self = this;
self.retries.setData(0);
let newIds = 1;
for (const feature of geojson.features) {
if(feature.properties.id === undefined){
feature.properties.id = "ext/"+newIds;
if (feature.properties.id === undefined) {
feature.properties.id = "ext/" + newIds;
newIds++;
}
}
geojson.features.forEach(feature => {
State.state.allElements.addElement(feature);
})
MetaTagging.addMetatags(geojson.features);
function renderLayers(layers: FilteredLayer[]) {
if (layers.length === 0) {
self.runningQuery.setData(false);
@ -125,6 +128,7 @@ export class UpdateFromOverpass {
}, 50)
}
renderLayers(State.state.filteredLayers.data);
}