forked from MapComplete/MapComplete
Optimize queries to overpass
This commit is contained in:
parent
fbcb72df7a
commit
9008e333ac
15 changed files with 787 additions and 18 deletions
File diff suppressed because one or more lines are too long
141
test/Tag.spec.ts
141
test/Tag.spec.ts
|
@ -9,6 +9,9 @@ import {Tag} from "../Logic/Tags/Tag";
|
|||
import {And} from "../Logic/Tags/And";
|
||||
import {TagUtils} from "../Logic/Tags/TagUtils";
|
||||
import TagRenderingConfig from "../Models/ThemeConfig/TagRenderingConfig";
|
||||
import {TagsFilter} from "../Logic/Tags/TagsFilter";
|
||||
import {Or} from "../Logic/Tags/Or";
|
||||
import {RegexTag} from "../Logic/Tags/RegexTag";
|
||||
|
||||
export default class TagSpec extends T {
|
||||
|
||||
|
@ -21,6 +24,133 @@ export default class TagSpec extends T {
|
|||
equal(tr.txt, "Test value abc");
|
||||
|
||||
}],
|
||||
["Optimize tags", () => {
|
||||
|
||||
let t : TagsFilter= new And(
|
||||
[
|
||||
new And([
|
||||
new Tag("x", "y")
|
||||
]),
|
||||
new Tag("a", "b")
|
||||
]
|
||||
)
|
||||
let opt =<TagsFilter> t.optimize()
|
||||
console.log(TagUtils.toString(opt))
|
||||
T.equals(`a=b&x=y`,TagUtils.toString(opt), "Optimization failed")
|
||||
|
||||
|
||||
// foo&bar & (x=y | a=b) & (x=y | c=d) & foo=bar is equivalent too foo=bar & ((x=y) | (a=b & c=d))
|
||||
t = new And([
|
||||
new Tag("foo","bar"),
|
||||
new Or([
|
||||
new Tag("x", "y"),
|
||||
new Tag("a", "b")
|
||||
]),
|
||||
new Or([
|
||||
new Tag("x", "y"),
|
||||
new Tag("c", "d")
|
||||
])
|
||||
])
|
||||
opt =<TagsFilter> t.optimize()
|
||||
console.log(TagUtils.toString(opt))
|
||||
T.equals(TagUtils.toString(opt), "foo=bar& (x=y| (a=b&c=d) )")
|
||||
|
||||
t = new Or([
|
||||
new Tag("foo","bar"),
|
||||
new And([
|
||||
new Tag("foo", "bar"),
|
||||
new Tag("x", "y"),
|
||||
])
|
||||
])
|
||||
opt =<TagsFilter> t.optimize()
|
||||
console.log(TagUtils.toString(opt))
|
||||
T.equals("foo=bar", TagUtils.toString(opt), "Optimizing away an unneeded factor failed")
|
||||
|
||||
|
||||
t = new And([
|
||||
new RegexTag("x","y"),
|
||||
new Tag("a","b")
|
||||
])
|
||||
opt =<TagsFilter> t.optimize()
|
||||
T.equals("a=b&x~^y$", TagUtils.toString(opt), "Regexes go to the end")
|
||||
|
||||
t = new And([
|
||||
new Tag("bicycle","yes"),
|
||||
new Tag("amenity","binoculars")
|
||||
])
|
||||
opt =<TagsFilter> t.optimize()
|
||||
T.equals("amenity=binoculars&bicycle=yes", TagUtils.toString(opt), "Common keys go to the end")
|
||||
|
||||
|
||||
|
||||
|
||||
const filter = TagUtils.Tag( {or: [
|
||||
{
|
||||
"and": [
|
||||
{
|
||||
"or": ["amenity=charging_station","disused:amenity=charging_station","planned:amenity=charging_station","construction:amenity=charging_station"]
|
||||
},
|
||||
"bicycle=yes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"and": [
|
||||
{
|
||||
"or": ["amenity=charging_station","disused:amenity=charging_station","planned:amenity=charging_station","construction:amenity=charging_station"]
|
||||
},
|
||||
]
|
||||
},
|
||||
"amenity=toilets",
|
||||
"amenity=bench",
|
||||
"leisure=picnic_table",
|
||||
{
|
||||
"and": [
|
||||
"tower:type=observation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"and": [
|
||||
"amenity=bicycle_repair_station"
|
||||
]
|
||||
},
|
||||
{
|
||||
"and": [
|
||||
{
|
||||
"or": [
|
||||
"amenity=bicycle_rental",
|
||||
"bicycle_rental~*",
|
||||
"service:bicycle:rental=yes",
|
||||
"rental~.*bicycle.*"
|
||||
]
|
||||
},
|
||||
"bicycle_rental!=docking_station"
|
||||
]
|
||||
},
|
||||
{
|
||||
"and": [
|
||||
"leisure=playground",
|
||||
"playground!=forest"
|
||||
]
|
||||
}
|
||||
]});
|
||||
|
||||
opt = <TagsFilter> filter.optimize()
|
||||
console.log(TagUtils.toString(opt))
|
||||
T.equals(("amenity=charging_station|" +
|
||||
"amenity=toilets|" +
|
||||
"amenity=bench|" +
|
||||
"amenity=bicycle_repair_station" +
|
||||
"|construction:amenity=charging_station|" +
|
||||
"disused:amenity=charging_station|" +
|
||||
"leisure=picnic_table|" +
|
||||
"planned:amenity=charging_station|" +
|
||||
"tower:type=observation| " +
|
||||
"( (amenity=bicycle_rental|service:bicycle:rental=yes|bicycle_rental~^..*$|rental~^.*bicycle.*$) &bicycle_rental!~^docking_station$) |" +
|
||||
" (leisure=playground&playground!~^forest$)").replace(/ /g, ""),
|
||||
TagUtils.toString(opt).replace(/ /g, ""), "Advanced case failed")
|
||||
}],
|
||||
|
||||
|
||||
["Parse tag config", (() => {
|
||||
const tag = TagUtils.Tag("key=value") as Tag;
|
||||
equal(tag.key, "key");
|
||||
|
@ -217,6 +347,17 @@ export default class TagSpec extends T {
|
|||
equal(3, overpassOrInor.length)
|
||||
}
|
||||
],
|
||||
[
|
||||
"Test regex to overpass",() => {
|
||||
/*(Specifiation to parse, expected value for new RegexTag(spec).asOverpass()[0]) */
|
||||
[["a~*", `"a"`],
|
||||
["a~[xyz]",`"a"~"^[xyz]$"`]].forEach(([spec, expected]) =>{
|
||||
T.equals(`[${expected}]`, TagUtils.Tag(
|
||||
spec
|
||||
).asOverpass()[0], "RegexRendering failed")
|
||||
} )
|
||||
}
|
||||
],
|
||||
[
|
||||
"Merge touching opening hours",
|
||||
() => {
|
||||
|
|
|
@ -20,11 +20,11 @@ export default class T {
|
|||
}
|
||||
}
|
||||
|
||||
static equals(a, b, msg?) {
|
||||
if (a !== b) {
|
||||
static equals(expected, got, msg?) {
|
||||
if (expected !== got) {
|
||||
throw "Not the same: " + (msg ?? "") + "\n" +
|
||||
"Expcected: " + a + "\n" +
|
||||
"Got : " + b
|
||||
"Expected: " + expected + "\n" +
|
||||
"Got : " + got
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ export default class T {
|
|||
throw `ListIdentical failed: expected a list of length ${expected.length} but got a list of length ${actual.length}`
|
||||
}
|
||||
for (let i = 0; i < expected.length; i++) {
|
||||
if (expected[i] !== undefined && expected[i]["length"] !== undefined) {
|
||||
if (Array.isArray(expected[i])) {
|
||||
T.listIdentical(<any>expected[i], <any>actual[i])
|
||||
} else if (expected[i] !== actual[i]) {
|
||||
throw `ListIdentical failed at index ${i}: expected ${expected[i]} but got ${actual[i]}`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue