From 65b1891cb6da5d23d74f1e72710ca0cc6525b0c7 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sat, 11 Dec 2021 02:19:28 +0100 Subject: [PATCH] Add metacalculation on currentview --- Customizations/AllKnownLayers.ts | 4 +-- Logic/FeatureSource/FeaturePipeline.ts | 34 +++++++++++--------- Logic/MetaTagging.ts | 18 ++++++++--- UI/BigComponents/LeftControls.ts | 7 ++-- assets/layers/current_view/current_view.json | 3 +- assets/themes/grb_import/grb.json | 31 ++++++++++++++++++ assets/themes/grb_import/license_info.json | 10 ++++++ assets/themes/grb_import/robot.svg | 5 +++ 8 files changed, 85 insertions(+), 27 deletions(-) create mode 100644 assets/themes/grb_import/robot.svg diff --git a/Customizations/AllKnownLayers.ts b/Customizations/AllKnownLayers.ts index a4a9d6c9d..4f142cfeb 100644 --- a/Customizations/AllKnownLayers.ts +++ b/Customizations/AllKnownLayers.ts @@ -20,8 +20,8 @@ export default class AllKnownLayers { public static sharedLayersJson: Map = AllKnownLayers.getSharedLayersJson(); - public static added_by_default: string[] = ["gps_location", "gps_location_history", "home_location", "gps_track","current_view"] - public static no_include: string[] = ["conflation", "left_right_style", "split_point"] + public static added_by_default: string[] = ["gps_location", "gps_location_history", "home_location", "gps_track"] + public static no_include: string[] = ["conflation", "left_right_style", "split_point","current_view"] /** * Layer IDs of layers which have special properties through built-in hooks */ diff --git a/Logic/FeatureSource/FeaturePipeline.ts b/Logic/FeatureSource/FeaturePipeline.ts index baed7e682..6cb3cc110 100644 --- a/Logic/FeatureSource/FeaturePipeline.ts +++ b/Logic/FeatureSource/FeaturePipeline.ts @@ -56,7 +56,7 @@ export default class FeaturePipeline { private readonly oldestAllowedDate: Date; private readonly osmSourceZoomLevel - + private readonly localStorageSavers = new Map() private readonly metataggingRecalculated = new UIEventSource(undefined) @@ -97,7 +97,7 @@ export default class FeaturePipeline { this.perLayerHierarchy = perLayerHierarchy // Given a tile, wraps it and passes it on to render (handled by 'handleFeatureSource' - function patchedHandleFeatureSource (src: FeatureSourceForLayer & IndexedFeatureSource & Tiled) { + function patchedHandleFeatureSource(src: FeatureSourceForLayer & IndexedFeatureSource & Tiled) { // This will already contain the merged features for this tile. In other words, this will only be triggered once for every tile const srcFiltered = new FilteringFeatureSource(state, src.tileIndex, @@ -110,14 +110,14 @@ export default class FeaturePipeline { // We do not mark as visited here, this is the responsability of the code near the actual loader (e.g. overpassLoader and OSMApiFeatureLoader) } - function handlePriviligedFeatureSource(src: FeatureSourceForLayer & Tiled){ + function handlePriviligedFeatureSource(src: FeatureSourceForLayer & Tiled) { // Passthrough to passed function, except that it registers as well handleFeatureSource(src) src.features.addCallbackAndRunD(fs => { - fs.forEach(ff => state.allElements.addOrGetElement(ff.feature)) + fs.forEach(ff => state.allElements.addOrGetElement(ff.feature)) }) } - + for (const filteredLayer of state.filteredLayers.data) { const id = filteredLayer.layerDef.id @@ -155,10 +155,11 @@ export default class FeaturePipeline { if (id === "current_view") { handlePriviligedFeatureSource(state.currentView) + state.currentView.features.map(ffs => ffs[0]?.feature?.properties?.id).withEqualityStabilized((x,y) => x === y).addCallbackAndRunD(_ => self.applyMetaTags(state.currentView)) continue } - - const localTileSaver = new SaveTileToLocalStorageActor(filteredLayer) + + const localTileSaver = new SaveTileToLocalStorageActor(filteredLayer) this.localStorageSavers.set(filteredLayer.layerDef.id, localTileSaver) if (source.geojsonSource === undefined) { @@ -220,8 +221,8 @@ export default class FeaturePipeline { new RegisteringAllFromFeatureSourceActor(tile, state.allElements) if (tile.layer.layerDef.maxAgeOfCache > 0) { const saver = self.localStorageSavers.get(tile.layer.layerDef.id) - if(saver === undefined){ - console.error("No localStorageSaver found for layer ",tile.layer.layerDef.id) + if (saver === undefined) { + console.error("No localStorageSaver found for layer ", tile.layer.layerDef.id) } saver?.addTile(tile) } @@ -234,12 +235,12 @@ export default class FeaturePipeline { state.filteredLayers.data.forEach(flayer => { const layer = flayer.layerDef if (layer.maxAgeOfCache > 0) { - const saver = self.localStorageSavers.get(layer.id) - if(saver === undefined){ - console.error("No local storage saver found for ", layer.id) - }else{ - saver.MarkVisited(tileId, new Date()) - } + const saver = self.localStorageSavers.get(layer.id) + if (saver === undefined) { + console.error("No local storage saver found for ", layer.id) + } else { + saver.MarkVisited(tileId, new Date()) + } } self.freshnesses.get(layer.id).addTileLoad(tileId, new Date()) }) @@ -458,7 +459,7 @@ export default class FeaturePipeline { { memberships: this.relationTracker, getFeaturesWithin: (layerId, bbox: BBox) => self.GetFeaturesWithin(layerId, bbox), - getFeatureById: (id:string) => self.state.allElements.ContainingFeatures.get(id) + getFeatureById: (id: string) => self.state.allElements.ContainingFeatures.get(id) }, layerDef, { @@ -481,6 +482,7 @@ export default class FeaturePipeline { self.applyMetaTags(tile) }) }) + this.applyMetaTags(this.state.currentView) self.metataggingRecalculated.ping() } diff --git a/Logic/MetaTagging.ts b/Logic/MetaTagging.ts index 42608e202..73342f964 100644 --- a/Logic/MetaTagging.ts +++ b/Logic/MetaTagging.ts @@ -70,7 +70,7 @@ export default class MetaTagging { // @ts-ignore metatag.applyMetaTagsOnFeature(feature, freshness, layer) - + } else { @@ -121,8 +121,8 @@ export default class MetaTagging { const func = new Function("feat", "return " + code + ";"); const f = (feature: any) => { - - + + delete feature.properties[key] Object.defineProperty(feature.properties, key, { configurable: true, @@ -144,7 +144,7 @@ export default class MetaTagging { return result; } catch (e) { if (MetaTagging.errorPrintCount < MetaTagging.stopErrorOutputAt) { - console.warn("Could not calculate a calculated tag for key "+key+" defined by " + 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", e, e.stack) + console.warn("Could not calculate a calculated tag for key " + key + " defined by " + 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", e, e.stack) MetaTagging.errorPrintCount++; if (MetaTagging.errorPrintCount == MetaTagging.stopErrorOutputAt) { console.error("Got ", MetaTagging.stopErrorOutputAt, " errors calculating this metatagging - stopping output now") @@ -162,6 +162,8 @@ export default class MetaTagging { return functions; } + private static retaggingFuncCache = new Map void)[]>() + private static createRetaggingFunc(layer: LayerConfig): ((params: ExtraFuncParams, feature: any) => void) { @@ -170,6 +172,13 @@ export default class MetaTagging { return undefined; } + let functions = MetaTagging.retaggingFuncCache.get(layer.id); + if (functions === undefined) { + functions = MetaTagging.createFunctionsForFeature(layer.id, calculatedTags) + MetaTagging.retaggingFuncCache.set(layer.id, functions) + } + + return (params: ExtraFuncParams, feature) => { const tags = feature.properties if (tags === undefined) { @@ -177,7 +186,6 @@ export default class MetaTagging { } try { - const functions = MetaTagging.createFunctionsForFeature(layer.id, calculatedTags) ExtraFunctions.FullPatchFeature(params, feature); for (const f of functions) { f(feature); diff --git a/UI/BigComponents/LeftControls.ts b/UI/BigComponents/LeftControls.ts index a0a5e215c..f8d6784af 100644 --- a/UI/BigComponents/LeftControls.ts +++ b/UI/BigComponents/LeftControls.ts @@ -57,14 +57,15 @@ export default class LeftControls extends Combine { return defaultIcon; } const tags = {...feature.properties, button: "yes"} - const elem = currentViewFL.layerDef.mapRendering[0]?.GenerateLeafletStyle(tags, false, { + const elem = currentViewFL.layerDef.mapRendering[0]?.GenerateLeafletStyle(new UIEventSource(tags), false, { noSize: true })?.html + console.log("Elem is ", elem, "for", tags) if(elem === undefined){ return defaultIcon } return elem - })) + })).SetClass("inline-block w-full h-full") const featureBox = new VariableUiElement(feature.map(feature => { if(feature === undefined){return undefined} @@ -81,7 +82,7 @@ export default class LeftControls extends Combine { guiState.currentViewControlIsOpened ) - }).SetClass("inline-block w-full").onClick(() => { + }).onClick(() => { guiState.currentViewControlIsOpened.setData(true) }), diff --git a/assets/layers/current_view/current_view.json b/assets/layers/current_view/current_view.json index 8d873863d..b3649f4bd 100644 --- a/assets/layers/current_view/current_view.json +++ b/assets/layers/current_view/current_view.json @@ -2,7 +2,8 @@ "id": "current_view", "description": "A meta-layer which contains one single feature, namely the BBOX of the current map view. This can be used to trigger special actions. If a popup is defined for this layer, this popup will be accessible via an extra button on screen.\n\nThe icon on the button is the default icon of the layer, but can be customized by detecting 'button=yes'.", "source": { - "osmTags": "current_view=yes" + "osmTags": "current_view=yes", + "maxCacheAge": 0 }, "shownByDefault": false, "title": "Current View", diff --git a/assets/themes/grb_import/grb.json b/assets/themes/grb_import/grb.json index e6b7b6d50..95d63ca25 100644 --- a/assets/themes/grb_import/grb.json +++ b/assets/themes/grb_import/grb.json @@ -29,6 +29,37 @@ "minzoom": 19 }, "layers": [ + { + "builtin": "current_view", + "override": { + "+mapRendering": [ + { + "location": ["point"], + "icon": { + "render": "./assets/themes/grb_import/robot.svg" + }, + "iconSize": "15,15,center" + } + ], + "calculatedTags": [ + "_x='y'", + "_embedded_crab_addresses=feat.overlapWith('crab_address').length" + ], + "tagRenderings": [ + { + "id": "hw", + "render": "There are {_embedded_crab_addresses} adresses in view", + "mappings": [{ + "if": "_embedded_crab_addresses=", + "then": "Loading..." + },{ + "if": "_embedded_crab_addresses=0", + "then": "No CRAB addresses in view. Zoom in more to see them" + }] + } + ] + } + }, { "builtin": "type_node", "override": { diff --git a/assets/themes/grb_import/license_info.json b/assets/themes/grb_import/license_info.json index 8ea1617ec..a3deb7f3e 100644 --- a/assets/themes/grb_import/license_info.json +++ b/assets/themes/grb_import/license_info.json @@ -6,5 +6,15 @@ "Pieter Vander Vennet" ], "sources": [] + }, + { + "path": "robot.svg", + "license": "CC-BY 4.0 International", + "authors": [ + "Font Awesome" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Font_Awesome_5_solid_robot.svg" + ] } ] \ No newline at end of file diff --git a/assets/themes/grb_import/robot.svg b/assets/themes/grb_import/robot.svg new file mode 100644 index 000000000..5eb96529f --- /dev/null +++ b/assets/themes/grb_import/robot.svg @@ -0,0 +1,5 @@ + + \ No newline at end of file