forked from MapComplete/MapComplete
		
	
		
			
	
	
		
			119 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			119 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| 
								 | 
							
								import {TagsFilter} from "./TagsFilter";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export class And extends TagsFilter {
							 | 
						||
| 
								 | 
							
								    public and: TagsFilter[]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    constructor(and: TagsFilter[]) {
							 | 
						||
| 
								 | 
							
								        super();
							 | 
						||
| 
								 | 
							
								        this.and = and;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    private static combine(filter: string, choices: string[]): string[] {
							 | 
						||
| 
								 | 
							
								        const values = [];
							 | 
						||
| 
								 | 
							
								        for (const or of choices) {
							 | 
						||
| 
								 | 
							
								            values.push(filter + or);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return values;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    matchesProperties(tags: any): boolean {
							 | 
						||
| 
								 | 
							
								        for (const tagsFilter of this.and) {
							 | 
						||
| 
								 | 
							
								            if (!tagsFilter.matchesProperties(tags)) {
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    asOverpass(): string[] {
							 | 
						||
| 
								 | 
							
								        let allChoices: string[] = null;
							 | 
						||
| 
								 | 
							
								        for (const andElement of this.and) {
							 | 
						||
| 
								 | 
							
								            const andElementFilter = andElement.asOverpass();
							 | 
						||
| 
								 | 
							
								            if (allChoices === null) {
							 | 
						||
| 
								 | 
							
								                allChoices = andElementFilter;
							 | 
						||
| 
								 | 
							
								                continue;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            const newChoices: string[] = [];
							 | 
						||
| 
								 | 
							
								            for (const choice of allChoices) {
							 | 
						||
| 
								 | 
							
								                newChoices.push(
							 | 
						||
| 
								 | 
							
								                    ...And.combine(choice, andElementFilter)
							 | 
						||
| 
								 | 
							
								                )
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            allChoices = newChoices;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return allChoices;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    substituteValues(tags: any): TagsFilter {
							 | 
						||
| 
								 | 
							
								        const newChoices = [];
							 | 
						||
| 
								 | 
							
								        for (const c of this.and) {
							 | 
						||
| 
								 | 
							
								            newChoices.push(c.substituteValues(tags));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return new And(newChoices);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    asHumanString(linkToWiki: boolean, shorten: boolean) {
							 | 
						||
| 
								 | 
							
								        return this.and.map(t => t.asHumanString(linkToWiki, shorten)).join("&");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    isUsableAsAnswer(): boolean {
							 | 
						||
| 
								 | 
							
								        for (const t of this.and) {
							 | 
						||
| 
								 | 
							
								            if (!t.isUsableAsAnswer()) {
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    isEquivalent(other: TagsFilter): boolean {
							 | 
						||
| 
								 | 
							
								        if (!(other instanceof And)) {
							 | 
						||
| 
								 | 
							
								            return false;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for (const selfTag of this.and) {
							 | 
						||
| 
								 | 
							
								            let matchFound = false;
							 | 
						||
| 
								 | 
							
								            for (let i = 0; i < other.and.length && !matchFound; i++) {
							 | 
						||
| 
								 | 
							
								                let otherTag = other.and[i];
							 | 
						||
| 
								 | 
							
								                matchFound = selfTag.isEquivalent(otherTag);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (!matchFound) {
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for (const selfTag of this.and) {
							 | 
						||
| 
								 | 
							
								            let matchFound = false;
							 | 
						||
| 
								 | 
							
								            for (const otherTag of other.and) {
							 | 
						||
| 
								 | 
							
								                matchFound = selfTag.isEquivalent(otherTag);
							 | 
						||
| 
								 | 
							
								                if (matchFound) {
							 | 
						||
| 
								 | 
							
								                    break;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (!matchFound) {
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for (const otherTag of other.and) {
							 | 
						||
| 
								 | 
							
								            let matchFound = false;
							 | 
						||
| 
								 | 
							
								            for (const selfTag of this.and) {
							 | 
						||
| 
								 | 
							
								                matchFound = selfTag.isEquivalent(otherTag);
							 | 
						||
| 
								 | 
							
								                if (matchFound) {
							 | 
						||
| 
								 | 
							
								                    break;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (!matchFound) {
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    usedKeys(): string[] {
							 | 
						||
| 
								 | 
							
								        return [].concat(...this.and.map(subkeys => subkeys.usedKeys()));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |