def test_fes20_c5_example14(): """This example restricts the active set of objects to those instances of the Person type that are older than 50 years old and live in Toronto. This filter expression uses an XPath (as given in W3C XML Path Language) expression to reference the complex attributes of the Person type. """ xml_text = """ <fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/fes/2.0 http://schemas.opengis.net/filter/2.0/filterAll.xsd"> <fes:And> <fes:PropertyIsGreaterThan> <fes:ValueReference>Person/age</fes:ValueReference> <fes:Literal>50</fes:Literal> </fes:PropertyIsGreaterThan> <fes:PropertyIsEqualTo> <fes:ValueReference>Person/mailAddress/Address/city</fes:ValueReference> <fes:Literal>Toronto</fes:Literal> </fes:PropertyIsEqualTo> </fes:And> </fes:Filter> """.strip() result = Filter.from_string(xml_text) expected = Filter(predicate=BinaryLogicOperator( operands=[ BinaryComparisonOperator( operatorType=BinaryComparisonName.PropertyIsGreaterThan, expression=( ValueReference(xpath="Person/age"), Literal(raw_value="50"), ), matchCase=True, matchAction=MatchAction.Any, ), BinaryComparisonOperator( operatorType=BinaryComparisonName.PropertyIsEqualTo, expression=( ValueReference(xpath="Person/mailAddress/Address/city"), Literal(raw_value="Toronto"), ), matchCase=True, matchAction=MatchAction.Any, ), ], operatorType=BinaryLogicType.And, )) assert result == expected, f"result={result!r}" # Test SQL generating query = result.compile_query() assert query == CompiledQuery(lookups=[ Q(Person__age__gt=50) & Q(Person__mailAddress__Address__city__exact="Toronto") ]), repr(query)
def test_fes20_c5_example2(): """A simple non-spatial filter comparing a property value to a literal. In this case, the DEPTH is checked to find instances where it is less than 30 - possibly to identify areas that need dredging. """ xml_text = """ <fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/fes/2.0 http://schemas.opengis.net/filter/2.0/filterAll.xsd"> <fes:PropertyIsLessThan> <fes:ValueReference>DEPTH</fes:ValueReference> <fes:Literal>30</fes:Literal> </fes:PropertyIsLessThan> </fes:Filter> """.strip() expected = Filter( BinaryComparisonOperator( BinaryComparisonName.PropertyIsLessThan, expression=(ValueReference("DEPTH"), Literal("30")), )) result = Filter.from_string(xml_text) assert result == expected, f"result={result!r}" # Test SQL generating query = result.compile_query() assert query == CompiledQuery(lookups=[Q(DEPTH__lt=30)]), repr(query)
def test_fes20_c5_example1(): """A simple non-spatial filter checking to see if SomeProperty is equal to 100.""" xml_text = """ <fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/fes/2.0 http://schemas.opengis.net/filter/2.0/filterAll.xsd"> <fes:PropertyIsEqualTo> <fes:ValueReference>SomeProperty</fes:ValueReference> <fes:Literal>100</fes:Literal> </fes:PropertyIsEqualTo> </fes:Filter> """.strip() expected = Filter( BinaryComparisonOperator( BinaryComparisonName.PropertyIsEqualTo, expression=( ValueReference("SomeProperty"), Literal("100"), ), )) result = Filter.from_string(xml_text) assert result == expected, f"result={result!r}" # Test SQL generating query = result.compile_query() assert query == CompiledQuery(lookups=[Q( SomeProperty__exact=100)]), repr(query)
def test_fes10_no_namespace(leading_whitespace): """Test that omitting a namespace still parses the object.""" xml_text = """ <Filter> <PropertyIsEqualTo> <ValueReference>SomeProperty</ValueReference> <Literal>100</Literal> </PropertyIsEqualTo> </Filter> """ if leading_whitespace: xml_text = xml_text.strip() expected = Filter(predicate=BinaryComparisonOperator( operatorType=BinaryComparisonName.PropertyIsEqualTo, expression=( ValueReference(xpath="SomeProperty"), Literal(raw_value="100"), ), matchCase=True, matchAction=MatchAction.Any, )) result = Filter.from_string(xml_text) assert result == expected, f"result={result!r}"
def test_fes20_c5_example7(): """This example assumes that the server advertises support for a function called "Add" in its filter capabilities document. The example encodes a filter that includes an arithmetic expression. This filter is equivalent to the expression PROPA = PROPB + 100. """ @function_registry.register( name="Add", arguments=dict(value1=XsdTypes.double, value2=XsdTypes.double), returns=XsdTypes.double, ) def fes_add(value1: F, value2: str): # value1 is already an F value (thanks to ValueReference) return value1 + value2 xml_text = """ <fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/fes/2.0 http://schemas.opengis.net/filter/2.0/filterAll.xsd"> <fes:PropertyIsEqualTo> <fes:ValueReference>PROPA</fes:ValueReference> <fes:Function name="Add"> <fes:ValueReference>PROPB</fes:ValueReference> <fes:Literal>100</fes:Literal> </fes:Function> </fes:PropertyIsEqualTo> </fes:Filter> """.strip() expected = Filter(predicate=BinaryComparisonOperator( operatorType=BinaryComparisonName.PropertyIsEqualTo, expression=( ValueReference(xpath="PROPA"), Function( name="Add", arguments=[ ValueReference(xpath="PROPB"), Literal(raw_value="100") ], ), ), matchCase=True, matchAction=MatchAction.Any, )) result = Filter.from_string(xml_text) assert result == expected, f"result={result!r}" # Test SQL generating # Testing against repr() because CombinedExpression / Value doesn't do __eq__ testing. query = result.compile_query() assert repr(query) == repr( CompiledQuery(lookups=[Q(PROPA__exact=F("PROPB") + 100)])), repr(query)
def test_fes10_add_sub(): """A simple non-spatial filter checking to see if SomeProperty is equal to 100.""" xml_text = """ <fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/fes/2.0 http://schemas.opengis.net/filter/2.0/filterAll.xsd"> <fes:PropertyIsEqualTo> <fes:ValueReference>SomeProperty</fes:ValueReference> <fes:Add> <fes:Sub> <fes:Literal>100</fes:Literal> <fes:Literal>50</fes:Literal> </fes:Sub> <fes:Literal>200</fes:Literal> </fes:Add> </fes:PropertyIsEqualTo> </fes:Filter> """.strip() expected = Filter(predicate=BinaryComparisonOperator( operatorType=BinaryComparisonName.PropertyIsEqualTo, expression=( ValueReference(xpath="SomeProperty"), BinaryOperator( _operatorType=BinaryOperatorType.Add, expression=( BinaryOperator( _operatorType=BinaryOperatorType.Sub, expression=( Literal(raw_value="100"), Literal(raw_value="50"), ), ), Literal(raw_value="200"), ), ), ), matchCase=True, matchAction=MatchAction.Any, )) result = Filter.from_string(xml_text) assert result == expected, f"result={result!r}" # Test SQL generating query = result.compile_query() integer_field = models.IntegerField() assert query == CompiledQuery(lookups=[ Q(SomeProperty__exact=(Value(100, output_field=integer_field) - Value(50, output_field=integer_field) + Value(200, output_field=integer_field))) ]), repr(query)
def test_fes20_c5_example6(): """The following filter includes the encoding of a function. This filter identifies all features where the sine() of the property named DISPERSION_ANGLE is 1. """ @function_registry.register( name="SIN", arguments=dict(value1="xsd:double"), returns="xsd:double", ) def fes_sin(value1): return Sin(value1) xml_text = """ <fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/fes/2.0 http://schemas.opengis.net/filter/2.0/filterAll.xsd"> <fes:PropertyIsEqualTo> <fes:Function name="SIN"> <fes:ValueReference>DISPERSION_ANGLE</fes:ValueReference> </fes:Function> <fes:Literal>1</fes:Literal> </fes:PropertyIsEqualTo> </fes:Filter> """.strip() expected = Filter(predicate=BinaryComparisonOperator( operatorType=BinaryComparisonName.PropertyIsEqualTo, expression=( Function( name="SIN", arguments=[ValueReference(xpath="DISPERSION_ANGLE")], ), Literal(raw_value="1"), ), matchCase=True, matchAction=MatchAction.Any, )) result = Filter.from_string(xml_text) assert result == expected, f"result={result!r}" # Test SQL generating query = result.compile_query() assert query == CompiledQuery( annotations={"a1": Sin(F("DISPERSION_ANGLE"))}, lookups=[Q(a1__exact=1)]), repr(query)
def test_fes20_c5_example12(): """In this example, a more complex scalar predicate is encoded using the logical operators AND and OR. The example is equivalent to the expression: ((FIELD1=10 OR FIELD1=20) AND (STATUS="VALID")) """ xml_text = """ <fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/fes/2.0 http://schemas.opengis.net/filter/2.0/filterAll.xsd"> <fes:And> <fes:Or> <fes:PropertyIsEqualTo> <fes:ValueReference>FIELD1</fes:ValueReference> <fes:Literal>10</fes:Literal> </fes:PropertyIsEqualTo> <fes:PropertyIsEqualTo> <fes:ValueReference>FIELD1</fes:ValueReference> <fes:Literal>20</fes:Literal> </fes:PropertyIsEqualTo> </fes:Or> <fes:PropertyIsEqualTo> <fes:ValueReference>STATUS</fes:ValueReference> <fes:Literal>VALID</fes:Literal> </fes:PropertyIsEqualTo> </fes:And> </fes:Filter> """.strip() expected = Filter(predicate=BinaryLogicOperator( operands=[ BinaryLogicOperator( operands=[ BinaryComparisonOperator( operatorType=BinaryComparisonName.PropertyIsEqualTo, expression=( ValueReference(xpath="FIELD1"), Literal(raw_value="10"), ), matchCase=True, matchAction=MatchAction.Any, ), BinaryComparisonOperator( operatorType=BinaryComparisonName.PropertyIsEqualTo, expression=( ValueReference(xpath="FIELD1"), Literal(raw_value="20"), ), matchCase=True, matchAction=MatchAction.Any, ), ], operatorType=BinaryLogicType.Or, ), BinaryComparisonOperator( operatorType=BinaryComparisonName.PropertyIsEqualTo, expression=( ValueReference(xpath="STATUS"), Literal(raw_value="VALID"), ), matchCase=True, matchAction=MatchAction.Any, ), ], operatorType=BinaryLogicType.And, )) result = Filter.from_string(xml_text) assert result == expected, f"result={result!r}" # Test SQL generating query = result.compile_query() assert query == CompiledQuery( lookups=[(Q(FIELD1__exact=10) | Q(FIELD1__exact=20)) & Q(STATUS__exact="VALID")]), repr(query)
def test_fes20_c5_example4(): """In this example, Examples 2 and 3 are combined with the logical operator AND. The predicate is thus interpreted as seeking all features that interact with the specified bounding box and have a DEPTH value of less than 30 m.""" xml_text = """ <?xml version="1.0"?> <fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/fes/2.0 http://schemas.opengis.net/filter/2.0/filterAll.xsd http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/geometry.xsd"> <fes:And> <fes:PropertyIsLessThan> <fes:ValueReference>DEPTH</fes:ValueReference> <fes:Literal>30</fes:Literal> </fes:PropertyIsLessThan> <fes:Not> <fes:Disjoint> <fes:ValueReference>Geometry</fes:ValueReference> <gml:Envelope srsName="http://www.opengis.net/def/crs/epsg/0/4326"> <gml:lowerCorner>13.0983 31.5899</gml:lowerCorner> <gml:upperCorner>35.5472 42.8143</gml:upperCorner> </gml:Envelope> </fes:Disjoint> </fes:Not> </fes:And> </fes:Filter> """.strip() expected = Filter(predicate=BinaryLogicOperator( operands=[ BinaryComparisonOperator( operatorType=BinaryComparisonName.PropertyIsLessThan, expression=( ValueReference(xpath="DEPTH"), Literal(raw_value="30"), ), matchCase=True, matchAction=MatchAction.Any, ), UnaryLogicOperator( operands=BinarySpatialOperator( operatorType=SpatialOperatorName.Disjoint, operand1=ValueReference(xpath="Geometry"), operand2=GEOSGMLGeometry( srs=WGS84, geos_data=GEOSGeometry( "POLYGON ((13.0983 31.5899, 35.5472 31.5899" ", 35.5472 42.8143, 13.0983 42.8143, 13.0983 31.5899))", srid=4326, ), ), ), operatorType=UnaryLogicType.Not, ), ], operatorType=BinaryLogicType.And, )) result = Filter.from_string(xml_text) assert result == expected, f"result={result!r}" # Test SQL generating query = result.compile_query() assert query == CompiledQuery(lookups=[ Q(DEPTH__lt=30) & ~Q(Geometry__disjoint=GEOSGeometry( "POLYGON ((13.0983 31.5899, 35.5472 31.5899" ", 35.5472 42.8143, 13.0983 42.8143, 13.0983 31.5899))", srid=4326, )) ]), repr(query)