forked from MapComplete/MapComplete
		
	Merge branch 'master' of github.com:pietervdvn/MapComplete
This commit is contained in:
		
						commit
						ba26bf3e63
					
				
					 6 changed files with 2305 additions and 2340 deletions
				
			
		| 
						 | 
					@ -83,6 +83,7 @@ export interface TagRenderingConfigJson {
 | 
				
			||||||
     * Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes
 | 
					     * Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    mappings?: {
 | 
					    mappings?: {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * If this condition is met, then the text under `then` will be shown.
 | 
					         * If this condition is met, then the text under `then` will be shown.
 | 
				
			||||||
         * If no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.
 | 
					         * If no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.
 | 
				
			||||||
| 
						 | 
					@ -168,6 +169,13 @@ export interface TagRenderingConfigJson {
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        ifnot?: AndOrTagConfigJson | string
 | 
					        ifnot?: AndOrTagConfigJson | string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * If chosen as answer, these tags will be applied as well onto the object.
 | 
				
			||||||
 | 
					         * Not compatible with multiAnswer
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        addExtraTags: string[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }[]
 | 
					    }[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@ import {TagUtils} from "../../Logic/Tags/TagUtils";
 | 
				
			||||||
import {And} from "../../Logic/Tags/And";
 | 
					import {And} from "../../Logic/Tags/And";
 | 
				
			||||||
import ValidatedTextField from "../../UI/Input/ValidatedTextField";
 | 
					import ValidatedTextField from "../../UI/Input/ValidatedTextField";
 | 
				
			||||||
import {Utils} from "../../Utils";
 | 
					import {Utils} from "../../Utils";
 | 
				
			||||||
 | 
					import {Tag} from "../../Logic/Tags/Tag";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***
 | 
					/***
 | 
				
			||||||
 * The parsed version of TagRenderingConfigJSON
 | 
					 * The parsed version of TagRenderingConfigJSON
 | 
				
			||||||
| 
						 | 
					@ -36,6 +37,7 @@ export default class TagRenderingConfig {
 | 
				
			||||||
        readonly ifnot?: TagsFilter,
 | 
					        readonly ifnot?: TagsFilter,
 | 
				
			||||||
        readonly then: Translation
 | 
					        readonly then: Translation
 | 
				
			||||||
        readonly hideInAnswer: boolean | TagsFilter
 | 
					        readonly hideInAnswer: boolean | TagsFilter
 | 
				
			||||||
 | 
					        readonly addExtraTags: Tag[]
 | 
				
			||||||
    }[]
 | 
					    }[]
 | 
				
			||||||
    readonly roaming: boolean;
 | 
					    readonly roaming: boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,21 +121,24 @@ export default class TagRenderingConfig {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.mappings = json.mappings.map((mapping, i) => {
 | 
					            this.mappings = json.mappings.map((mapping, i) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                const ctx = `${context}.mapping[${i}]`
 | 
				
			||||||
                if (mapping.then === undefined) {
 | 
					                if (mapping.then === undefined) {
 | 
				
			||||||
                    throw `${context}.mapping[${i}]: Invalid mapping: if without body`
 | 
					                    throw `${ctx}: Invalid mapping: if without body`
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (mapping.ifnot !== undefined && !this.multiAnswer) {
 | 
					                if (mapping.ifnot !== undefined && !this.multiAnswer) {
 | 
				
			||||||
                    throw `${context}.mapping[${i}]: Invalid mapping: ifnot defined, but the tagrendering is not a multianswer`
 | 
					                    throw `${ctx}: Invalid mapping: ifnot defined, but the tagrendering is not a multianswer`
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (mapping.if === undefined) {
 | 
					                if (mapping.if === undefined) {
 | 
				
			||||||
                    throw `${context}.mapping[${i}]: Invalid mapping: "if" is not defined, but the tagrendering is not a multianswer`
 | 
					                    throw `${ctx}: Invalid mapping: "if" is not defined, but the tagrendering is not a multianswer`
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (typeof mapping.if !== "string" && mapping.if["length"] !== undefined) {
 | 
					                if (typeof mapping.if !== "string" && mapping.if["length"] !== undefined) {
 | 
				
			||||||
                    throw `${context}.mapping[${i}]: Invalid mapping: "if" is defined as an array. Use {"and": <your conditions>} or {"or": <your conditions>} instead`
 | 
					                    throw `${ctx}: Invalid mapping: "if" is defined as an array. Use {"and": <your conditions>} or {"or": <your conditions>} instead`
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if(mapping.addExtraTags !== undefined && this.multiAnswer){
 | 
				
			||||||
 | 
					                    throw `${ctx}: Invalid mapping: got a multi-Answer with addExtraTags; this is not allowed`
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let hideInAnswer: boolean | TagsFilter = false;
 | 
					                let hideInAnswer: boolean | TagsFilter = false;
 | 
				
			||||||
                if (typeof mapping.hideInAnswer === "boolean") {
 | 
					                if (typeof mapping.hideInAnswer === "boolean") {
 | 
				
			||||||
| 
						 | 
					@ -141,12 +146,12 @@ export default class TagRenderingConfig {
 | 
				
			||||||
                } else if (mapping.hideInAnswer !== undefined) {
 | 
					                } else if (mapping.hideInAnswer !== undefined) {
 | 
				
			||||||
                    hideInAnswer = TagUtils.Tag(mapping.hideInAnswer, `${context}.mapping[${i}].hideInAnswer`);
 | 
					                    hideInAnswer = TagUtils.Tag(mapping.hideInAnswer, `${context}.mapping[${i}].hideInAnswer`);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                const mappingContext = `${context}.mapping[${i}]`
 | 
					 | 
				
			||||||
                const mp = {
 | 
					                const mp = {
 | 
				
			||||||
                    if: TagUtils.Tag(mapping.if, `${mappingContext}.if`),
 | 
					                    if: TagUtils.Tag(mapping.if, `${ctx}.if`),
 | 
				
			||||||
                    ifnot: (mapping.ifnot !== undefined ? TagUtils.Tag(mapping.ifnot, `${mappingContext}.ifnot`) : undefined),
 | 
					                    ifnot: (mapping.ifnot !== undefined ? TagUtils.Tag(mapping.ifnot, `${ctx}.ifnot`) : undefined),
 | 
				
			||||||
                    then: Translations.T(mapping.then, `{mappingContext}.then`),
 | 
					                    then: Translations.T(mapping.then, `{mappingContext}.then`),
 | 
				
			||||||
                    hideInAnswer: hideInAnswer
 | 
					                    hideInAnswer: hideInAnswer,
 | 
				
			||||||
 | 
					                    addExtraTags: (mapping.addExtraTags??[]).map((str, j) => TagUtils.SimpleTag(str, `${ctx}.addExtraTags[${j}]`))
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
                if (this.question) {
 | 
					                if (this.question) {
 | 
				
			||||||
                    if (hideInAnswer !== true && mp.if !== undefined && !mp.if.isUsableAsAnswer()) {
 | 
					                    if (hideInAnswer !== true && mp.if !== undefined && !mp.if.isUsableAsAnswer()) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,7 +49,7 @@ export default class TagRenderingQuestion extends Combine {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const applicableMappingsSrc =
 | 
					        const applicableMappingsSrc =
 | 
				
			||||||
            UIEventSource.ListStabilized(tags.map(tags => {
 | 
					            UIEventSource.ListStabilized(tags.map(tags => {
 | 
				
			||||||
                const applicableMappings: { if: TagsFilter, then: any, ifnot?: TagsFilter }[] = []
 | 
					                const applicableMappings: { if: TagsFilter, then: any, ifnot?: TagsFilter, addExtraTags: Tag[] }[] = []
 | 
				
			||||||
                for (const mapping of configuration.mappings ?? []) {
 | 
					                for (const mapping of configuration.mappings ?? []) {
 | 
				
			||||||
                    if (mapping.hideInAnswer === true) {
 | 
					                    if (mapping.hideInAnswer === true) {
 | 
				
			||||||
                        continue
 | 
					                        continue
 | 
				
			||||||
| 
						 | 
					@ -108,9 +108,9 @@ export default class TagRenderingQuestion extends Combine {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const saveButton = new Combine([
 | 
					        const saveButton = new Combine([
 | 
				
			||||||
            options.saveButtonConstr(inputElement.GetValue()),
 | 
					            options.saveButtonConstr(inputElement.GetValue()),
 | 
				
			||||||
            new Toggle(Translations.t.general.testing, undefined, State.state.featureSwitchIsTesting).SetClass("alert")
 | 
					            new Toggle(Translations.t.general.testing.SetClass("alert"), undefined, State.state.featureSwitchIsTesting)
 | 
				
			||||||
        ])
 | 
					        ])
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        let bottomTags: BaseUIElement;
 | 
					        let bottomTags: BaseUIElement;
 | 
				
			||||||
        if (options.bottomText !== undefined) {
 | 
					        if (options.bottomText !== undefined) {
 | 
				
			||||||
            bottomTags = options.bottomText(inputElement.GetValue())
 | 
					            bottomTags = options.bottomText(inputElement.GetValue())
 | 
				
			||||||
| 
						 | 
					@ -147,7 +147,7 @@ export default class TagRenderingQuestion extends Combine {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static GenerateInputElement(configuration: TagRenderingConfig,
 | 
					    private static GenerateInputElement(configuration: TagRenderingConfig,
 | 
				
			||||||
                                        applicableMappings: { if: TagsFilter, then: any, ifnot?: TagsFilter }[],
 | 
					                                        applicableMappings: { if: TagsFilter, then: any, ifnot?: TagsFilter, addExtraTags: Tag[] }[],
 | 
				
			||||||
                                        applicableUnit: Unit,
 | 
					                                        applicableUnit: Unit,
 | 
				
			||||||
                                        tagsSource: UIEventSource<any>)
 | 
					                                        tagsSource: UIEventSource<any>)
 | 
				
			||||||
        : InputElement<TagsFilter> {
 | 
					        : InputElement<TagsFilter> {
 | 
				
			||||||
| 
						 | 
					@ -341,12 +341,16 @@ export default class TagRenderingQuestion extends Combine {
 | 
				
			||||||
        mapping: {
 | 
					        mapping: {
 | 
				
			||||||
            if: TagsFilter,
 | 
					            if: TagsFilter,
 | 
				
			||||||
            then: Translation,
 | 
					            then: Translation,
 | 
				
			||||||
 | 
					            addExtraTags: Tag[]
 | 
				
			||||||
        }, ifNot?: TagsFilter[]): InputElement<TagsFilter> {
 | 
					        }, ifNot?: TagsFilter[]): InputElement<TagsFilter> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let tagging: TagsFilter = mapping.if;
 | 
					        let tagging: TagsFilter = mapping.if;
 | 
				
			||||||
        if (ifNot !== undefined) {
 | 
					        if (ifNot !== undefined) {
 | 
				
			||||||
            tagging = new And([mapping.if, ...ifNot])
 | 
					            tagging = new And([mapping.if, ...ifNot])
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (mapping.addExtraTags) {
 | 
				
			||||||
 | 
					            tagging = new And([tagging, ...mapping.addExtraTags])
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return new FixedInputElement(
 | 
					        return new FixedInputElement(
 | 
				
			||||||
            new SubstitutedTranslation(mapping.then, tagsSource),
 | 
					            new SubstitutedTranslation(mapping.then, tagsSource),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -83,7 +83,6 @@
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "description": {},
 | 
					 | 
				
			||||||
    "tagRenderings": [
 | 
					    "tagRenderings": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "question": {
 | 
					            "question": {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										85
									
								
								scripts/slice.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								scripts/slice.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,85 @@
 | 
				
			||||||
 | 
					import * as fs from "fs";
 | 
				
			||||||
 | 
					import TiledFeatureSource from "../Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource";
 | 
				
			||||||
 | 
					import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSource";
 | 
				
			||||||
 | 
					import * as readline from "readline";
 | 
				
			||||||
 | 
					import ScriptUtils from "./ScriptUtils";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function main(args: string[]) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    console.log("GeoJSON slicer")
 | 
				
			||||||
 | 
					    if (args.length < 3) {
 | 
				
			||||||
 | 
					        console.log("USAGE: <input-file.line-delimited-geojson> <target-zoom-level> <output-directory>")
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const inputFile = args[0]
 | 
				
			||||||
 | 
					    const zoomlevel = Number(args[1])
 | 
				
			||||||
 | 
					    const outputDirectory = args[2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!fs.existsSync(outputDirectory)) {
 | 
				
			||||||
 | 
					        fs.mkdirSync(outputDirectory)
 | 
				
			||||||
 | 
					        console.log("Directory created")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    console.log("Using directory ", outputDirectory)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const fileStream = fs.createReadStream(inputFile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const rl = readline.createInterface({
 | 
				
			||||||
 | 
					        input: fileStream,
 | 
				
			||||||
 | 
					        crlfDelay: Infinity
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    // Note: we use the crlfDelay option to recognize all instances of CR LF
 | 
				
			||||||
 | 
					    // ('\r\n') in input.txt as a single line break.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const allFeatures = []
 | 
				
			||||||
 | 
					    // @ts-ignore
 | 
				
			||||||
 | 
					    for await (const line of rl) {
 | 
				
			||||||
 | 
					        // Each line in input.txt will be successively available here as `line`.
 | 
				
			||||||
 | 
					        try{
 | 
				
			||||||
 | 
					            allFeatures.push(JSON.parse(line))
 | 
				
			||||||
 | 
					        }catch (e) {
 | 
				
			||||||
 | 
					            console.error("Could not parse", line)
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if(allFeatures.length % 10000 === 0){
 | 
				
			||||||
 | 
					            ScriptUtils.erasableLog("Loaded ", allFeatures.length, "features up till now")
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    console.log("Loaded all", allFeatures.length, "points")
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					    const keysToRemove = ["ID","STRAATNMID","NISCODE","GEMEENTE","POSTCODE","HERKOMST","APPTNR"]
 | 
				
			||||||
 | 
					    for (const f of allFeatures) {
 | 
				
			||||||
 | 
					        for (const keyToRm of keysToRemove) {
 | 
				
			||||||
 | 
					            delete f.properties[keyToRm]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    //const knownKeys = Utils.Dedup([].concat(...allFeatures.map(f => Object.keys(f.properties))))
 | 
				
			||||||
 | 
					    //console.log("Kept keys: ", knownKeys)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TiledFeatureSource.createHierarchy(
 | 
				
			||||||
 | 
					        new StaticFeatureSource(allFeatures, false),
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            minZoomLevel: zoomlevel,
 | 
				
			||||||
 | 
					            maxZoomLevel: zoomlevel,
 | 
				
			||||||
 | 
					            maxFeatureCount: Number.MAX_VALUE,
 | 
				
			||||||
 | 
					            registerTile: tile => {
 | 
				
			||||||
 | 
					                const path = `${outputDirectory}/tile_${tile.z}_${tile.x}_${tile.y}.geojson`
 | 
				
			||||||
 | 
					                fs.writeFileSync(path, JSON.stringify({
 | 
				
			||||||
 | 
					                    "type": "FeatureCollection",
 | 
				
			||||||
 | 
					                    "features": tile.features.data.map(ff => ff.feature)
 | 
				
			||||||
 | 
					                }, null, "  "))
 | 
				
			||||||
 | 
					                console.log("Written ", path, "which has ", tile.features.data.length, "features")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let args = [...process.argv]
 | 
				
			||||||
 | 
					args.splice(0, 2)
 | 
				
			||||||
 | 
					main(args).then(_ => {
 | 
				
			||||||
 | 
					    console.log("All done!")
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue