diff --git a/Logic/Tags/And.ts b/Logic/Tags/And.ts index 426e2addc..fa79d3eda 100644 --- a/Logic/Tags/And.ts +++ b/Logic/Tags/And.ts @@ -238,4 +238,8 @@ export class And extends TagsFilter { return new And(newAnds) } + + isNegative(): boolean { + return !this.and.some(t => !t.isNegative()); + } } \ No newline at end of file diff --git a/Logic/Tags/ComparingTag.ts b/Logic/Tags/ComparingTag.ts index 20d5ffbde..6b790311b 100644 --- a/Logic/Tags/ComparingTag.ts +++ b/Logic/Tags/ComparingTag.ts @@ -59,4 +59,8 @@ export default class ComparingTag implements TagsFilter { optimize(): TagsFilter | boolean { return this; } + + isNegative(): boolean { + return true; + } } \ No newline at end of file diff --git a/Logic/Tags/Or.ts b/Logic/Tags/Or.ts index 2ff799178..07f50629b 100644 --- a/Logic/Tags/Or.ts +++ b/Logic/Tags/Or.ts @@ -167,6 +167,10 @@ export class Or extends TagsFilter { return new Or(newOrs) } + + isNegative(): boolean { + return this.or.some(t => t.isNegative()); + } } diff --git a/Logic/Tags/RegexTag.ts b/Logic/Tags/RegexTag.ts index b3a48b6a1..8a4c7ad3b 100644 --- a/Logic/Tags/RegexTag.ts +++ b/Logic/Tags/RegexTag.ts @@ -197,4 +197,8 @@ export class RegexTag extends TagsFilter { optimize(): TagsFilter | boolean { return this; } + + isNegative(): boolean { + return this.invert; + } } \ No newline at end of file diff --git a/Logic/Tags/SubstitutingTag.ts b/Logic/Tags/SubstitutingTag.ts index 41b114ec3..532c2586e 100644 --- a/Logic/Tags/SubstitutingTag.ts +++ b/Logic/Tags/SubstitutingTag.ts @@ -89,4 +89,8 @@ export default class SubstitutingTag implements TagsFilter { optimize(): TagsFilter | boolean { return this; } + + isNegative(): boolean { + return false; + } } \ No newline at end of file diff --git a/Logic/Tags/Tag.ts b/Logic/Tags/Tag.ts index 9bc1b1eba..9a4919688 100644 --- a/Logic/Tags/Tag.ts +++ b/Logic/Tags/Tag.ts @@ -120,4 +120,8 @@ export class Tag extends TagsFilter { optimize(): TagsFilter | boolean { return this; } + + isNegative(): boolean { + return false; + } } \ No newline at end of file diff --git a/Logic/Tags/TagUtils.ts b/Logic/Tags/TagUtils.ts index cd4a90f85..d72008136 100644 --- a/Logic/Tags/TagUtils.ts +++ b/Logic/Tags/TagUtils.ts @@ -172,7 +172,7 @@ export class TagUtils { * * TagUtils.Tag("key=value") // => new Tag("key", "value") * TagUtils.Tag("key=") // => new Tag("key", "") - * TagUtils.Tag("key!=") // => new RegexTag("key", "^..*$", true) + * TagUtils.Tag("key!=") // => new RegexTag("key", "^..*$") * TagUtils.Tag("key!=value") // => new RegexTag("key", /^value$/, true) * TagUtils.Tag("vending~.*bicycle_tube.*") // => new RegexTag("vending", /^.*bicycle_tube.*$/) * TagUtils.Tag("x!~y") // => new RegexTag("x", /^y$/, true) @@ -298,6 +298,7 @@ export class TagUtils { } if (split[1] === "") { split[1] = "..*" + return new RegexTag(split[0], /^..*$/) } return new RegexTag( split[0], diff --git a/Logic/Tags/TagsFilter.ts b/Logic/Tags/TagsFilter.ts index 5a9270953..c505fe117 100644 --- a/Logic/Tags/TagsFilter.ts +++ b/Logic/Tags/TagsFilter.ts @@ -33,5 +33,21 @@ export abstract class TagsFilter { */ abstract optimize(): TagsFilter | boolean; - + /** + * Returns 'true' if the tagsfilter might select all features (i.e. the filter will return everything from OSM, except a few entries). + * + * A typical negative tagsfilter is 'key!=value' + * + * import {RegexTag} from "./RegexTag"; + * import {Tag} from "./Tag"; + * import {And} from "./And"; + * import {Or} from "./Or"; + * + * new Tag("key","value").isNegative() // => false + * new And([new RegexTag("key","value", true)]).isNegative() // => true + * new Or([new RegexTag("key","value", true), new Tag("x","y")]).isNegative() // => true + * new And([new RegexTag("key","value", true), new Tag("x","y")]).isNegative() // => false + */ + abstract isNegative(): boolean + } \ No newline at end of file diff --git a/Models/Constants.ts b/Models/Constants.ts index 7f6124ad3..cd587284f 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.17.0"; + public static vNumber = "0.17.1"; public static ImgurApiKey = '7070e7167f0a25a' public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index 405cf59be..94d663096 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -101,6 +101,10 @@ export default class LayerConfig extends WithContextLoader { context + "source.osmTags" ); + if(Constants.priviliged_layers.indexOf(this.id) < 0 && osmTags.isNegative()){ + throw context + "The source states tags which give a very wide selection: it only uses negative expressions, which will result in too much and unexpected data. Add at least one required tag. The tags are:\n\t"+osmTags.asHumanString(false, false, {}); + } + if (json.source["geoJsonSource"] !== undefined) { throw context + "Use 'geoJson' instead of 'geoJsonSource'"; } @@ -108,6 +112,7 @@ export default class LayerConfig extends WithContextLoader { if (json.source["geojson"] !== undefined) { throw context + "Use 'geoJson' instead of 'geojson' (the J is a capital letter)"; } + this.source = new SourceConfig( {