Better tag rendering stealing capacity

This commit is contained in:
pietervdvn 2021-11-14 18:01:48 +01:00
parent c940890eca
commit b5693304f2
4 changed files with 104 additions and 213 deletions

View file

@ -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<string, LayerConfig> = AllKnownLayers.getSharedLayers();
public static sharedLayersJson: Map<string, any> = 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 <TagRenderingConfigJson[]>[{
id: "dummy"
}]
}
throw "Builtin layer " + layerId + " not found"
}
const renderings = layer?.tagRenderings ?? []
if (id === "*") {
return <TagRenderingConfigJson[]>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 = <TagRenderingConfigJson>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<string, LayerConfig> {
const sharedLayers = new Map<string, LayerConfig>();
@ -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 <TagRenderingConfigJson> {
id: "dummy"
}
}
throw "Builtin layer "+layerId+" not found"
}
const renderings = layer?.tagRenderings ?? []
for (const rendering of renderings) {
if(rendering["id"] === id){
const found = <TagRenderingConfigJson> 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(", ")}`
}
}

View file

@ -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");

View file

@ -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\": <your text>} instead"}`;
}
if (renderingJson["builtin"] === undefined) {
const patchedConfig = options.prepConfig(<TagRenderingConfigJson>renderingJson)
preparedConfigs.push(patchedConfig)
continue
}
const renderingId = renderingJson["builtin"]
let sharedJsons = []
if(typeof renderingId === "string"){
sharedJsons = WithContextLoader.getKnownTagRenderings(renderingId)
}else{
sharedJsons = [].concat( ...(<string[]>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\": <your text>} 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(<TagRenderingConfigJson>sharedJson)
preparedConfigs.push(patchedConfig)
}
}
const patchedConfig = options.prepConfig(<TagRenderingConfigJson>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`
}

151
test.ts
View file

@ -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<BaseLayer>(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")
console.log("Tests...")