119 lines
No EOL
3.1 KiB
TypeScript
119 lines
No EOL
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()));
|
|
}
|
|
} |