Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pygeofilter/cql2.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"a_equals": ast.ArrayEquals,
"a_contains": ast.ArrayContains,
"a_containedby": ast.ArrayContainedBy,
"a_containedBy": ast.ArrayContainedBy,
"a_overlaps": ast.ArrayOverlaps,
}

Expand Down
11 changes: 11 additions & 0 deletions pygeofilter/parsers/cql2_text/grammar.lark
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
| "EXCLUDE"i -> exclude
| spatial_predicate
| temporal_predicate
| array_predicate


?temporal_predicate: expression _binary_temporal_predicate_func expression -> binary_temporal_predicate
Expand Down Expand Up @@ -95,6 +96,14 @@
| "S_EQUALS"i


?array_predicate: _array_predicate_func "(" expression "," expression ")" -> binary_array_predicate

!_array_predicate_func: "A_EQUALS"i
| "A_CONTAINS"i
| "A_CONTAINEDBY"i
| "A_OVERLAPS"i


?expression: sum

?sum: product
Expand All @@ -109,6 +118,8 @@
| attribute
| literal
| "-" atom -> neg
| "(" ")" -> empty_array
| "(" expression ("," expression)+ ")" -> array
| "(" expression ")"

func.2: attribute "(" expression ("," expression)* ")" -> function
Expand Down
11 changes: 10 additions & 1 deletion pygeofilter/parsers/cql2_text/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from lark import Lark, logger, v_args

from ... import ast, values
from ...cql2 import SPATIAL_PREDICATES_MAP, TEMPORAL_PREDICATES_MAP
from ...cql2 import ARRAY_PREDICATES_MAP, SPATIAL_PREDICATES_MAP, TEMPORAL_PREDICATES_MAP
from ..iso8601 import ISO8601Transformer
from ..wkt import WKTTransformer

Expand Down Expand Up @@ -124,6 +124,15 @@ def during_or_after(self, node, period):
def after(self, node, dt):
return ast.TimeAfter(node, dt)

def binary_array_predicate(self, func, lhs, rhs):
return ARRAY_PREDICATES_MAP[func.lower()](lhs, rhs)

def array(self, *items):
return list(items)

def empty_array(self):
return []

def binary_spatial_predicate(self, op, lhs, rhs):
op = op.lower()
return SPATIAL_PREDICATES_MAP[op](lhs, rhs)
Expand Down
20 changes: 20 additions & 0 deletions tests/parsers/cql2_text/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,3 +477,23 @@ def test_not_eq():
assert result == ast.Not(
ast.Equal(ast.Attribute("attr"), 2)
)


def test_array_equals():
result = parse("A_EQUALS(attr, (1, 2, 3))")
assert result == ast.ArrayEquals(ast.Attribute("attr"), [1, 2, 3])


def test_array_contains():
result = parse("A_CONTAINS(attr, (1, 2, 3))")
assert result == ast.ArrayContains(ast.Attribute("attr"), [1, 2, 3])


def test_array_overlaps():
result = parse("A_OVERLAPS(attr, (1, 2, 3))")
assert result == ast.ArrayOverlaps(ast.Attribute("attr"), [1, 2, 3])


def test_array_empty():
result = parse("A_EQUALS(attr, ())")
assert result == ast.ArrayEquals(ast.Attribute("attr"), [])
Loading