From b5693304f2138d859a673f50aca7428c40ddcb8f Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 14 Nov 2021 18:01:48 +0100 Subject: [PATCH] Better tag rendering stealing capacity --- Customizations/AllKnownLayers.ts | 99 ++++++++------- Models/ThemeConfig/TagRenderingConfig.ts | 12 +- Models/ThemeConfig/WithContextLoader.ts | 55 ++++++--- test.ts | 151 +---------------------- 4 files changed, 104 insertions(+), 213 deletions(-) diff --git a/Customizations/AllKnownLayers.ts b/Customizations/AllKnownLayers.ts index cf6aa010fc..8e00fef453 100644 --- a/Customizations/AllKnownLayers.ts +++ b/Customizations/AllKnownLayers.ts @@ -10,23 +10,75 @@ export default class AllKnownLayers { public static inited = (_ => { WithContextLoader.getKnownTagRenderings = (id => AllKnownLayers.getTagRendering(id)) - return true + return true })() - + // Must be below the list... public static sharedLayers: Map = AllKnownLayers.getSharedLayers(); public static sharedLayersJson: Map = AllKnownLayers.getSharedLayersJson(); - public static added_by_default: string[] = ["gps_location","gps_location_history", "home_location", "gps_track",] - public static no_include: string[] = [ "conflation", "left_right_style"] + public static added_by_default: string[] = ["gps_location", "gps_location_history", "home_location", "gps_track",] + public static no_include: string[] = ["conflation", "left_right_style"] /** * Layer IDs of layers which have special properties through built-in hooks */ - public static priviliged_layers: string[] = [...AllKnownLayers.added_by_default, "type_node",...AllKnownLayers.no_include] + public static priviliged_layers: string[] = [...AllKnownLayers.added_by_default, "type_node", ...AllKnownLayers.no_include] + /** + * Gets the appropriate tagRenderingJSON + * Allows to steal them from other layers. + * This will add the tags of the layer to the configuration though! + * @param renderingId + */ + static getTagRendering(renderingId: string): TagRenderingConfigJson[] { + if (renderingId.indexOf(".") < 0) { + const found = SharedTagRenderings.SharedTagRenderingJson.get(renderingId) + if(found === undefined){ + return [] + } + return [found] + } + const [layerId, id] = renderingId.split(".") + const layer = AllKnownLayers.getSharedLayersJson().get(layerId) + if (layer === undefined) { + if (Utils.runningFromConsole) { + // Probably generating the layer overview + return [{ + id: "dummy" + }] + } + throw "Builtin layer " + layerId + " not found" + } + + const renderings = layer?.tagRenderings ?? [] + if (id === "*") { + return JSON.parse(JSON.stringify(renderings)) + } + + const selectByGroup = id.startsWith("*") + const expectedGroupName = id.substring(1) + + const allValidValues = [] + for (const rendering of renderings) { + if ((!selectByGroup && rendering["id"] === id) || (selectByGroup && rendering["group"] === expectedGroupName)) { + const found = JSON.parse(JSON.stringify(rendering)) + if (found.condition === undefined) { + found.condition = layer.source.osmTags + } else { + found.condition = {and: [found.condition, layer.source.osmTags]} + } + allValidValues.push(found) + } + } + if(allValidValues.length === 0){ + + throw `The rendering with id ${id} was not found in the builtin layer ${layerId}. Try one of ${Utils.NoNull(renderings.map(r => r["id"])).join(", ")}` + } + return allValidValues + } private static getSharedLayers(): Map { const sharedLayers = new Map(); @@ -75,41 +127,4 @@ export default class AllKnownLayers { return sharedLayers; } - /** - * Gets the appropriate tagRenderingJSON - * Allows to steal them from other layers. - * This will add the tags of the layer to the configuration though! - * @param renderingId - */ - static getTagRendering(renderingId: string): TagRenderingConfigJson { - if(renderingId.indexOf(".") < 0){ - return SharedTagRenderings.SharedTagRenderingJson.get(renderingId) - } - - const [layerId, id] = renderingId.split(".") - const layer = AllKnownLayers.getSharedLayersJson().get(layerId) - if(layer === undefined){ - if(Utils.runningFromConsole){ - // Probably generating the layer overview - return { - id: "dummy" - } - } - throw "Builtin layer "+layerId+" not found" - } - const renderings = layer?.tagRenderings ?? [] - for (const rendering of renderings) { - if(rendering["id"] === id){ - const found = JSON.parse(JSON.stringify(rendering)) - if(found.condition === undefined){ - found.condition = layer.source.osmTags - }else{ - found.condition = {and: [found.condition, layer.source.osmTags]} - } - return found - } - } - throw `The rendering with id ${id} was not found in the builtin layer ${layerId}. Try one of ${Utils.NoNull(renderings.map(r => r["id"])).join(", ")}` - } - } diff --git a/Models/ThemeConfig/TagRenderingConfig.ts b/Models/ThemeConfig/TagRenderingConfig.ts index c1374b7eef..6716b63ab5 100644 --- a/Models/ThemeConfig/TagRenderingConfig.ts +++ b/Models/ThemeConfig/TagRenderingConfig.ts @@ -42,6 +42,9 @@ export default class TagRenderingConfig { }[] constructor(json: string | TagRenderingConfigJson, context?: string) { + if (json === undefined) { + throw "Initing a TagRenderingConfig with undefined in " + context; + } if (json === "questions") { // Very special value @@ -55,14 +58,11 @@ export default class TagRenderingConfig { if (typeof json === "number") { - this.render = Translations.T("" + json, context + ".render") - return; + json = ""+json } - if (json === undefined) { - throw "Initing a TagRenderingConfig with undefined in " + context; - } + if (typeof json === "string") { this.render = Translations.T(json, context + ".render"); this.multiAnswer = false; @@ -75,6 +75,8 @@ export default class TagRenderingConfig { throw "Invalid ID in "+context+": an id can only contain [a-zA-Z0-0_-] as characters. The offending id is: "+this.id } + + this.group = json.group ?? ""; this.render = Translations.T(json.render, context + ".render"); this.question = Translations.T(json.question, context + ".question"); diff --git a/Models/ThemeConfig/WithContextLoader.ts b/Models/ThemeConfig/WithContextLoader.ts index ed9e2580a2..87ba16bb6b 100644 --- a/Models/ThemeConfig/WithContextLoader.ts +++ b/Models/ThemeConfig/WithContextLoader.ts @@ -7,8 +7,13 @@ export default class WithContextLoader { protected readonly _context: string; private readonly _json: any; - public static getKnownTagRenderings : ((id: string) => TagRenderingConfigJson)= function(id) { - return SharedTagRenderings.SharedTagRenderingJson.get(id) + public static getKnownTagRenderings : ((id: string) => TagRenderingConfigJson[])= function(id) { + const found = SharedTagRenderings.SharedTagRenderingJson.get(id) + if(found !== undefined){ + return [found] + }else{ + return [] + } } constructor(json: any, context: string) { @@ -64,36 +69,54 @@ export default class WithContextLoader { } const context = this._context - const renderings: TagRenderingConfig[] = [] options = options ?? {} if (options.prepConfig === undefined) { options.prepConfig = c => c } + const preparedConfigs : TagRenderingConfigJson[] = [] for (let i = 0; i < tagRenderings.length; i++) { let renderingJson = tagRenderings[i] if (typeof renderingJson === "string") { renderingJson = {builtin: renderingJson, override: undefined} } - if (renderingJson["builtin"] !== undefined) { - const renderingId = renderingJson["builtin"] - let sharedJson = WithContextLoader.getKnownTagRenderings(renderingId) - if (sharedJson === undefined) { - const keys = Array.from(SharedTagRenderings.SharedTagRenderingJson.keys()); - throw `Predefined tagRendering ${renderingId} not found in ${context}.\n Try one of ${keys.join( - ", " - )}\n If you intent to output this text literally, use {\"render\": } instead"}`; - } + if (renderingJson["builtin"] === undefined) { + const patchedConfig = options.prepConfig(renderingJson) + preparedConfigs.push(patchedConfig) + continue + + } + + + const renderingId = renderingJson["builtin"] + let sharedJsons = [] + if(typeof renderingId === "string"){ + sharedJsons = WithContextLoader.getKnownTagRenderings(renderingId) + }else{ + sharedJsons = [].concat( ...(renderingId).map(id => WithContextLoader.getKnownTagRenderings(id) ) ) + } + + if (sharedJsons.length === 0) { + const keys = Array.from(SharedTagRenderings.SharedTagRenderingJson.keys()); + throw `Predefined tagRendering ${renderingId} not found in ${context}.\n Try one of ${keys.join( + ", " + )}\n If you intent to output this text literally, use {\"render\": } instead"}`; + } + for (let sharedJson of sharedJsons) { if (renderingJson["override"] !== undefined) { sharedJson = Utils.Merge(renderingJson["override"], JSON.parse(JSON.stringify(sharedJson))) } - renderingJson = sharedJson + + const patchedConfig = options.prepConfig(sharedJson) + preparedConfigs.push(patchedConfig) } + } - const patchedConfig = options.prepConfig(renderingJson) - - const tr = new TagRenderingConfig(patchedConfig, `${context}.tagrendering[${i}]`); + const renderings: TagRenderingConfig[] = [] + for (let i = 0; i < preparedConfigs.length; i++){ + const preparedConfig = preparedConfigs[i]; + const tr = new TagRenderingConfig(preparedConfig, `${context}.tagrendering[${i}]`); if(options.readOnlyMode && tr.question !== undefined){ throw "A question is defined for "+`${context}.tagrendering[${i}], but this is not allowed at this position - probably because this rendering is an icon, badge or label` } diff --git a/test.ts b/test.ts index 7141bb366c..d9d131fdf8 100644 --- a/test.ts +++ b/test.ts @@ -1,150 +1 @@ -import ShowDataLayer from "./UI/ShowDataLayer/ShowDataLayer"; -import AllKnownLayers from "./Customizations/AllKnownLayers"; -import Minimap from "./UI/Base/Minimap"; -import StaticFeatureSource from "./Logic/FeatureSource/Sources/StaticFeatureSource"; -import MinimapImplementation from "./UI/Base/MinimapImplementation"; -import AvailableBaseLayers from "./Logic/Actors/AvailableBaseLayers"; -import BaseLayer from "./Models/BaseLayer"; -import {UIEventSource} from "./Logic/UIEventSource"; -import AvailableBaseLayersImplementation from "./Logic/Actors/AvailableBaseLayersImplementation"; - -MinimapImplementation.initialize() -AvailableBaseLayers.implement(new AvailableBaseLayersImplementation()) -const confirmationMap = Minimap.createMiniMap({ - background: new UIEventSource(AvailableBaseLayers.osmCarto) -}) -const features = [{ - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 1728823483}, - "geometry": { - "type": "LineString", - "coordinates": [[3.216693, 51.2147409], [3.2166930000000225, 51.214740500000055]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 1728823481}, - "geometry": { - "type": "LineString", - "coordinates": [[3.2167247, 51.2146969], [3.21671060000004, 51.2147159000002]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 1728823481}, - "geometry": { - "type": "LineString", - "coordinates": [[3.2167247, 51.2146969], [3.2167241999999976, 51.214696799999714]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 1728823549}, - "geometry": { - "type": "LineString", - "coordinates": [[3.2168871, 51.2147399], [3.2168876999999547, 51.21474009999989]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 4978289383}, - "geometry": { - "type": "LineString", - "coordinates": [[3.2169973, 51.2147676], [3.2169969000000034, 51.21476780000005]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 4978289388}, - "geometry": { - "type": "LineString", - "coordinates": [[3.2169829, 51.2147884], [3.2169673999999895, 51.21481170000002]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 4978289388}, - "geometry": { - "type": "LineString", - "coordinates": [[3.2169829, 51.2147884], [3.216949899999979, 51.214808000000225]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 4978289388}, - "geometry": {"type": "LineString", "coordinates": [[3.2169829, 51.2147884], [3.2169306, 51.21480400000028]]} - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 4978289388}, - "geometry": { - "type": "LineString", - "coordinates": [[3.2169829, 51.2147884], [3.2169465999999756, 51.214779199999825]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 4978288381}, - "geometry": { - "type": "LineString", - "coordinates": [[3.2168856, 51.2147638], [3.216885599999961, 51.214763799999986]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 4978289386}, - "geometry": { - "type": "LineString", - "coordinates": [[3.2168815, 51.2147718], [3.216881100000038, 51.21477160000009]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 4978289384}, - "geometry": { - "type": "LineString", - "coordinates": [[3.2168674, 51.2147683], [3.216867399999983, 51.214768400000224]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 1728823514}, - "geometry": { - "type": "LineString", - "coordinates": [[3.2168551, 51.2147863], [3.2168551000000436, 51.21478629999984]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}, { - "feature": { - "type": "Feature", - "properties": {"move": "yes", "osm-id": 1728823483}, - "geometry": { - "type": "LineString", - "coordinates": [[3.216693, 51.2147409], [3.2166930000000225, 51.214740500000055]] - } - }, "freshness": "2021-11-02T20:06:53.088Z" -}] -const changePreview = new StaticFeatureSource(features.map(f => f.feature), false) -console.log("ChangePreview", changePreview.features.data) -new ShowDataLayer({ - leafletMap: confirmationMap.leafletMap, - enablePopups: false, - zoomToFeatures: true, - features: changePreview, - layerToShow: AllKnownLayers.sharedLayers.get("conflation") -}) - -confirmationMap.SetStyle("height: 20rem").SetClass("w-full").AttachTo("maindiv") \ No newline at end of file +console.log("Tests...") \ No newline at end of file