forked from MapComplete/MapComplete
Better tag rendering stealing capacity
This commit is contained in:
parent
c940890eca
commit
b5693304f2
4 changed files with 104 additions and 213 deletions
|
@ -10,23 +10,75 @@ export default class AllKnownLayers {
|
||||||
|
|
||||||
public static inited = (_ => {
|
public static inited = (_ => {
|
||||||
WithContextLoader.getKnownTagRenderings = (id => AllKnownLayers.getTagRendering(id))
|
WithContextLoader.getKnownTagRenderings = (id => AllKnownLayers.getTagRendering(id))
|
||||||
return true
|
return true
|
||||||
})()
|
})()
|
||||||
|
|
||||||
|
|
||||||
// Must be below the list...
|
// Must be below the list...
|
||||||
public static sharedLayers: Map<string, LayerConfig> = AllKnownLayers.getSharedLayers();
|
public static sharedLayers: Map<string, LayerConfig> = AllKnownLayers.getSharedLayers();
|
||||||
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",]
|
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 no_include: string[] = ["conflation", "left_right_style"]
|
||||||
/**
|
/**
|
||||||
* Layer IDs of layers which have special properties through built-in hooks
|
* 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> {
|
private static getSharedLayers(): Map<string, LayerConfig> {
|
||||||
const sharedLayers = new Map<string, LayerConfig>();
|
const sharedLayers = new Map<string, LayerConfig>();
|
||||||
|
@ -75,41 +127,4 @@ export default class AllKnownLayers {
|
||||||
return sharedLayers;
|
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(", ")}`
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,9 @@ export default class TagRenderingConfig {
|
||||||
}[]
|
}[]
|
||||||
|
|
||||||
constructor(json: string | TagRenderingConfigJson, context?: string) {
|
constructor(json: string | TagRenderingConfigJson, context?: string) {
|
||||||
|
if (json === undefined) {
|
||||||
|
throw "Initing a TagRenderingConfig with undefined in " + context;
|
||||||
|
}
|
||||||
|
|
||||||
if (json === "questions") {
|
if (json === "questions") {
|
||||||
// Very special value
|
// Very special value
|
||||||
|
@ -55,14 +58,11 @@ export default class TagRenderingConfig {
|
||||||
|
|
||||||
|
|
||||||
if (typeof json === "number") {
|
if (typeof json === "number") {
|
||||||
this.render = Translations.T("" + json, context + ".render")
|
json = ""+json
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (json === undefined) {
|
|
||||||
throw "Initing a TagRenderingConfig with undefined in " + context;
|
|
||||||
}
|
|
||||||
if (typeof json === "string") {
|
if (typeof json === "string") {
|
||||||
this.render = Translations.T(json, context + ".render");
|
this.render = Translations.T(json, context + ".render");
|
||||||
this.multiAnswer = false;
|
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
|
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.group = json.group ?? "";
|
||||||
this.render = Translations.T(json.render, context + ".render");
|
this.render = Translations.T(json.render, context + ".render");
|
||||||
this.question = Translations.T(json.question, context + ".question");
|
this.question = Translations.T(json.question, context + ".question");
|
||||||
|
|
|
@ -7,8 +7,13 @@ export default class WithContextLoader {
|
||||||
protected readonly _context: string;
|
protected readonly _context: string;
|
||||||
private readonly _json: any;
|
private readonly _json: any;
|
||||||
|
|
||||||
public static getKnownTagRenderings : ((id: string) => TagRenderingConfigJson)= function(id) {
|
public static getKnownTagRenderings : ((id: string) => TagRenderingConfigJson[])= function(id) {
|
||||||
return SharedTagRenderings.SharedTagRenderingJson.get(id)
|
const found = SharedTagRenderings.SharedTagRenderingJson.get(id)
|
||||||
|
if(found !== undefined){
|
||||||
|
return [found]
|
||||||
|
}else{
|
||||||
|
return []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(json: any, context: string) {
|
constructor(json: any, context: string) {
|
||||||
|
@ -64,36 +69,54 @@ export default class WithContextLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
const context = this._context
|
const context = this._context
|
||||||
const renderings: TagRenderingConfig[] = []
|
|
||||||
options = options ?? {}
|
options = options ?? {}
|
||||||
if (options.prepConfig === undefined) {
|
if (options.prepConfig === undefined) {
|
||||||
options.prepConfig = c => c
|
options.prepConfig = c => c
|
||||||
}
|
}
|
||||||
|
const preparedConfigs : TagRenderingConfigJson[] = []
|
||||||
for (let i = 0; i < tagRenderings.length; i++) {
|
for (let i = 0; i < tagRenderings.length; i++) {
|
||||||
let renderingJson = tagRenderings[i]
|
let renderingJson = tagRenderings[i]
|
||||||
if (typeof renderingJson === "string") {
|
if (typeof renderingJson === "string") {
|
||||||
renderingJson = {builtin: renderingJson, override: undefined}
|
renderingJson = {builtin: renderingJson, override: undefined}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderingJson["builtin"] !== undefined) {
|
if (renderingJson["builtin"] === undefined) {
|
||||||
const renderingId = renderingJson["builtin"]
|
const patchedConfig = options.prepConfig(<TagRenderingConfigJson>renderingJson)
|
||||||
let sharedJson = WithContextLoader.getKnownTagRenderings(renderingId)
|
preparedConfigs.push(patchedConfig)
|
||||||
if (sharedJson === undefined) {
|
continue
|
||||||
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"}`;
|
|
||||||
}
|
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) {
|
if (renderingJson["override"] !== undefined) {
|
||||||
sharedJson = Utils.Merge(renderingJson["override"], JSON.parse(JSON.stringify(sharedJson)))
|
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 renderings: TagRenderingConfig[] = []
|
||||||
|
for (let i = 0; i < preparedConfigs.length; i++){
|
||||||
const tr = new TagRenderingConfig(patchedConfig, `${context}.tagrendering[${i}]`);
|
const preparedConfig = preparedConfigs[i];
|
||||||
|
const tr = new TagRenderingConfig(preparedConfig, `${context}.tagrendering[${i}]`);
|
||||||
if(options.readOnlyMode && tr.question !== undefined){
|
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`
|
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
151
test.ts
|
@ -1,150 +1 @@
|
||||||
import ShowDataLayer from "./UI/ShowDataLayer/ShowDataLayer";
|
console.log("Tests...")
|
||||||
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")
|
|
Loading…
Add table
Reference in a new issue