forked from MapComplete/MapComplete
Performance improvements, add clock
This commit is contained in:
parent
c2b1f6643b
commit
efd7631837
21 changed files with 2947 additions and 105 deletions
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue