forked from MapComplete/MapComplete
		
	
		
			
	
	
		
			121 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			121 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| 
								 | 
							
								import {Tag} from "./Tag";
							 | 
						||
| 
								 | 
							
								import {TagsFilter} from "./TagsFilter";
							 | 
						||
| 
								 | 
							
								import {And} from "./And";
							 | 
						||
| 
								 | 
							
								import {Utils} from "../Utils";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export class TagUtils {
							 | 
						||
| 
								 | 
							
								    static ApplyTemplate(template: string, tags: any): string {
							 | 
						||
| 
								 | 
							
								        for (const k in tags) {
							 | 
						||
| 
								 | 
							
								            while (template.indexOf("{" + k + "}") >= 0) {
							 | 
						||
| 
								 | 
							
								                const escaped = tags[k].replace(/</g, '<').replace(/>/g, '>');
							 | 
						||
| 
								 | 
							
								                template = template.replace("{" + k + "}", escaped);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return template;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static KVtoProperties(tags: Tag[]): any {
							 | 
						||
| 
								 | 
							
								        const properties = {};
							 | 
						||
| 
								 | 
							
								        for (const tag of tags) {
							 | 
						||
| 
								 | 
							
								            properties[tag.key] = tag.value
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return properties;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Given two hashes of {key --> values[]}, makes sure that every neededTag is present in availableTags
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    static AllKeysAreContained(availableTags: any, neededTags: any) {
							 | 
						||
| 
								 | 
							
								        for (const neededKey in neededTags) {
							 | 
						||
| 
								 | 
							
								            const availableValues: string[] = availableTags[neededKey]
							 | 
						||
| 
								 | 
							
								            if (availableValues === undefined) {
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            const neededValues: string[] = neededTags[neededKey];
							 | 
						||
| 
								 | 
							
								            for (const neededValue of neededValues) {
							 | 
						||
| 
								 | 
							
								                if (availableValues.indexOf(neededValue) < 0) {
							 | 
						||
| 
								 | 
							
								                    return false;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /***
							 | 
						||
| 
								 | 
							
								     * Creates a hash {key --> [values]}, with all the values present in the tagsfilter
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param tagsFilters
							 | 
						||
| 
								 | 
							
								     * @constructor
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    static SplitKeys(tagsFilters: TagsFilter[]) {
							 | 
						||
| 
								 | 
							
								        const keyValues = {} // Map string -> string[]
							 | 
						||
| 
								 | 
							
								        tagsFilters = [...tagsFilters] // copy all
							 | 
						||
| 
								 | 
							
								        while (tagsFilters.length > 0) {
							 | 
						||
| 
								 | 
							
								            // Queue
							 | 
						||
| 
								 | 
							
								            const tagsFilter = tagsFilters.shift();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (tagsFilter === undefined) {
							 | 
						||
| 
								 | 
							
								                continue;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (tagsFilter instanceof And) {
							 | 
						||
| 
								 | 
							
								                tagsFilters.push(...tagsFilter.and);
							 | 
						||
| 
								 | 
							
								                continue;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (tagsFilter instanceof Tag) {
							 | 
						||
| 
								 | 
							
								                if (keyValues[tagsFilter.key] === undefined) {
							 | 
						||
| 
								 | 
							
								                    keyValues[tagsFilter.key] = [];
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                keyValues[tagsFilter.key].push(...tagsFilter.value.split(";"));
							 | 
						||
| 
								 | 
							
								                continue;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            console.error("Invalid type to flatten the multiAnswer", tagsFilter);
							 | 
						||
| 
								 | 
							
								            throw "Invalid type to FlattenMultiAnswer"
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return keyValues;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Given multiple tagsfilters which can be used as answer, will take the tags with the same keys together as set.
							 | 
						||
| 
								 | 
							
								     * E.g:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * FlattenMultiAnswer([and: [ "x=a", "y=0;1"], and: ["x=b", "y=2"], and: ["x=", "y=3"]])
							 | 
						||
| 
								 | 
							
								     * will result in
							 | 
						||
| 
								 | 
							
								     * ["x=a;b", "y=0;1;2;3"]
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param tagsFilters
							 | 
						||
| 
								 | 
							
								     * @constructor
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    static FlattenMultiAnswer(tagsFilters: TagsFilter[]): And {
							 | 
						||
| 
								 | 
							
								        if (tagsFilters === undefined) {
							 | 
						||
| 
								 | 
							
								            return new And([]);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        let keyValues = TagUtils.SplitKeys(tagsFilters);
							 | 
						||
| 
								 | 
							
								        const and: TagsFilter[] = []
							 | 
						||
| 
								 | 
							
								        for (const key in keyValues) {
							 | 
						||
| 
								 | 
							
								            and.push(new Tag(key, Utils.Dedup(keyValues[key]).join(";")));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return new And(and);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static MatchesMultiAnswer(tag: TagsFilter, tags: any): boolean {
							 | 
						||
| 
								 | 
							
								        const splitted = TagUtils.SplitKeys([tag]);
							 | 
						||
| 
								 | 
							
								        for (const splitKey in splitted) {
							 | 
						||
| 
								 | 
							
								            const neededValues = splitted[splitKey];
							 | 
						||
| 
								 | 
							
								            if (tags[splitKey] === undefined) {
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            const actualValue = tags[splitKey].split(";");
							 | 
						||
| 
								 | 
							
								            for (const neededValue of neededValues) {
							 | 
						||
| 
								 | 
							
								                if (actualValue.indexOf(neededValue) < 0) {
							 | 
						||
| 
								 | 
							
								                    return false;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |