forked from MapComplete/MapComplete
		
	First working version with multi-rendering
This commit is contained in:
		
							parent
							
								
									0c0ef48a96
								
							
						
					
					
						commit
						20fa5028d9
					
				
					 5 changed files with 129 additions and 21 deletions
				
			
		| 
						 | 
					@ -67,17 +67,100 @@ export default class SimpleMetaTagger {
 | 
				
			||||||
    private static layerInfo = new SimpleMetaTagger(
 | 
					    private static layerInfo = new SimpleMetaTagger(
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            doc: "The layer-id to which this feature belongs. Note that this might be return any applicable if `passAllFeatures` is defined.",
 | 
					            doc: "The layer-id to which this feature belongs. Note that this might be return any applicable if `passAllFeatures` is defined.",
 | 
				
			||||||
            keys:["_layer"],
 | 
					            keys: ["_layer"],
 | 
				
			||||||
            includesDates: false,
 | 
					            includesDates: false,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        (feature, freshness, layer) => {
 | 
					        (feature, freshness, layer) => {
 | 
				
			||||||
            if(feature.properties._layer === layer.id){
 | 
					            if (feature.properties._layer === layer.id) {
 | 
				
			||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            feature.properties._layer = layer.id
 | 
					            feature.properties._layer = layer.id
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					    private static noBothButLeftRight = new SimpleMetaTagger(
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            keys: ["sidewalk:left", "sidewalk:right", "generic_key:left:property", "generic_key:right:property"],
 | 
				
			||||||
 | 
					            doc: "Rewrites tags from 'generic_key:both:property' as 'generic_key:left:property' and 'generic_key:right:property' (and similar for sidewalk tagging). Note that this rewritten tags _will be reuploaded on a change_. To prevent to much unrelated retagging, this is only enabled if the layer has at least some lineRenderings with offset defined",
 | 
				
			||||||
 | 
					            includesDates: false,
 | 
				
			||||||
 | 
					            cleanupRetagger: true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        ((feature, state, layer) => {
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if(!layer.lineRendering.some(lr => lr.leftRightSensitive)){
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            const tgs = feature.properties;
 | 
				
			||||||
 | 
					            let somethingChanged = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /**
 | 
				
			||||||
 | 
					             * Sets the key onto the properties (but doesn't overwrite if already existing)
 | 
				
			||||||
 | 
					             */
 | 
				
			||||||
 | 
					            function set(key, value) {
 | 
				
			||||||
 | 
					                if (tgs[key] === undefined || tgs[key] === "") {
 | 
				
			||||||
 | 
					                    tgs[key] = value
 | 
				
			||||||
 | 
					                    somethingChanged = true
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (tgs["sidewalk"]) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                const v = tgs["sidewalk"]
 | 
				
			||||||
 | 
					                switch (v) {
 | 
				
			||||||
 | 
					                    case "none":
 | 
				
			||||||
 | 
					                    case "no":
 | 
				
			||||||
 | 
					                        set("sidewalk:left", "no");
 | 
				
			||||||
 | 
					                        set("sidewalk:right", "no");
 | 
				
			||||||
 | 
					                        break
 | 
				
			||||||
 | 
					                    case "both":
 | 
				
			||||||
 | 
					                        set("sidewalk:left", "yes");
 | 
				
			||||||
 | 
					                        set("sidewalk:right", "yes");
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case "left":
 | 
				
			||||||
 | 
					                        set("sidewalk:left", "yes");
 | 
				
			||||||
 | 
					                        set("sidewalk:right", "no");
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case "right":
 | 
				
			||||||
 | 
					                        set("sidewalk:left", "no");
 | 
				
			||||||
 | 
					                        set("sidewalk:right", "yes");
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    default:
 | 
				
			||||||
 | 
					                        set("sidewalk:left", v);
 | 
				
			||||||
 | 
					                        set("sidewalk:right", v);
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                delete tgs["sidewalk"]
 | 
				
			||||||
 | 
					                somethingChanged = true
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const regex = /\([^:]*\):both:\(.*\)/
 | 
				
			||||||
 | 
					            for (const key in tgs) {
 | 
				
			||||||
 | 
					                const v = tgs[key]
 | 
				
			||||||
 | 
					                if (key.endsWith(":both")) {
 | 
				
			||||||
 | 
					                    const strippedKey = key.substring(0, key.length - ":both".length)
 | 
				
			||||||
 | 
					                    set(strippedKey + ":left", v)
 | 
				
			||||||
 | 
					                    set(strippedKey + ":right", v)
 | 
				
			||||||
 | 
					                    delete tgs[key]
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                const match = key.match(regex)
 | 
				
			||||||
 | 
					                if (match !== null) {
 | 
				
			||||||
 | 
					                    const strippedKey = match[1]
 | 
				
			||||||
 | 
					                    const property = match[1]
 | 
				
			||||||
 | 
					                    set(strippedKey + ":left:" + property, v)
 | 
				
			||||||
 | 
					                    set(strippedKey + ":right:" + property, v)
 | 
				
			||||||
 | 
					                    console.log("Left-right rewritten " + key)
 | 
				
			||||||
 | 
					                    delete tgs[key]
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return somethingChanged
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    private static surfaceArea = new SimpleMetaTagger(
 | 
					    private static surfaceArea = new SimpleMetaTagger(
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            keys: ["_surface", "_surface:ha"],
 | 
					            keys: ["_surface", "_surface:ha"],
 | 
				
			||||||
| 
						 | 
					@ -90,7 +173,7 @@ export default class SimpleMetaTagger {
 | 
				
			||||||
                enumerable: false,
 | 
					                enumerable: false,
 | 
				
			||||||
                configurable: true,
 | 
					                configurable: true,
 | 
				
			||||||
                get: () => {
 | 
					                get: () => {
 | 
				
			||||||
                    const sqMeters = ""+ GeoOperations.surfaceAreaInSqMeters(feature);
 | 
					                    const sqMeters = "" + GeoOperations.surfaceAreaInSqMeters(feature);
 | 
				
			||||||
                    delete feature.properties["_surface"]
 | 
					                    delete feature.properties["_surface"]
 | 
				
			||||||
                    feature.properties["_surface"] = sqMeters;
 | 
					                    feature.properties["_surface"] = sqMeters;
 | 
				
			||||||
                    return sqMeters
 | 
					                    return sqMeters
 | 
				
			||||||
| 
						 | 
					@ -220,7 +303,7 @@ export default class SimpleMetaTagger {
 | 
				
			||||||
                return false
 | 
					                return false
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Object.defineProperty(feature.properties, "_isOpen",{
 | 
					            Object.defineProperty(feature.properties, "_isOpen", {
 | 
				
			||||||
                enumerable: false,
 | 
					                enumerable: false,
 | 
				
			||||||
                configurable: true,
 | 
					                configurable: true,
 | 
				
			||||||
                get: () => {
 | 
					                get: () => {
 | 
				
			||||||
| 
						 | 
					@ -354,7 +437,8 @@ export default class SimpleMetaTagger {
 | 
				
			||||||
        SimpleMetaTagger.isOpen,
 | 
					        SimpleMetaTagger.isOpen,
 | 
				
			||||||
        SimpleMetaTagger.directionSimplified,
 | 
					        SimpleMetaTagger.directionSimplified,
 | 
				
			||||||
        SimpleMetaTagger.currentTime,
 | 
					        SimpleMetaTagger.currentTime,
 | 
				
			||||||
        SimpleMetaTagger.objectMetaInfo
 | 
					        SimpleMetaTagger.objectMetaInfo,
 | 
				
			||||||
 | 
					        SimpleMetaTagger.noBothButLeftRight
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
    public static readonly lazyTags: string[] = [].concat(...SimpleMetaTagger.metatags.filter(tagger => tagger.isLazy)
 | 
					    public static readonly lazyTags: string[] = [].concat(...SimpleMetaTagger.metatags.filter(tagger => tagger.isLazy)
 | 
				
			||||||
| 
						 | 
					@ -371,19 +455,21 @@ export default class SimpleMetaTagger {
 | 
				
			||||||
     * @param docs: what does this extra data do?
 | 
					     * @param docs: what does this extra data do?
 | 
				
			||||||
     * @param f: apply the changes. Returns true if something changed
 | 
					     * @param f: apply the changes. Returns true if something changed
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    constructor(docs: { keys: string[], doc: string, includesDates?: boolean, isLazy?: boolean },
 | 
					    constructor(docs: { keys: string[], doc: string, includesDates?: boolean, isLazy?: boolean, cleanupRetagger?: boolean },
 | 
				
			||||||
                f: ((feature: any, freshness: Date, layer: LayerConfig) => boolean)) {
 | 
					                f: ((feature: any, freshness: Date, layer: LayerConfig) => boolean)) {
 | 
				
			||||||
        this.keys = docs.keys;
 | 
					        this.keys = docs.keys;
 | 
				
			||||||
        this.doc = docs.doc;
 | 
					        this.doc = docs.doc;
 | 
				
			||||||
        this.isLazy = docs.isLazy
 | 
					        this.isLazy = docs.isLazy
 | 
				
			||||||
        this.applyMetaTagsOnFeature = f;
 | 
					        this.applyMetaTagsOnFeature = f;
 | 
				
			||||||
        this.includesDates = docs.includesDates ?? false;
 | 
					        this.includesDates = docs.includesDates ?? false;
 | 
				
			||||||
 | 
					        if (!docs.cleanupRetagger) {
 | 
				
			||||||
            for (const key of docs.keys) {
 | 
					            for (const key of docs.keys) {
 | 
				
			||||||
                if (!key.startsWith('_') && key.toLowerCase().indexOf("theme") < 0) {
 | 
					                if (!key.startsWith('_') && key.toLowerCase().indexOf("theme") < 0) {
 | 
				
			||||||
                    throw `Incorrect metakey ${key}: it should start with underscore (_)`
 | 
					                    throw `Incorrect metakey ${key}: it should start with underscore (_)`
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static HelpText(): BaseUIElement {
 | 
					    public static HelpText(): BaseUIElement {
 | 
				
			||||||
        const subElements: (string | BaseUIElement)[] = [
 | 
					        const subElements: (string | BaseUIElement)[] = [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,10 @@ export default interface LineRenderingConfigJson {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * The number of pixels this line should be moved. 
 | 
					     * The number of pixels this line should be moved. 
 | 
				
			||||||
     * Use a positive numbe to move to the right, a negative to move to the left (left/right as defined by the drawing direction of the line)
 | 
					     * Use a positive numbe to move to the right, a negative to move to the left (left/right as defined by the drawing direction of the line).
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * IMPORTANT: MapComplete will already normalize 'key:both:property' and 'key:both' into the corresponding 'key:left' and 'key:right' tagging (same for 'sidewalk=left/right/both' which is rewritten to 'sidewalk:left' and 'sidewalk:right')
 | 
				
			||||||
 | 
					     * This simplifies programming. Refer to the CalculatedTags.md-documentation for more details
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    offset?: number | TagRenderingConfigJson
 | 
					    offset?: number | TagRenderingConfigJson
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -12,12 +12,16 @@ export default class LineRenderingConfig extends WithContextLoader {
 | 
				
			||||||
    public readonly width: TagRenderingConfig;
 | 
					    public readonly width: TagRenderingConfig;
 | 
				
			||||||
    public readonly dashArray: TagRenderingConfig;
 | 
					    public readonly dashArray: TagRenderingConfig;
 | 
				
			||||||
    public readonly offset: TagRenderingConfig;
 | 
					    public readonly offset: TagRenderingConfig;
 | 
				
			||||||
 | 
					    public readonly leftRightSensitive: boolean
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    constructor(json: LineRenderingConfigJson, context: string) {
 | 
					    constructor(json: LineRenderingConfigJson, context: string) {
 | 
				
			||||||
        super(json, context)
 | 
					        super(json, context)
 | 
				
			||||||
        this.color = this.tr("color", "#0000ff");
 | 
					        this.color = this.tr("color", "#0000ff");
 | 
				
			||||||
        this.width = this.tr("width", "7");
 | 
					        this.width = this.tr("width", "7");
 | 
				
			||||||
        this.dashArray = this.tr("dashArray", "");
 | 
					        this.dashArray = this.tr("dashArray", "");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					            this.leftRightSensitive = json.offset !== undefined && json.offset !== 0 && json.offset !== "0"
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        this.offset = this.tr("offset", "0");
 | 
					        this.offset = this.tr("offset", "0");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,7 @@ export default class TagRenderingConfig {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(typeof json === "number"){
 | 
					        if(typeof json === "number"){
 | 
				
			||||||
            this.render =Translations.WT( ""+json)
 | 
					            this.render = Translations.WT( ""+json)
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,8 +45,23 @@
 | 
				
			||||||
          "width": 8
 | 
					          "width": 8
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          "color": "#888",
 | 
					          "color": {
 | 
				
			||||||
          "width": 8,
 | 
					            "render": "#888"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "width": {
 | 
				
			||||||
 | 
					            "render": "8",
 | 
				
			||||||
 | 
					            "mappings": [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                "if": {
 | 
				
			||||||
 | 
					                  "or": [
 | 
				
			||||||
 | 
					                    "sidewalk:left=no",
 | 
				
			||||||
 | 
					                    "sidewalk:left=separate"
 | 
				
			||||||
 | 
					                  ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "then": 0
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
          "offset": -8
 | 
					          "offset": -8
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue