forked from MapComplete/MapComplete
		
	Further work on GRB, bugfixes
This commit is contained in:
		
							parent
							
								
									4e4e64ce13
								
							
						
					
					
						commit
						89004af7f9
					
				
					 16 changed files with 456 additions and 102 deletions
				
			
		| 
						 | 
					@ -89,3 +89,5 @@ To mitigate this, use:
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					One can use `key!:=prefix-{other_key}-postfix` as well, to match if `key` is _not_ the same as `prefix-{other_key}-postfix` (with other_key substituted by the value)
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,7 @@ export default class FeaturePipeline {
 | 
				
			||||||
    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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(
 | 
					    constructor(
 | 
				
			||||||
        handleFeatureSource: (source: FeatureSourceForLayer & Tiled) => void,
 | 
					        handleFeatureSource: (source: FeatureSourceForLayer & Tiled) => void,
 | 
				
			||||||
| 
						 | 
					@ -95,11 +96,13 @@ export default class FeaturePipeline {
 | 
				
			||||||
        const perLayerHierarchy = new Map<string, TileHierarchyMerger>()
 | 
					        const perLayerHierarchy = new Map<string, TileHierarchyMerger>()
 | 
				
			||||||
        this.perLayerHierarchy = perLayerHierarchy
 | 
					        this.perLayerHierarchy = perLayerHierarchy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 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,
 | 
				
			||||||
                    new ChangeGeometryApplicator(src, state.changes)
 | 
					                    new ChangeGeometryApplicator(src, state.changes),
 | 
				
			||||||
 | 
					                    self.metataggingRecalculated
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            handleFeatureSource(srcFiltered)
 | 
					            handleFeatureSource(srcFiltered)
 | 
				
			||||||
| 
						 | 
					@ -472,6 +475,7 @@ export default class FeaturePipeline {
 | 
				
			||||||
                self.applyMetaTags(tile)
 | 
					                self.applyMetaTags(tile)
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
 | 
					        self.metataggingRecalculated.ping()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,8 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
 | 
				
			||||||
            allElements: ElementStorage
 | 
					            allElements: ElementStorage
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        tileIndex,
 | 
					        tileIndex,
 | 
				
			||||||
        upstream: FeatureSourceForLayer
 | 
					        upstream: FeatureSourceForLayer,
 | 
				
			||||||
 | 
					        metataggingUpdated: UIEventSource<any>
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        this.name = "FilteringFeatureSource(" + upstream.name + ")"
 | 
					        this.name = "FilteringFeatureSource(" + upstream.name + ")"
 | 
				
			||||||
        this.tileIndex = tileIndex
 | 
					        this.tileIndex = tileIndex
 | 
				
			||||||
| 
						 | 
					@ -54,10 +55,14 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        metataggingUpdated.addCallback(_ => {
 | 
				
			||||||
 | 
					            self._is_dirty.setData(true)
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.update();
 | 
					        this.update();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public update() {
 | 
					    private update() {
 | 
				
			||||||
        const self = this;
 | 
					        const self = this;
 | 
				
			||||||
        const layer = this.upstream.layer;
 | 
					        const layer = this.upstream.layer;
 | 
				
			||||||
        const features: { feature: any; freshness: Date }[] = this.upstream.features.data;
 | 
					        const features: { feature: any; freshness: Date }[] = this.upstream.features.data;
 | 
				
			||||||
| 
						 | 
					@ -106,13 +111,11 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        this._alreadyRegistered.add(src)
 | 
					        this._alreadyRegistered.add(src)
 | 
				
			||||||
        if (layer.isShown !== undefined) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const self = this;
 | 
					            const self = this;
 | 
				
			||||||
            src.map(tags => layer.isShown?.GetRenderValue(tags, "yes").txt).addCallbackAndRunD(isShown => {
 | 
					            src.addCallbackAndRunD(isShown => {
 | 
				
			||||||
                self._is_dirty.setData(true)
 | 
					                self._is_dirty.setData(true)
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,7 +80,7 @@ export class GeoOperations {
 | 
				
			||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                const intersection = this.calculateInstersection(feature, otherFeature, featureBBox)
 | 
					                const intersection = GeoOperations.calculateInstersection(feature, otherFeature, featureBBox)
 | 
				
			||||||
                if (intersection === null) {
 | 
					                if (intersection === null) {
 | 
				
			||||||
                    continue
 | 
					                    continue
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -353,7 +353,7 @@ export class GeoOperations {
 | 
				
			||||||
     * Returns 0 if both are linestrings
 | 
					     * Returns 0 if both are linestrings
 | 
				
			||||||
     * Returns null if the features are not intersecting
 | 
					     * Returns null if the features are not intersecting
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private static calculateInstersection(feature, otherFeature, featureBBox: BBox, otherFeatureBBox?: BBox): number {
 | 
					    static calculateInstersection(feature, otherFeature, featureBBox: BBox, otherFeatureBBox?: BBox): number {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            if (feature.geometry.type === "LineString") {
 | 
					            if (feature.geometry.type === "LineString") {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -433,7 +433,7 @@ export class GeoOperations {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } catch (exception) {
 | 
					        } catch (exception) {
 | 
				
			||||||
            console.warn("EXCEPTION CAUGHT WHILE INTERSECTING: ", exception);
 | 
					            console.warn("EXCEPTION CAUGHT WHILE INTERSECTING: ", exception,"\nThe considered objects are",feature, otherFeature);
 | 
				
			||||||
            return undefined
 | 
					            return undefined
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return undefined;
 | 
					        return undefined;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -292,6 +292,10 @@ export default class CreateWayWithPointReuseAction extends OsmChangeAction {
 | 
				
			||||||
                        continue
 | 
					                        continue
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
 | 
					                    if(coorInfo.closebyNodes[0] === undefined){
 | 
				
			||||||
 | 
					                        continue
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (other.closebyNodes[0].node === coorInfo.closebyNodes[0].node) {
 | 
					                    if (other.closebyNodes[0].node === coorInfo.closebyNodes[0].node) {
 | 
				
			||||||
                        conflictFree = false
 | 
					                        conflictFree = false
 | 
				
			||||||
                        // We have found a conflict!
 | 
					                        // We have found a conflict!
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,13 +12,14 @@ import {TagsFilter} from "./TagsFilter";
 | 
				
			||||||
export default class SubstitutingTag implements TagsFilter {
 | 
					export default class SubstitutingTag implements TagsFilter {
 | 
				
			||||||
    private readonly _key: string;
 | 
					    private readonly _key: string;
 | 
				
			||||||
    private readonly _value: string;
 | 
					    private readonly _value: string;
 | 
				
			||||||
 | 
					private readonly _invert: boolean
 | 
				
			||||||
    constructor(key: string, value: string) {
 | 
					    constructor(key: string, value: string, invert = false) {
 | 
				
			||||||
        this._key = key;
 | 
					        this._key = key;
 | 
				
			||||||
        this._value = value;
 | 
					        this._value = value;
 | 
				
			||||||
 | 
					        this._invert = invert
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static substituteString(template: string, dict: any): string {
 | 
					    private static substituteString(template: string, dict: any): string {
 | 
				
			||||||
        for (const k in dict) {
 | 
					        for (const k in dict) {
 | 
				
			||||||
            template = template.replace(new RegExp("\\{" + k + "\\}", 'g'), dict[k])
 | 
					            template = template.replace(new RegExp("\\{" + k + "\\}", 'g'), dict[k])
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -26,7 +27,7 @@ export default class SubstitutingTag implements TagsFilter {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    asHumanString(linkToWiki: boolean, shorten: boolean, properties) {
 | 
					    asHumanString(linkToWiki: boolean, shorten: boolean, properties) {
 | 
				
			||||||
        return this._key + "=" + SubstitutingTag.substituteString(this._value, properties);
 | 
					        return this._key + (this._invert ? '!' : '') + "=" + SubstitutingTag.substituteString(this._value, properties);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    asOverpass(): string[] {
 | 
					    asOverpass(): string[] {
 | 
				
			||||||
| 
						 | 
					@ -37,11 +38,11 @@ export default class SubstitutingTag implements TagsFilter {
 | 
				
			||||||
        if (!(other instanceof SubstitutingTag)) {
 | 
					        if (!(other instanceof SubstitutingTag)) {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return other._key === this._key && other._value === this._value;
 | 
					        return other._key === this._key && other._value === this._value && other._invert === this._invert;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    isUsableAsAnswer(): boolean {
 | 
					    isUsableAsAnswer(): boolean {
 | 
				
			||||||
        return true;
 | 
					        return !this._invert;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    matchesProperties(properties: any): boolean {
 | 
					    matchesProperties(properties: any): boolean {
 | 
				
			||||||
| 
						 | 
					@ -50,7 +51,7 @@ export default class SubstitutingTag implements TagsFilter {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        const expectedValue = SubstitutingTag.substituteString(this._value, properties);
 | 
					        const expectedValue = SubstitutingTag.substituteString(this._value, properties);
 | 
				
			||||||
        return value === expectedValue;
 | 
					        return (value === expectedValue) !== this._invert;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    usedKeys(): string[] {
 | 
					    usedKeys(): string[] {
 | 
				
			||||||
| 
						 | 
					@ -58,6 +59,7 @@ export default class SubstitutingTag implements TagsFilter {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    asChange(properties: any): { k: string; v: string }[] {
 | 
					    asChange(properties: any): { k: string; v: string }[] {
 | 
				
			||||||
 | 
					    if(this._invert){throw "An inverted substituting tag can not be used to create a change"}
 | 
				
			||||||
        const v = SubstitutingTag.substituteString(this._value, properties);
 | 
					        const v = SubstitutingTag.substituteString(this._value, properties);
 | 
				
			||||||
        if (v.match(/{.*}/) !== null) {
 | 
					        if (v.match(/{.*}/) !== null) {
 | 
				
			||||||
            throw "Could not calculate all the substitutions: still have " + v
 | 
					            throw "Could not calculate all the substitutions: still have " + v
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -226,6 +226,10 @@ export class TagUtils {
 | 
				
			||||||
                    new RegExp("^" + split[1] + "$")
 | 
					                    new RegExp("^" + split[1] + "$")
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            if (tag.indexOf("!:=") >= 0) {
 | 
				
			||||||
 | 
					                const split = Utils.SplitFirst(tag, "!:=");
 | 
				
			||||||
 | 
					                return new SubstitutingTag(split[0], split[1], true);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (tag.indexOf(":=") >= 0) {
 | 
					            if (tag.indexOf(":=") >= 0) {
 | 
				
			||||||
                const split = Utils.SplitFirst(tag, ":=");
 | 
					                const split = Utils.SplitFirst(tag, ":=");
 | 
				
			||||||
                return new SubstitutingTag(split[0], split[1]);
 | 
					                return new SubstitutingTag(split[0], split[1]);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -553,7 +553,7 @@ export default class SpecialVisualizations {
 | 
				
			||||||
                        doc: "If specified, applies the the tags onto _another_ object. The id will be read from properties[id_of_object_to_apply_this_one] of the selected object. The tags are still calculated based on the tags of the _selected_ element"
 | 
					                        doc: "If specified, applies the the tags onto _another_ object. The id will be read from properties[id_of_object_to_apply_this_one] of the selected object. The tags are still calculated based on the tags of the _selected_ element"
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
                example: "`{tag_apply(survey_date:=$_now:date, Surveyed today!)}`",
 | 
					                example: "`{tag_apply(survey_date=$_now:date, Surveyed today!)}`, `{tag_apply(addr:street=$addr:street, Apply the address, apply_icon.svg, _closest_osm_id)",
 | 
				
			||||||
                constr: (state, tags, args) => {
 | 
					                constr: (state, tags, args) => {
 | 
				
			||||||
                    const tagsToApply = SpecialVisualizations.generateTagsToApply(args[0], tags)
 | 
					                    const tagsToApply = SpecialVisualizations.generateTagsToApply(args[0], tags)
 | 
				
			||||||
                    const msg = args[1]
 | 
					                    const msg = args[1]
 | 
				
			||||||
| 
						 | 
					@ -650,6 +650,13 @@ export default class SpecialVisualizations {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return kv
 | 
					            return kv
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (const spec of tgsSpec) {
 | 
				
			||||||
 | 
					            if(spec[0].endsWith(':')){
 | 
				
			||||||
 | 
					                throw "A tag specification for import or apply ends with ':'. The theme author probably wrote key:=otherkey instead of key=$otherkey"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        return tagSource.map(tags => {
 | 
					        return tagSource.map(tags => {
 | 
				
			||||||
            const newTags: Tag [] = []
 | 
					            const newTags: Tag [] = []
 | 
				
			||||||
            for (const [key, value] of tgsSpec) {
 | 
					            for (const [key, value] of tgsSpec) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,45 +124,7 @@ export class Translation extends BaseUIElement {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            let template: string = this.translations[lang];
 | 
					            let template: string = this.translations[lang];
 | 
				
			||||||
            for (const k in text) {
 | 
					            newTranslations[lang] = Utils.SubstituteKeys(template, text);
 | 
				
			||||||
                if (!text.hasOwnProperty(k)) {
 | 
					 | 
				
			||||||
                    continue
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                const combined: (string)[] = [];
 | 
					 | 
				
			||||||
                const parts = template.split("{" + k + "}");
 | 
					 | 
				
			||||||
                const el: string | BaseUIElement = text[k];
 | 
					 | 
				
			||||||
                if (el === undefined) {
 | 
					 | 
				
			||||||
                    continue;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                let rtext: string = "";
 | 
					 | 
				
			||||||
                if (typeof (el) === "string") {
 | 
					 | 
				
			||||||
                    rtext = el;
 | 
					 | 
				
			||||||
                } else if (typeof (el) === "number") {
 | 
					 | 
				
			||||||
                    // HUH? Where did that number come from? It might be a version number or something calculated
 | 
					 | 
				
			||||||
                    rtext = "" + el;
 | 
					 | 
				
			||||||
                } else if (el["toISOString"] != undefined) {
 | 
					 | 
				
			||||||
                    // This is a date, probably the timestamp of the object
 | 
					 | 
				
			||||||
                    // @ts-ignore
 | 
					 | 
				
			||||||
                    const date: Date = el;
 | 
					 | 
				
			||||||
                    rtext = date.toLocaleString();
 | 
					 | 
				
			||||||
                } else if (el.ConstructElement === undefined) {
 | 
					 | 
				
			||||||
                    console.error("ConstructElement is not defined", el);
 | 
					 | 
				
			||||||
                    throw "ConstructElement is not defined, you are working with a " + (typeof el) + ":" + (el.constructor.name)
 | 
					 | 
				
			||||||
                } else if (el["textFor"] !== undefined) {
 | 
					 | 
				
			||||||
                    // @ts-ignore
 | 
					 | 
				
			||||||
                    rtext = el.textFor(lang)
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    rtext = el.ConstructElement().innerHTML;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                for (let i = 0; i < parts.length - 1; i++) {
 | 
					 | 
				
			||||||
                    combined.push(parts[i]);
 | 
					 | 
				
			||||||
                    combined.push(rtext)
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                combined.push(parts[parts.length - 1]);
 | 
					 | 
				
			||||||
                template = combined.join("")
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            newTranslations[lang] = template;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return new Translation(newTranslations);
 | 
					        return new Translation(newTranslations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								Utils.ts
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								Utils.ts
									
										
									
									
									
								
							| 
						 | 
					@ -203,6 +203,19 @@ Note that these values can be prepare with javascript in the theme by using a [c
 | 
				
			||||||
            const key = match[1]
 | 
					            const key = match[1]
 | 
				
			||||||
            let v = tags[key]
 | 
					            let v = tags[key]
 | 
				
			||||||
            if(v !== undefined ){
 | 
					            if(v !== undefined ){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (v["toISOString"] != undefined) {
 | 
				
			||||||
 | 
					                    // This is a date, probably the timestamp of the object
 | 
				
			||||||
 | 
					                    // @ts-ignore
 | 
				
			||||||
 | 
					                    const date: Date = el;
 | 
				
			||||||
 | 
					                    v = date.toISOString()
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if(v.InnerConstructElement !== undefined){
 | 
				
			||||||
 | 
					                    console.warn("SubstituteKeys received a BaseUIElement to substitute in - this is probably a bug and will be downcast to a string", v)
 | 
				
			||||||
 | 
					                    v = ( <HTMLElement> v.InnerConstructElement())?.innerText
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                if(typeof v !== "string"){
 | 
					                if(typeof v !== "string"){
 | 
				
			||||||
                    v = ""+v
 | 
					                    v = ""+v
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  "id": "crab_address",
 | 
					  "id": "crab_address",
 | 
				
			||||||
  "description": "Address data for Flanders by the governement, suited for import into OpenStreetMap. Datadump from 2021-10-26. This layer contains only visualisation logic. Import buttons should be added via an override.",
 | 
					  "description": "Address data for Flanders by the governement, suited for import into OpenStreetMap. Datadump from 2021-10-26. This layer contains only visualisation logic. Import buttons should be added via an override. Note that HNRLABEL contains the original value, whereas _HNRLABEL contains a slightly cleaned version",
 | 
				
			||||||
  "source": {
 | 
					  "source": {
 | 
				
			||||||
    "osmTags": "HUISNR~*",
 | 
					    "osmTags": "HUISNR~*",
 | 
				
			||||||
    "geoJson": "https://pietervdvn.github.io/CRAB_2021_10_26/tile_{z}_{x}_{y}.geojson",
 | 
					    "geoJson": "https://pietervdvn.github.io/CRAB_2021_10_26/tile_{z}_{x}_{y}.geojson",
 | 
				
			||||||
| 
						 | 
					@ -18,15 +18,18 @@
 | 
				
			||||||
      "iconSize": "50,50,center",
 | 
					      "iconSize": "50,50,center",
 | 
				
			||||||
      "icon": "./assets/layers/crab_address/housenumber_blank.svg",
 | 
					      "icon": "./assets/layers/crab_address/housenumber_blank.svg",
 | 
				
			||||||
      "label": {
 | 
					      "label": {
 | 
				
			||||||
        "render": "<div style='margin-top: -42px; color: white' class='rounded-full p-1 font-bold relative'>{HNRLABEL}</div>"
 | 
					        "render": "<div style='margin-top: -42px; color: white' class='rounded-full p-1 font-bold relative'>{_HNRLABEL}</div>"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
 | 
					  "calculatedTags": [
 | 
				
			||||||
 | 
					    "_HNRLABEL=(() => {const lbl = feat.properties.HNRLABEL?.split('-')?.map(l => Number(l))?.filter(i => !isNaN (i)) ;if(lbl?.length != 2) {return feat.properties.HNRLABEL}; const addresses = []; for(let i = lbl[0]; i <= lbl[1]; i += 1){addresses.push(''+i);}; return addresses.join(';')        })()"
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
  "tagRenderings": [
 | 
					  "tagRenderings": [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "id": "render_crab",
 | 
					      "id": "render_crab",
 | 
				
			||||||
      "render": {
 | 
					      "render": {
 | 
				
			||||||
        "nl": "Volgens het CRAB ligt hier <b>{STRAATNM}</b> {HUISNR} (label: {HNRLABEL})"
 | 
					        "nl": "Volgens het CRAB ligt hier <b>{STRAATNM}</b> {HUISNR} (label: {_HNRLABEL})"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -349,26 +349,43 @@
 | 
				
			||||||
          "_embedding_street=feat.get('_embedded_in')['addr:street']",
 | 
					          "_embedding_street=feat.get('_embedded_in')['addr:street']",
 | 
				
			||||||
          "_embedding_id=feat.get('_embedded_in').id",
 | 
					          "_embedding_id=feat.get('_embedded_in').id",
 | 
				
			||||||
          "_closeby_addresses=feat.closestn('address',10,undefined,50).map(f => f.feat).filter(addr => addr.properties['addr:street'] == feat.properties['STRAATNM'] && feat.properties['HNRLABEL'] == addr.properties['addr:housenumber'] + (addr.properties['addr:unit']??'') ).length",
 | 
					          "_closeby_addresses=feat.closestn('address',10,undefined,50).map(f => f.feat).filter(addr => addr.properties['addr:street'] == feat.properties['STRAATNM'] && feat.properties['HNRLABEL'] == addr.properties['addr:housenumber'] + (addr.properties['addr:unit']??'') ).length",
 | 
				
			||||||
          "_has_identical_closeby_address=feat.get('_closeby_addresses') >= 1 ? 'yes' : 'no'"
 | 
					          "_has_identical_closeby_address=feat.get('_closeby_addresses') >= 1 ? 'yes' : 'no'",
 | 
				
			||||||
 | 
					          "_embedded_in_grb=feat.overlapWith('GRB')[0]?.feat?.properties ?? {}",
 | 
				
			||||||
 | 
					          "_embedding_nr_grb=feat.get('_embedded_in_grb')['addr:housenumber']",
 | 
				
			||||||
 | 
					          "_embedding_street_grb=feat.get('_embedded_in_grb')['addr:street']"
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "isShown": {
 | 
					        "filter": [
 | 
				
			||||||
          "render": "yes",
 | 
					 | 
				
			||||||
          "mappings": [
 | 
					 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
              "if": {
 | 
					            "id": "show_matched_addresses",
 | 
				
			||||||
 | 
					            "options": [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                "question": "Show all CRAB-addresses (including already matched ones)"
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                "question": "Only show unmatched addresses",
 | 
				
			||||||
 | 
					                "osmTags": {
 | 
				
			||||||
                  "and": [
 | 
					                  "and": [
 | 
				
			||||||
                  "_embedding_nr:={HUISNR}",
 | 
					                    "_has_identical_closeby_address!=yes",
 | 
				
			||||||
                  "_embedding_street:={STRAATNM}"
 | 
					                    {
 | 
				
			||||||
 | 
					                      "#": "Matches the embedding OSM object",
 | 
				
			||||||
 | 
					                      "or": [
 | 
				
			||||||
 | 
					                        "_embedding_nr!:={HUISNR}",
 | 
				
			||||||
 | 
					                        "_embedding_street!:={STRAATNM}"
 | 
				
			||||||
                      ]
 | 
					                      ]
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
              "then": "no"
 | 
					                    {    "#": "Matches the embedding GRB object",
 | 
				
			||||||
            },
 | 
					
 | 
				
			||||||
            {
 | 
					                      "or": [
 | 
				
			||||||
              "if": "_has_identical_closeby_address=yes",
 | 
					                        "_embedding_nr_grb!:={HUISNR}",
 | 
				
			||||||
              "then": "no"
 | 
					                        "_embedding_street_grb!:={STRAATNM}"
 | 
				
			||||||
 | 
					                      ]
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                  ]
 | 
					                  ]
 | 
				
			||||||
        },
 | 
					                }
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
        "tagRenderings+": [
 | 
					        "tagRenderings+": [
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            "id": "render_embedded",
 | 
					            "id": "render_embedded",
 | 
				
			||||||
| 
						 | 
					@ -388,7 +405,7 @@
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            "id": "apply-button",
 | 
					            "id": "apply-button",
 | 
				
			||||||
            "render": "{tag_apply(addr:street=$STRAATNM; addr:housenumber=$HUISNR,Apply this address on the OSM-building,,_embedding_id)}",
 | 
					            "render": "{tag_apply(addr:street=$STRAATNM; addr:housenumber=$_HNRLABEL,Apply this address on the OSM-building,,_embedding_id)}",
 | 
				
			||||||
            "condition": "_embedding_id!="
 | 
					            "condition": "_embedding_id!="
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
| 
						 | 
					@ -417,13 +434,15 @@
 | 
				
			||||||
      "name": "GRB geometries",
 | 
					      "name": "GRB geometries",
 | 
				
			||||||
      "title": "GRB outline",
 | 
					      "title": "GRB outline",
 | 
				
			||||||
      "calculatedTags": [
 | 
					      "calculatedTags": [
 | 
				
			||||||
        "_overlaps_with=feat.overlapWith('OSM-buildings').filter(f => f.overlap > 1 &&  (feat.get('_surface') < 20 || f.overlap / feat.get('_surface')) > 0.5)[0] ?? null",
 | 
					        "_overlaps_with=feat.overlapWith('OSM-buildings').filter(f => f.overlap > 1 &&  (feat.get('_surface') < 20 || f.overlap / feat.get('_surface')) > 0.5)[0] ?? ''",
 | 
				
			||||||
        "_overlap_absolute=feat.get('_overlaps_with')?.overlap",
 | 
					        "_overlap_absolute=feat.get('_overlaps_with')?.overlap",
 | 
				
			||||||
        "_overlap_percentage=Math.round(100 * feat.get('_overlap_absolute') / feat.get('_surface')) ",
 | 
					        "_overlap_percentage=Math.round(100 * feat.get('_overlap_absolute') / feat.get('_surface')) ",
 | 
				
			||||||
        "_osm_obj:source:ref=feat.get('_overlaps_with')?.feat?.properties['source:geometry:ref']",
 | 
					        "_osm_obj:source:ref=feat.get('_overlaps_with')?.feat?.properties['source:geometry:ref']",
 | 
				
			||||||
        "_osm_obj:source:date=feat.get('_overlaps_with')?.feat?.properties['source:geometry:date'].replace(/\\//g, '-')",
 | 
					        "_osm_obj:source:date=feat.get('_overlaps_with')?.feat?.properties['source:geometry:date'].replace(/\\//g, '-')",
 | 
				
			||||||
        "_osm_obj:building=feat.get('_overlaps_with')?.feat?.properties.building",
 | 
					        "_osm_obj:building=feat.get('_overlaps_with')?.feat?.properties?.building",
 | 
				
			||||||
        "_osm_obj:id=feat.get('_overlaps_with')?.feat?.properties.id",
 | 
					        "_osm_obj:id=feat.get('_overlaps_with')?.feat?.properties?.id",
 | 
				
			||||||
 | 
					        "_osm_obj:addr:street=(feat.get('_overlaps_with')?.feat?.properties ?? {})['addr:street']",
 | 
				
			||||||
 | 
					        "_osm_obj:addr:housenumber=(feat.get('_overlaps_with')?.feat?.properties ?? {})['addr:housenumber']",
 | 
				
			||||||
        "_grb_ref=feat.properties['source:geometry:entity'] + '/' + feat.properties['source:geometry:oidn']",
 | 
					        "_grb_ref=feat.properties['source:geometry:entity'] + '/' + feat.properties['source:geometry:oidn']",
 | 
				
			||||||
        "_imported_osm_object_found= feat.properties['_osm_obj:source:ref'] == feat.properties._grb_ref",
 | 
					        "_imported_osm_object_found= feat.properties['_osm_obj:source:ref'] == feat.properties._grb_ref",
 | 
				
			||||||
        "_grb_date=feat.properties['source:geometry:date'].replace(/\\//g,'-')",
 | 
					        "_grb_date=feat.properties['source:geometry:date'].replace(/\\//g,'-')",
 | 
				
			||||||
| 
						 | 
					@ -432,21 +451,86 @@
 | 
				
			||||||
        "_building:min_level= feat.properties['fixme']?.startsWith('verdieping, correct the building tag, add building:level and building:min_level before upload in JOSM!') ? '1' : ''"
 | 
					        "_building:min_level= feat.properties['fixme']?.startsWith('verdieping, correct the building tag, add building:level and building:min_level before upload in JOSM!') ? '1' : ''"
 | 
				
			||||||
      ],
 | 
					      ],
 | 
				
			||||||
      "tagRenderings": [
 | 
					      "tagRenderings": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          "id": "Import-button",
 | 
				
			||||||
 | 
					          "render": "{import_button(OSM-buildings,building=$building; source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref; addr:street=$addr:street; addr:housenumber=$addr:housenumber; building:min_level=$_building:min_level, Upload this building to OpenStreetMap)}",
 | 
				
			||||||
 | 
					          "mappings": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              "if": {"and":
 | 
				
			||||||
 | 
					              [
 | 
				
			||||||
 | 
					                "_overlaps_with!=",
 | 
				
			||||||
 | 
					                "_osm_obj:addr:street=",
 | 
				
			||||||
 | 
					                "_osm_obj:addr:housenumber=",
 | 
				
			||||||
 | 
					                "addr:street~*",
 | 
				
			||||||
 | 
					                "addr:housenumber~*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              ]
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              "then": "{import_button(OSM-buildings,building=$_target_building_type; source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref; addr:street=$addr:street; addr:housenumber=$addr:housenumber, Replace the geometry in OpenStreetMap and add the address,,,_osm_obj:id)}"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              "if": "_overlaps_with!=",
 | 
				
			||||||
 | 
					              "then": "{import_button(OSM-buildings,building=$_target_building_type; source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref, Replace the geometry in OpenStreetMap,,,_osm_obj:id)}"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          ]
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          "id": "Building info",
 | 
					          "id": "Building info",
 | 
				
			||||||
          "render": "This is a <b>{building}</b> <span class='subtle'>detected by {detection_method}</span>"
 | 
					          "render": "This is a <b>{building}</b> <span class='subtle'>detected by {detection_method}</span>"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          "id": "overlapping building address",
 | 
				
			||||||
 | 
					          "render": "The overlapping openstreetmap-building has no address information at all",
 | 
				
			||||||
 | 
					          "mappings": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              "if": {
 | 
				
			||||||
 | 
					                "and": [
 | 
				
			||||||
 | 
					                  "_osm_obj:addr:street~*",
 | 
				
			||||||
 | 
					                  "_osm_obj:addr:housenumber~*"
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              "then": "The overlapping openstreetmap-building has address {_osm_obj:addr:street} {_osm_obj:addr:housenumber}"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              "if": "_osm_obj:addr:street~*",
 | 
				
			||||||
 | 
					              "then": "The overlapping building only has a street known: {_osm_obj:addr:street}"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              "if": "_osm_obj:addr:housenumber~*",
 | 
				
			||||||
 | 
					              "then": "The overlapping building only has a housenumber known: {_osm_obj:addr:housenumber}"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "conditon": "_osm_obj:id~*"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          "id": "grb_address_diff",
 | 
				
			||||||
 | 
					          "render": "<div>The overlapping openstreetmap-building has a different address then this GRB-object: {addr:street} {addr:housenumber}<br/>{tag_apply(addr:street=$addr:street; addr:housenumber=$addr:housenumber,Copy the GRB-address onto the OSM-object,,_osm_obj:id)}",
 | 
				
			||||||
 | 
					          "condition": {
 | 
				
			||||||
 | 
					            "and": [
 | 
				
			||||||
 | 
					              "_osm_obj:id~*",
 | 
				
			||||||
 | 
					              "addr:street~*",
 | 
				
			||||||
 | 
					              "addr:housenumber~*",
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                "or": [
 | 
				
			||||||
 | 
					                  "addr:street!:={_osm_obj:addr:street}",
 | 
				
			||||||
 | 
					                  "addr:housenumber!:={_osm_obj:addr:housenumber}"
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          "id": "overlapping building type",
 | 
					          "id": "overlapping building type",
 | 
				
			||||||
          "render": "<div>The overlapping openstreetmap-building is a <b>{_osm_obj:building}</b> and covers <b>{_overlap_percentage}%</b> of the GRB building<div><h3>GRB geometry:</h3>{minimap(21, id):height:10rem;border-radius:1rem;overflow:hidden}<h3>OSM geometry:</h3>{minimap(21,_osm_obj:id):height:10rem;border-radius:1rem;overflow:hidden}",
 | 
					          "render": "<div>The overlapping <a href='https://osm.org/{_osm_obj:id}' target='_blank'>openstreetmap-building</a> is a <b>{_osm_obj:building}</b> and covers <b>{_overlap_percentage}%</b> of the GRB building<div><h3>GRB geometry:</h3>{minimap(21, id):height:10rem;border-radius:1rem;overflow:hidden}<h3>OSM geometry:</h3>{minimap(21,_osm_obj:id):height:10rem;border-radius:1rem;overflow:hidden}",
 | 
				
			||||||
          "condition": "_overlaps_with!=null"
 | 
					          "condition": "_overlaps_with!="
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          "id": "apply-id",
 | 
					          "id": "apply-id",
 | 
				
			||||||
          "render": "{tag_apply(source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref,Mark the OSM-building as imported,,_osm_obj:id)}",
 | 
					          "render": "{tag_apply(source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref,Mark the OSM-building as imported,,_osm_obj:id)}",
 | 
				
			||||||
          "condition": {
 | 
					          "condition": {
 | 
				
			||||||
            "and": [
 | 
					            "and": [
 | 
				
			||||||
              "_overlaps_with!=null"
 | 
					              "_overlaps_with!=",
 | 
				
			||||||
 | 
					              "_imported!=yes"
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
| 
						 | 
					@ -455,23 +539,12 @@
 | 
				
			||||||
          "render": "{tag_apply(building=$building,Use the building type from GRB,,_osm_obj:id)}",
 | 
					          "render": "{tag_apply(building=$building,Use the building type from GRB,,_osm_obj:id)}",
 | 
				
			||||||
          "condition": {
 | 
					          "condition": {
 | 
				
			||||||
            "and": [
 | 
					            "and": [
 | 
				
			||||||
              "_overlaps_with!=null",
 | 
					              "_overlaps_with!=",
 | 
				
			||||||
              "_osm_obj:building=yes",
 | 
					              "_osm_obj:building=yes",
 | 
				
			||||||
              "building!=yes"
 | 
					              "building!=yes"
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "id": "Import-button",
 | 
					 | 
				
			||||||
          "render": "{import_button(OSM-buildings,building=$building; source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref; addr:street=$addr:street; addr:housenumber=$addr:housenumber; building:min_level=$_building:min_level, Upload this building to OpenStreetMap)}",
 | 
					 | 
				
			||||||
          "mappings": [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              "if": "_overlaps_with!=null",
 | 
					 | 
				
			||||||
              "then": "{import_button(OSM-buildings,building=$_target_building_type; source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref, Replace the geometry in OpenStreetMap,,,_osm_obj:id)}"
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
          ]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "all_tags"
 | 
					 | 
				
			||||||
      ],
 | 
					      ],
 | 
				
			||||||
      "isShown": {
 | 
					      "isShown": {
 | 
				
			||||||
        "render": "yes",
 | 
					        "render": "yes",
 | 
				
			||||||
| 
						 | 
					@ -489,9 +562,41 @@
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "mapRendering": [
 | 
					      "mapRendering": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					          "label": {
 | 
				
			||||||
 | 
					            "render": "<div style='margin-top: -42px; color: black' class='rounded-full p-1 font-bold relative'>{addr:housenumber}</div>",
 | 
				
			||||||
 | 
					            "condition": "addr:housenumber~*"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "iconSize": "50,50,center",
 | 
				
			||||||
 | 
					          "icon": {
 | 
				
			||||||
 | 
					            "render": "./assets/themes/grb_import/housenumber_blank.svg",
 | 
				
			||||||
 | 
					            "mappings": [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                "if": "addr:housenumber=",
 | 
				
			||||||
 | 
					                "then": ""
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "location": [
 | 
				
			||||||
 | 
					            "point",
 | 
				
			||||||
 | 
					            "centroid"
 | 
				
			||||||
 | 
					          ]
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { "width": {
 | 
				
			||||||
 | 
					          "render": 5,
 | 
				
			||||||
 | 
					          "mappings": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              "if": "_imported=yes",
 | 
				
			||||||
 | 
					              "then": "1"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          ]
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
          "color": {
 | 
					          "color": {
 | 
				
			||||||
            "render": "#00a",
 | 
					            "render": "#00a",
 | 
				
			||||||
            "mappings": [
 | 
					            "mappings": [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                "if": "_imported=yes",
 | 
				
			||||||
 | 
					                "then":"#00ff00"
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
              {
 | 
					              {
 | 
				
			||||||
                "if": {
 | 
					                "if": {
 | 
				
			||||||
                  "and": [
 | 
					                  "and": [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										63
									
								
								assets/themes/grb_import/housenumber_blank.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								assets/themes/grb_import/housenumber_blank.svg
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,63 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   viewBox="0 0 171.5778 87.883003"
 | 
				
			||||||
 | 
					   id="svg12"
 | 
				
			||||||
 | 
					   sodipodi:docname="housenumber_blank.svg"
 | 
				
			||||||
 | 
					   inkscape:version="1.1.1 (1:1.1+202109281949+c3084ef5ed)"
 | 
				
			||||||
 | 
					   width="171.5778"
 | 
				
			||||||
 | 
					   height="87.883003"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/">
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata18">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs16" />
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     pagecolor="#ffffff"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1"
 | 
				
			||||||
 | 
					     objecttolerance="10"
 | 
				
			||||||
 | 
					     gridtolerance="10"
 | 
				
			||||||
 | 
					     guidetolerance="10"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="0"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:window-width="1920"
 | 
				
			||||||
 | 
					     inkscape:window-height="999"
 | 
				
			||||||
 | 
					     id="namedview14"
 | 
				
			||||||
 | 
					     showgrid="false"
 | 
				
			||||||
 | 
					     inkscape:zoom="2.2561926"
 | 
				
			||||||
 | 
					     inkscape:cx="-16.620921"
 | 
				
			||||||
 | 
					     inkscape:cy="-20.166718"
 | 
				
			||||||
 | 
					     inkscape:window-x="0"
 | 
				
			||||||
 | 
					     inkscape:window-y="0"
 | 
				
			||||||
 | 
					     inkscape:window-maximized="1"
 | 
				
			||||||
 | 
					     inkscape:current-layer="svg12"
 | 
				
			||||||
 | 
					     inkscape:pagecheckerboard="0" />
 | 
				
			||||||
 | 
					  <path
 | 
				
			||||||
 | 
					     d="m 14.044,0 h 143.48981 c 7.7801,0 14.044,6.2634 14.044,14.044 v 59.795 c 0,7.7801 -6.2634,14.044 -14.044,14.044 H 14.044 C 6.2639,87.883 0,81.6196 0,73.839 V 14.044 C 0,6.2639 6.2634,0 14.044,0 Z"
 | 
				
			||||||
 | 
					     style="fill:#fff5c8;paint-order:normal;fill-opacity:1;stroke:#000000;stroke-opacity:1"
 | 
				
			||||||
 | 
					     id="path6"
 | 
				
			||||||
 | 
					     inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					     sodipodi:nodetypes="sssssssss" />
 | 
				
			||||||
 | 
					  <path
 | 
				
			||||||
 | 
					     d="m 8.747,22.773 v 42.233 c 7.0389,0 14.078,7.0389 14.078,14.078 h 125.81781 c 0,-7.0389 7.0389,-14.078 14.078,-14.078 V 22.773 c -7.0389,0 -14.078,-7.0389 -14.078,-14.078 H 22.825 c 0,7.0389 -7.0389,14.078 -14.078,14.078 z"
 | 
				
			||||||
 | 
					     id="path8"
 | 
				
			||||||
 | 
					     inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					     style="fill:none;stroke:#fa7d69;stroke-width:5.0152;stroke-opacity:1"
 | 
				
			||||||
 | 
					     sodipodi:nodetypes="ccccccccc" />
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 2.3 KiB  | 
							
								
								
									
										10
									
								
								assets/themes/grb_import/license_info.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								assets/themes/grb_import/license_info.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "path": "housenumber_blank.svg",
 | 
				
			||||||
 | 
					    "license": "CC0",
 | 
				
			||||||
 | 
					    "authors": [
 | 
				
			||||||
 | 
					      "Pieter Vander Vennet"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "sources": []
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
| 
						 | 
					@ -52,12 +52,12 @@
 | 
				
			||||||
            "confirmButton": "Voeg hier een {category} toe<br/><div class='alert'>Je toevoeging is voor iedereen zichtbaar</div>",
 | 
					            "confirmButton": "Voeg hier een {category} toe<br/><div class='alert'>Je toevoeging is voor iedereen zichtbaar</div>",
 | 
				
			||||||
            "openLayerControl": "Open de laag-instellingen",
 | 
					            "openLayerControl": "Open de laag-instellingen",
 | 
				
			||||||
            "layerNotEnabled": "De laag {layer} is gedeactiveerd. Activeer deze om een punt toe te voegen",
 | 
					            "layerNotEnabled": "De laag {layer} is gedeactiveerd. Activeer deze om een punt toe te voegen",
 | 
				
			||||||
            "presetInfo": "Het nieuwe punt krijgt de attributen {tags}",
 | 
					            "presetInfo": "Het nieuwe object krijgt de attributen {tags}",
 | 
				
			||||||
            "disableFiltersExplanation": "Interessepunten kunnen verborgen zijn door een filter",
 | 
					            "disableFiltersExplanation": "Interessepunten kunnen verborgen zijn door een filter",
 | 
				
			||||||
            "disableFilters": "Zet alle filters af",
 | 
					            "disableFilters": "Zet alle filters af",
 | 
				
			||||||
            "hasBeenImported": "Dit punt is reeds geimporteerd",
 | 
					            "hasBeenImported": "Dit object is reeds geimporteerd",
 | 
				
			||||||
            "warnVisibleForEveryone": "Je toevoeging is voor iedereen zichtbaar",
 | 
					            "warnVisibleForEveryone": "Je toevoeging is voor iedereen zichtbaar",
 | 
				
			||||||
            "zoomInMore": "Zoom meer in om dit punt te importeren"
 | 
					            "zoomInMore": "Zoom meer in om dit object te importeren"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "pickLanguage": "Kies je taal: ",
 | 
					        "pickLanguage": "Kies je taal: ",
 | 
				
			||||||
        "about": "Bewerk en voeg data toe aan OpenStreetMap over een specifiek onderwerp op een gemakkelijke manier",
 | 
					        "about": "Bewerk en voeg data toe aan OpenStreetMap over een specifiek onderwerp op een gemakkelijke manier",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -187,8 +187,180 @@ export default class GeoOperationsSpec extends T {
 | 
				
			||||||
                        equal(51.5292513551899, bbox.minLat)
 | 
					                        equal(51.5292513551899, bbox.minLat)
 | 
				
			||||||
                        equal(51.53266860674158, bbox.maxLat)
 | 
					                        equal(51.53266860674158, bbox.maxLat)
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                ["Regression test: intersection/overlap", () => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    const polyGrb ={
 | 
				
			||||||
 | 
					                        "type": "Feature",
 | 
				
			||||||
 | 
					                        "properties": {
 | 
				
			||||||
 | 
					                            "osm_id": "25189153",
 | 
				
			||||||
 | 
					                            "size_grb_building": "217.14",
 | 
				
			||||||
 | 
					                            "addr:housenumber": "173",
 | 
				
			||||||
 | 
					                            "addr:street": "Kortrijksestraat",
 | 
				
			||||||
 | 
					                            "building": "house",
 | 
				
			||||||
 | 
					                            "source:geometry:entity": "Gbg",
 | 
				
			||||||
 | 
					                            "source:geometry:date": "2015/02/27",
 | 
				
			||||||
 | 
					                            "source:geometry:oidn": "1729460",
 | 
				
			||||||
 | 
					                            "source:geometry:uidn": "8713648",
 | 
				
			||||||
 | 
					                            "H_DTM_MIN": "17.28",
 | 
				
			||||||
 | 
					                            "H_DTM_GEM": "17.59",
 | 
				
			||||||
 | 
					                            "H_DSM_MAX": "29.04",
 | 
				
			||||||
 | 
					                            "H_DSM_P99": "28.63",
 | 
				
			||||||
 | 
					                            "HN_MAX": "11.45",
 | 
				
			||||||
 | 
					                            "HN_P99": "11.04",
 | 
				
			||||||
 | 
					                            "detection_method": "from existing OSM building source: house ,hits (3)",
 | 
				
			||||||
 | 
					                            "auto_building": "house",
 | 
				
			||||||
 | 
					                            "size_shared": "210.68",
 | 
				
			||||||
 | 
					                            "size_source_building": "212.63",
 | 
				
			||||||
 | 
					                            "id": "https://betadata.grbosm.site/grb?bbox=360935.6475626023,6592540.815539878,361088.52161917265,6592693.689596449/37",
 | 
				
			||||||
 | 
					                            "_lat": "50.83736194999996",
 | 
				
			||||||
 | 
					                            "_lon": "3.2432137000000116",
 | 
				
			||||||
 | 
					                            "_layer": "GRB",
 | 
				
			||||||
 | 
					                            "_length": "48.51529464293261",
 | 
				
			||||||
 | 
					                            "_length:km": "0.0",
 | 
				
			||||||
 | 
					                            "_now:date": "2021-12-05",
 | 
				
			||||||
 | 
					                            "_now:datetime": "2021-12-05 21:51:40",
 | 
				
			||||||
 | 
					                            "_loaded:date": "2021-12-05",
 | 
				
			||||||
 | 
					                            "_loaded:datetime": "2021-12-05 21:51:40"
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        "geometry": {
 | 
				
			||||||
 | 
					                            "type": "Polygon",
 | 
				
			||||||
 | 
					                            "coordinates": [
 | 
				
			||||||
 | 
					                                [
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.2431059999999974,
 | 
				
			||||||
 | 
					                                        50.83730270000021
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.243174299999987,
 | 
				
			||||||
 | 
					                                        50.83728850000007
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.2432116000000173,
 | 
				
			||||||
 | 
					                                        50.83736910000003
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.2433214000000254,
 | 
				
			||||||
 | 
					                                        50.83740350000011
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.24329779999996,
 | 
				
			||||||
 | 
					                                        50.837435399999855
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.2431881000000504,
 | 
				
			||||||
 | 
					                                        50.83740090000025
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.243152699999997,
 | 
				
			||||||
 | 
					                                        50.83738980000017
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.2431059999999974,
 | 
				
			||||||
 | 
					                                        50.83730270000021
 | 
				
			||||||
                                    ]
 | 
					                                    ]
 | 
				
			||||||
                                ]
 | 
					                                ]
 | 
				
			||||||
 | 
					                            ]
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        "id": "https://betadata.grbosm.site/grb?bbox=360935.6475626023,6592540.815539878,361088.52161917265,6592693.689596449/37",
 | 
				
			||||||
 | 
					                        "_lon": 3.2432137000000116,
 | 
				
			||||||
 | 
					                        "_lat": 50.83736194999996,
 | 
				
			||||||
 | 
					                        "bbox": {
 | 
				
			||||||
 | 
					                            "maxLat": 50.837435399999855,
 | 
				
			||||||
 | 
					                            "maxLon": 3.2433214000000254,
 | 
				
			||||||
 | 
					                            "minLat": 50.83728850000007,
 | 
				
			||||||
 | 
					                            "minLon": 3.2431059999999974
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    const polyHouse = {
 | 
				
			||||||
 | 
					                        "type": "Feature",
 | 
				
			||||||
 | 
					                        "id": "way/594963177",
 | 
				
			||||||
 | 
					                        "properties": {
 | 
				
			||||||
 | 
					                            "timestamp": "2021-12-05T04:04:55Z",
 | 
				
			||||||
 | 
					                            "version": 3,
 | 
				
			||||||
 | 
					                            "changeset": 114571409,
 | 
				
			||||||
 | 
					                            "user": "Pieter Vander Vennet",
 | 
				
			||||||
 | 
					                            "uid": 3818858,
 | 
				
			||||||
 | 
					                            "addr:housenumber": "171",
 | 
				
			||||||
 | 
					                            "addr:street": "Kortrijksestraat",
 | 
				
			||||||
 | 
					                            "building": "house",
 | 
				
			||||||
 | 
					                            "source:geometry:date": "2018-10-22",
 | 
				
			||||||
 | 
					                            "source:geometry:ref": "Gbg/5096537",
 | 
				
			||||||
 | 
					                            "_last_edit:contributor": "Pieter Vander Vennet",
 | 
				
			||||||
 | 
					                            "_last_edit:contributor:uid": 3818858,
 | 
				
			||||||
 | 
					                            "_last_edit:changeset": 114571409,
 | 
				
			||||||
 | 
					                            "_last_edit:timestamp": "2021-12-05T04:04:55Z",
 | 
				
			||||||
 | 
					                            "_version_number": 3,
 | 
				
			||||||
 | 
					                            "id": "way/594963177",
 | 
				
			||||||
 | 
					                            "_backend": "https://www.openstreetmap.org",
 | 
				
			||||||
 | 
					                            "_lat": "50.83736395",
 | 
				
			||||||
 | 
					                            "_lon": "3.2430937",
 | 
				
			||||||
 | 
					                            "_layer": "OSM-buildings",
 | 
				
			||||||
 | 
					                            "_length": "43.561938680928506",
 | 
				
			||||||
 | 
					                            "_length:km": "0.0",
 | 
				
			||||||
 | 
					                            "_now:date": "2021-12-05",
 | 
				
			||||||
 | 
					                            "_now:datetime": "2021-12-05 21:51:40",
 | 
				
			||||||
 | 
					                            "_loaded:date": "2021-12-05",
 | 
				
			||||||
 | 
					                            "_loaded:datetime": "2021-12-05 21:51:39",
 | 
				
			||||||
 | 
					                            "_surface": "93.32785810484549",
 | 
				
			||||||
 | 
					                            "_surface:ha": "0"
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        "geometry": {
 | 
				
			||||||
 | 
					                            "type": "Polygon",
 | 
				
			||||||
 | 
					                            "coordinates": [
 | 
				
			||||||
 | 
					                                [
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.2429993,
 | 
				
			||||||
 | 
					                                        50.8373243
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.243106,
 | 
				
			||||||
 | 
					                                        50.8373027
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.2431527,
 | 
				
			||||||
 | 
					                                        50.8373898
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.2431881,
 | 
				
			||||||
 | 
					                                        50.8374009
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.2431691,
 | 
				
			||||||
 | 
					                                        50.8374252
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.2430936,
 | 
				
			||||||
 | 
					                                        50.837401
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.243046,
 | 
				
			||||||
 | 
					                                        50.8374112
 | 
				
			||||||
 | 
					                                    ],
 | 
				
			||||||
 | 
					                                    [
 | 
				
			||||||
 | 
					                                        3.2429993,
 | 
				
			||||||
 | 
					                                        50.8373243
 | 
				
			||||||
 | 
					                                    ]
 | 
				
			||||||
 | 
					                                ]
 | 
				
			||||||
 | 
					                            ]
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        "_lon": 3.2430937,
 | 
				
			||||||
 | 
					                        "_lat": 50.83736395,
 | 
				
			||||||
 | 
					                        "bbox": {
 | 
				
			||||||
 | 
					                            "maxLat": 50.8374252,
 | 
				
			||||||
 | 
					                            "maxLon": 3.2431881,
 | 
				
			||||||
 | 
					                            "minLat": 50.8373027,
 | 
				
			||||||
 | 
					                            "minLon": 3.2429993
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    const overlaps = GeoOperations.calculateOverlap(polyGrb, [polyHouse])
 | 
				
			||||||
 | 
					                    Assert.equal(overlaps.length, 1)
 | 
				
			||||||
 | 
					                    const overlapsRev= GeoOperations.calculateOverlap(polyHouse, [polyGrb])
 | 
				
			||||||
 | 
					                    Assert.equal(overlaps.length, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                }]
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue