Add metacalculation on currentview

This commit is contained in:
Pieter Vander Vennet 2021-12-11 02:19:28 +01:00
parent c76b0a6340
commit 65b1891cb6
8 changed files with 85 additions and 27 deletions

View file

@ -20,8 +20,8 @@ export default class AllKnownLayers {
public static sharedLayersJson: Map<string, any> = AllKnownLayers.getSharedLayersJson(); public static sharedLayersJson: Map<string, any> = AllKnownLayers.getSharedLayersJson();
public static added_by_default: string[] = ["gps_location", "gps_location_history", "home_location", "gps_track","current_view"] 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"] 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 * Layer IDs of layers which have special properties through built-in hooks
*/ */

View file

@ -56,7 +56,7 @@ export default class FeaturePipeline {
private readonly oldestAllowedDate: Date; private readonly oldestAllowedDate: Date;
private readonly osmSourceZoomLevel private readonly osmSourceZoomLevel
private readonly localStorageSavers = new Map<string, SaveTileToLocalStorageActor>() private readonly localStorageSavers = new Map<string, SaveTileToLocalStorageActor>()
private readonly metataggingRecalculated = new UIEventSource<void>(undefined) private readonly metataggingRecalculated = new UIEventSource<void>(undefined)
@ -97,7 +97,7 @@ export default class FeaturePipeline {
this.perLayerHierarchy = perLayerHierarchy this.perLayerHierarchy = perLayerHierarchy
// Given a tile, wraps it and passes it on to render (handled by 'handleFeatureSource' // 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 // This will already contain the merged features for this tile. In other words, this will only be triggered once for every tile
const srcFiltered = const srcFiltered =
new FilteringFeatureSource(state, src.tileIndex, 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) // 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 // Passthrough to passed function, except that it registers as well
handleFeatureSource(src) handleFeatureSource(src)
src.features.addCallbackAndRunD(fs => { 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) { for (const filteredLayer of state.filteredLayers.data) {
const id = filteredLayer.layerDef.id const id = filteredLayer.layerDef.id
@ -155,10 +155,11 @@ export default class FeaturePipeline {
if (id === "current_view") { if (id === "current_view") {
handlePriviligedFeatureSource(state.currentView) handlePriviligedFeatureSource(state.currentView)
state.currentView.features.map(ffs => ffs[0]?.feature?.properties?.id).withEqualityStabilized((x,y) => x === y).addCallbackAndRunD(_ => self.applyMetaTags(state.currentView))
continue continue
} }
const localTileSaver = new SaveTileToLocalStorageActor(filteredLayer) const localTileSaver = new SaveTileToLocalStorageActor(filteredLayer)
this.localStorageSavers.set(filteredLayer.layerDef.id, localTileSaver) this.localStorageSavers.set(filteredLayer.layerDef.id, localTileSaver)
if (source.geojsonSource === undefined) { if (source.geojsonSource === undefined) {
@ -220,8 +221,8 @@ export default class FeaturePipeline {
new RegisteringAllFromFeatureSourceActor(tile, state.allElements) new RegisteringAllFromFeatureSourceActor(tile, state.allElements)
if (tile.layer.layerDef.maxAgeOfCache > 0) { if (tile.layer.layerDef.maxAgeOfCache > 0) {
const saver = self.localStorageSavers.get(tile.layer.layerDef.id) const saver = self.localStorageSavers.get(tile.layer.layerDef.id)
if(saver === undefined){ if (saver === undefined) {
console.error("No localStorageSaver found for layer ",tile.layer.layerDef.id) console.error("No localStorageSaver found for layer ", tile.layer.layerDef.id)
} }
saver?.addTile(tile) saver?.addTile(tile)
} }
@ -234,12 +235,12 @@ export default class FeaturePipeline {
state.filteredLayers.data.forEach(flayer => { state.filteredLayers.data.forEach(flayer => {
const layer = flayer.layerDef const layer = flayer.layerDef
if (layer.maxAgeOfCache > 0) { if (layer.maxAgeOfCache > 0) {
const saver = self.localStorageSavers.get(layer.id) const saver = self.localStorageSavers.get(layer.id)
if(saver === undefined){ if (saver === undefined) {
console.error("No local storage saver found for ", layer.id) console.error("No local storage saver found for ", layer.id)
}else{ } else {
saver.MarkVisited(tileId, new Date()) saver.MarkVisited(tileId, new Date())
} }
} }
self.freshnesses.get(layer.id).addTileLoad(tileId, new Date()) self.freshnesses.get(layer.id).addTileLoad(tileId, new Date())
}) })
@ -458,7 +459,7 @@ export default class FeaturePipeline {
{ {
memberships: this.relationTracker, memberships: this.relationTracker,
getFeaturesWithin: (layerId, bbox: BBox) => self.GetFeaturesWithin(layerId, bbox), 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, layerDef,
{ {
@ -481,6 +482,7 @@ export default class FeaturePipeline {
self.applyMetaTags(tile) self.applyMetaTags(tile)
}) })
}) })
this.applyMetaTags(this.state.currentView)
self.metataggingRecalculated.ping() self.metataggingRecalculated.ping()
} }

View file

@ -70,7 +70,7 @@ export default class MetaTagging {
// @ts-ignore // @ts-ignore
metatag.applyMetaTagsOnFeature(feature, freshness, layer) metatag.applyMetaTagsOnFeature(feature, freshness, layer)
} else { } else {
@ -121,8 +121,8 @@ export default class MetaTagging {
const func = new Function("feat", "return " + code + ";"); const func = new Function("feat", "return " + code + ";");
const f = (feature: any) => { const f = (feature: any) => {
delete feature.properties[key] delete feature.properties[key]
Object.defineProperty(feature.properties, key, { Object.defineProperty(feature.properties, key, {
configurable: true, configurable: true,
@ -144,7 +144,7 @@ export default class MetaTagging {
return result; return result;
} catch (e) { } catch (e) {
if (MetaTagging.errorPrintCount < MetaTagging.stopErrorOutputAt) { 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++; MetaTagging.errorPrintCount++;
if (MetaTagging.errorPrintCount == MetaTagging.stopErrorOutputAt) { if (MetaTagging.errorPrintCount == MetaTagging.stopErrorOutputAt) {
console.error("Got ", MetaTagging.stopErrorOutputAt, " errors calculating this metatagging - stopping output now") console.error("Got ", MetaTagging.stopErrorOutputAt, " errors calculating this metatagging - stopping output now")
@ -162,6 +162,8 @@ export default class MetaTagging {
return functions; return functions;
} }
private static retaggingFuncCache = new Map<string, ((feature: any) => void)[]>()
private static createRetaggingFunc(layer: LayerConfig): private static createRetaggingFunc(layer: LayerConfig):
((params: ExtraFuncParams, feature: any) => void) { ((params: ExtraFuncParams, feature: any) => void) {
@ -170,6 +172,13 @@ export default class MetaTagging {
return undefined; 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) => { return (params: ExtraFuncParams, feature) => {
const tags = feature.properties const tags = feature.properties
if (tags === undefined) { if (tags === undefined) {
@ -177,7 +186,6 @@ export default class MetaTagging {
} }
try { try {
const functions = MetaTagging.createFunctionsForFeature(layer.id, calculatedTags)
ExtraFunctions.FullPatchFeature(params, feature); ExtraFunctions.FullPatchFeature(params, feature);
for (const f of functions) { for (const f of functions) {
f(feature); f(feature);

View file

@ -57,14 +57,15 @@ export default class LeftControls extends Combine {
return defaultIcon; return defaultIcon;
} }
const tags = {...feature.properties, button: "yes"} 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 noSize: true
})?.html })?.html
console.log("Elem is ", elem, "for", tags)
if(elem === undefined){ if(elem === undefined){
return defaultIcon return defaultIcon
} }
return elem return elem
})) })).SetClass("inline-block w-full h-full")
const featureBox = new VariableUiElement(feature.map(feature => { const featureBox = new VariableUiElement(feature.map(feature => {
if(feature === undefined){return undefined} if(feature === undefined){return undefined}
@ -81,7 +82,7 @@ export default class LeftControls extends Combine {
guiState.currentViewControlIsOpened guiState.currentViewControlIsOpened
) )
}).SetClass("inline-block w-full").onClick(() => { }).onClick(() => {
guiState.currentViewControlIsOpened.setData(true) guiState.currentViewControlIsOpened.setData(true)
}), }),

View file

@ -2,7 +2,8 @@
"id": "current_view", "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'.", "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": { "source": {
"osmTags": "current_view=yes" "osmTags": "current_view=yes",
"maxCacheAge": 0
}, },
"shownByDefault": false, "shownByDefault": false,
"title": "Current View", "title": "Current View",

View file

@ -29,6 +29,37 @@
"minzoom": 19 "minzoom": 19
}, },
"layers": [ "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", "builtin": "type_node",
"override": { "override": {

View file

@ -6,5 +6,15 @@
"Pieter Vander Vennet" "Pieter Vander Vennet"
], ],
"sources": [] "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"
]
} }
] ]

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M0 256v128c0 17.7 14.3 32 32 32h32V224H32c-17.7 0-32 14.3-32 32zM464 96H352V32c0-17.7-14.3-32-32-32s-32 14.3-32 32v64H176c-44.2 0-80 35.8-80 80v272c0 35.3 28.7 64 64 64h320c35.3 0 64-28.7 64-64V176c0-44.2-35.8-80-80-80zM256 416h-64v-32h64v32zm-32-120c-22.1 0-40-17.9-40-40s17.9-40 40-40 40 17.9 40 40-17.9 40-40 40zm128 120h-64v-32h64v32zm96 0h-64v-32h64v32zm-32-120c-22.1 0-40-17.9-40-40s17.9-40 40-40 40 17.9 40 40-17.9 40-40 40zm192-72h-32v192h32c17.7 0 32-14.3 32-32V256c0-17.7-14.3-32-32-32z"/></svg>
<!--
Font Awesome Free 5.2.0 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->

After

Width:  |  Height:  |  Size: 751 B