forked from MapComplete/MapComplete
Fix #287
This commit is contained in:
parent
da7c9951c0
commit
99a6321cc9
2 changed files with 77 additions and 27 deletions
|
@ -5,7 +5,6 @@ import List from "../UI/Base/List"
|
|||
import Title from "../UI/Base/Title"
|
||||
import { BBox } from "./BBox"
|
||||
import { Feature, Geometry, MultiPolygon, Polygon } from "geojson"
|
||||
import { GeoJSONFeature } from "maplibre-gl"
|
||||
|
||||
export interface ExtraFuncParams {
|
||||
/**
|
||||
|
@ -508,9 +507,9 @@ export class ExtraFunctions {
|
|||
public static constructHelpers(
|
||||
params: ExtraFuncParams
|
||||
): Record<ExtraFuncType, (feature: Feature) => Function> {
|
||||
const record: Record<string, (feature: GeoJSONFeature) => Function> = {}
|
||||
const record: Record<string, (feature: Feature) => Function> = {}
|
||||
for (const f of ExtraFunctions.allFuncs) {
|
||||
if (this.types.indexOf(<any>f._name) < 0) {
|
||||
if ((<readonly string[]> this.types).indexOf(f._name) < 0) {
|
||||
throw "Invalid extraFunc-type: " + f._name
|
||||
}
|
||||
record[f._name] = (feat) => f._f(params, feat)
|
||||
|
|
|
@ -9,11 +9,14 @@ import { IndexedFeatureSource } from "./FeatureSource/FeatureSource"
|
|||
import OsmObjectDownloader from "./Osm/OsmObjectDownloader"
|
||||
import { Utils } from "../Utils"
|
||||
import { Store, UIEventSource } from "./UIEventSource"
|
||||
import { selectDefault } from "../Utils/selectDefault"
|
||||
|
||||
/**
|
||||
* Metatagging adds various tags to the elements, e.g. lat, lon, surface area, ...
|
||||
*
|
||||
* All metatags start with an underscore
|
||||
* All metatags start with an underscore.
|
||||
*
|
||||
* Will apply the metatags as soon as they are passed in
|
||||
*/
|
||||
export default class MetaTagging {
|
||||
private static errorPrintCount = 0
|
||||
|
@ -23,6 +26,18 @@ export default class MetaTagging {
|
|||
string,
|
||||
((feature: Feature, propertiesStore: UIEventSource<any>) => void)[]
|
||||
>()
|
||||
private state: {
|
||||
readonly selectedElement: Store<Feature>;
|
||||
readonly layout: LayoutConfig;
|
||||
readonly osmObjectDownloader: OsmObjectDownloader;
|
||||
readonly perLayer: ReadonlyMap<string, GeoIndexedStoreForLayer>;
|
||||
readonly indexedFeatures: IndexedFeatureSource;
|
||||
readonly featureProperties: FeaturePropertiesStore
|
||||
}
|
||||
private params: {
|
||||
getFeatureById: (id) => Feature;
|
||||
getFeaturesWithin: (layerId, bbox) => (Feature[][] | [Feature[]])
|
||||
}
|
||||
|
||||
constructor(state: {
|
||||
readonly selectedElement: Store<Feature>
|
||||
|
@ -32,7 +47,8 @@ export default class MetaTagging {
|
|||
readonly indexedFeatures: IndexedFeatureSource
|
||||
readonly featureProperties: FeaturePropertiesStore
|
||||
}) {
|
||||
const params = MetaTagging.createExtraFuncParams(state)
|
||||
this.state = state
|
||||
const params = this.params = MetaTagging.createExtraFuncParams(state)
|
||||
for (const layer of state.layout.layers) {
|
||||
if (layer.source === null) {
|
||||
continue
|
||||
|
@ -61,21 +77,55 @@ export default class MetaTagging {
|
|||
})
|
||||
}
|
||||
|
||||
state.selectedElement.addCallbackAndRunD((feature) => {
|
||||
const layer = state.layout.getMatchingLayer(feature.properties)
|
||||
// Force update the tags of the currently selected element
|
||||
MetaTagging.addMetatags(
|
||||
[feature],
|
||||
params,
|
||||
layer,
|
||||
state.layout,
|
||||
state.osmObjectDownloader,
|
||||
state.featureProperties,
|
||||
{
|
||||
evaluateStrict: true,
|
||||
// Force update the tags of the currently selected element
|
||||
state.selectedElement.addCallbackAndRunD(feature => {
|
||||
this.updateCurrentSelectedElement()
|
||||
let lastUpdateMoment = new Date()
|
||||
const tags = state?.featureProperties?.getStore(feature.properties.id)
|
||||
console.log("Binding an updater to", feature)
|
||||
tags?.addCallbackD(() => {
|
||||
console.log("Received an update!")
|
||||
if(feature !== state.selectedElement.data){
|
||||
return true // Unregister, we are not the selected element anymore
|
||||
}
|
||||
)
|
||||
if(new Date().getTime() - lastUpdateMoment.getTime() < 250){
|
||||
return
|
||||
}
|
||||
lastUpdateMoment = new Date()
|
||||
window.requestIdleCallback(() => {
|
||||
this.updateCurrentSelectedElement()
|
||||
lastUpdateMoment = new Date()
|
||||
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers an update of the calculated tags of the selected element
|
||||
* @private
|
||||
*/
|
||||
private updateCurrentSelectedElement() {
|
||||
const feature = this.state.selectedElement.data
|
||||
if (!feature) {
|
||||
return
|
||||
}
|
||||
const state = this.state
|
||||
const layer = state.layout.getMatchingLayer(feature.properties)
|
||||
// Force update if the tags of the element changed
|
||||
MetaTagging.addMetatags(
|
||||
[feature],
|
||||
this.params,
|
||||
layer,
|
||||
state.layout,
|
||||
state.osmObjectDownloader,
|
||||
state.featureProperties,
|
||||
{
|
||||
evaluateStrict: true
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
|
@ -142,7 +192,7 @@ export default class MetaTagging {
|
|||
const feature = features[i]
|
||||
const tags = featurePropertiesStores?.getStore(feature.properties.id)
|
||||
let somethingChanged = false
|
||||
let definedTags = new Set(Object.getOwnPropertyNames(feature.properties))
|
||||
const definedTags = new Set(Object.getOwnPropertyNames(feature.properties))
|
||||
|
||||
for (const metatag of metatagsToApply) {
|
||||
try {
|
||||
|
@ -161,6 +211,7 @@ export default class MetaTagging {
|
|||
metatag.applyMetaTagsOnFeature(feature, layer, tags, state)
|
||||
if (options?.evaluateStrict) {
|
||||
for (const key of metatag.keys) {
|
||||
// Important: we _have_ to evaluate this as this might trigger a calculation
|
||||
const evaluated = feature.properties[key]
|
||||
if (evaluated !== undefined) {
|
||||
strictlyEvaluated++
|
||||
|
@ -211,6 +262,7 @@ export default class MetaTagging {
|
|||
atLeastOneFeatureChanged = true
|
||||
}
|
||||
}
|
||||
console.debug("Strictly evaluated ", strictlyEvaluated, " values") // Do not remove this
|
||||
return atLeastOneFeatureChanged
|
||||
}
|
||||
|
||||
|
@ -228,12 +280,12 @@ export default class MetaTagging {
|
|||
})
|
||||
return feats
|
||||
}
|
||||
if(!state.perLayer.get(layerId)){
|
||||
if (!state.perLayer.get(layerId)) {
|
||||
// This layer is not loaded
|
||||
return []
|
||||
}
|
||||
return [state.perLayer.get(layerId).GetFeaturesWithin(bbox)]
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,8 +330,8 @@ export default class MetaTagging {
|
|||
if (MetaTagging.errorPrintCount < MetaTagging.stopErrorOutputAt) {
|
||||
console.warn(
|
||||
"Could not calculate a " +
|
||||
(isStrict ? "strict " : "") +
|
||||
"calculated tag for key",
|
||||
(isStrict ? "strict " : "") +
|
||||
"calculated tag for key",
|
||||
key,
|
||||
"for feature",
|
||||
feat.properties.id,
|
||||
|
@ -287,9 +339,9 @@ export default class MetaTagging {
|
|||
code,
|
||||
"(in layer",
|
||||
layerId +
|
||||
") due to \n" +
|
||||
e +
|
||||
"\n. Are you the theme creator? Doublecheck your code. Note that the metatags might not be stable on new features",
|
||||
") due to \n" +
|
||||
e +
|
||||
"\n. Are you the theme creator? Doublecheck your code. Note that the metatags might not be stable on new features",
|
||||
e,
|
||||
e.stack,
|
||||
{ feat }
|
||||
|
@ -328,7 +380,6 @@ export default class MetaTagging {
|
|||
|
||||
const funcName = "metaTaggging_for_" + id
|
||||
if (typeof MetaTagging.metataggingObject[funcName] !== "function") {
|
||||
console.log(MetaTagging.metataggingObject)
|
||||
throw (
|
||||
"Error: metatagging-object for this theme does not have an entry at " +
|
||||
funcName +
|
||||
|
|
Loading…
Reference in a new issue