Open Geospatial Consortium |
Submission Date: 2024-03-26 |
Approval Date: 2024-05-23 |
Publication Date: 2024-07-26 |
External identifier of this OGC® document: http://www.opengis.net/doc/IS/cql2/1.0 |
Internal reference number of this OGC® document: 21-065r2 |
Version: 1.0.0 |
Category: OGC Standard |
Editors: Panagiotis (Peter) A. Vretanos, Clemens Portele |
Common Query Language (CQL2) |
Copyright notice |
Copyright © 2024 Open Geospatial Consortium |
To obtain additional rights of use, visit http://www.ogc.org/legal/ |
Warning |
This document is an OGC Member approved international standard. This document is available on a royalty free, non-discriminatory basis. Recipients of this document are invited to submit, with their comments, notification of any relevant patent rights of which they are aware and to provide supporting documentation.
Document type: OGC Standard |
Document subtype: Interface |
Document stage: Approved |
Document language: English |
License Agreement
Permission is hereby granted by the Open Geospatial Consortium, ("Licensor"), free of charge and subject to the terms set forth below, to any person obtaining a copy of this Intellectual Property and any associated documentation, to deal in the Intellectual Property without restriction (except as set forth below), including without limitation the rights to implement, use, copy, modify, merge, publish, distribute, and/or sublicense copies of the Intellectual Property, and to permit persons to whom the Intellectual Property is furnished to do so, provided that all copyright notices on the intellectual property are retained intact and that each person to whom the Intellectual Property is furnished agrees to the terms of this Agreement.
If you modify the Intellectual Property, all copies of the modified Intellectual Property must include, in addition to the above copyright notice, a notice that the Intellectual Property includes modifications that have not been approved or adopted by LICENSOR.
THIS LICENSE IS A COPYRIGHT LICENSE ONLY, AND DOES NOT CONVEY ANY RIGHTS UNDER ANY PATENTS THAT MAY BE IN FORCE ANYWHERE IN THE WORLD.
THE INTELLECTUAL PROPERTY IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE DO NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE INTELLECTUAL PROPERTY WILL MEET YOUR REQUIREMENTS OR THAT THE OPERATION OF THE INTELLECTUAL PROPERTY WILL BE UNINTERRUPTED OR ERROR FREE. ANY USE OF THE INTELLECTUAL PROPERTY SHALL BE MADE ENTIRELY AT THE USER’S OWN RISK. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY CONTRIBUTOR OF INTELLECTUAL PROPERTY RIGHTS TO THE INTELLECTUAL PROPERTY BE LIABLE FOR ANY CLAIM, OR ANY DIRECT, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM ANY ALLEGED INFRINGEMENT OR ANY LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR UNDER ANY OTHER LEGAL THEORY, ARISING OUT OF OR IN CONNECTION WITH THE IMPLEMENTATION, USE, COMMERCIALIZATION OR PERFORMANCE OF THIS INTELLECTUAL PROPERTY.
This license is effective until terminated. You may terminate it at any time by destroying the Intellectual Property together with all copies in any form. The license will also terminate if you fail to comply with any term or condition of this Agreement. Except as provided in the following sentence, no such termination of this license shall require the termination of any third party end-user sublicense to the Intellectual Property which is in force as of the date of notice of such termination. In addition, should the Intellectual Property, or the operation of the Intellectual Property, infringe, or in LICENSOR’s sole opinion be likely to infringe, any patent, copyright, trademark or other right of a third party, you agree that LICENSOR, in its sole discretion, may terminate this license without any compensation or liability to you, your licensees or any other party. You agree upon termination of any kind to destroy or cause to be destroyed the Intellectual Property together with all copies in any form, whether held by you or by any third party.
Except as contained in this notice, the name of LICENSOR or of any other holder of a copyright in all or part of the Intellectual Property shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Intellectual Property without prior written authorization of LICENSOR or such copyright holder. LICENSOR is and shall at all times be the sole entity that may authorize you or any third party to use certification marks, trademarks or other special designations to indicate compliance with any LICENSOR standards or specifications. This Agreement is governed by the laws of the Commonwealth of Massachusetts. The application to this Agreement of the United Nations Convention on Contracts for the International Sale of Goods is hereby expressly excluded. In the event any provision of this Agreement shall be deemed unenforceable, void or invalid, such provision shall be modified so as to make it valid and enforceable, and as so modified the entire Agreement shall remain in full force and effect. No decision, action or inaction by LICENSOR shall be construed to be a waiver of any rights or remedies available to it.
- 1. Scope
- 2. Conformance
- 3. References
- 4. Terms, Definitions, Symbols and Abbreviated Terms
- 5. Conventions and background
- 6. Requirements Class "Basic CQL2"
- 7. Common Query Language enhancements
- 7.1. Overview
- 7.2. Requirements Class "Advanced Comparison Operators"
- 7.3. Requirements Class "Case-insensitive Comparison"
- 7.4. Requirements Class "Accent-insensitive Comparison"
- 7.5. Requirements Class "Basic Spatial Functions"
- 7.6. Requirements Class "Basic Spatial Functions with additional Spatial Literals"
- 7.7. Requirements Class "Spatial Functions"
- 7.8. Requirements Class "Temporal Functions"
- 7.9. Requirements class "Array Functions"
- 7.10. Requirements Class "Property-Property Comparisons"
- 7.11. Requirements Class "Functions"
- 7.12. Requirements Class "Arithmetic Expressions"
- 8. Requirements classes for encodings
- 9. Media Types
- Annex A: Abstract Test Suite (Normative)
- A.1. Conformance Class "CQL2 Text"
- A.2. Conformance Class "CQL2 JSON"
- A.3. Conformance Class "Basic-CQL2"
- A.4. Conformance Class "Advanced Comparison Operators"
- A.5. Conformance Class "Case-insensitive Comparison"
- A.6. Conformance Class "Accent-insensitive Comparison"
- A.7. Conformance Class "Basic Spatial Functions"
- A.8. Conformance Class "Basic Spatial Functions with additional Spatial Literals"
- A.9. Conformance Class "Spatial Functions"
- A.10. Conformance Class "Temporal Functions"
- A.11. Conformance Class "Array Functions"
- A.12. Conformance Class "Property-Property Comparisons"
- A.13. Conformance Class "Functions"
- A.14. Conformance Class "Arithmetic Expressions"
- Annex B: CQL2 BNF (Normative)
- Annex C: JSON schemas for CQL2 (Normative)
- Annex D: Revision History
- Annex E: Bibliography
i. Abstract
A fundamental operation performed on a collection of features is that of filtering in order to obtain a subset of the data which contains feature instances that satisfy some filtering criteria. This document specifies
-
A filter grammar called Common Query Language (CQL2);
-
Two encodings for CQL2 - a text and a JSON encoding.
The Common Query Language (CQL2) defined in this document is a generic filter grammar that can be used to specify how resource instances in a source collection of any item type, including features, can be filtered to identify a results set. Typically, CQL2 is used in query operations to identify the subset of resources, such as features, that should be included in a response document. However, CQL2 can also be used in other operations, such as updates, to identify the subset of resources that should be affected by an operation.
Each resource instance in the source collection is evaluated against a filtering
expression. The filter expression always evaluates to true
, false
or null
. If the
expression evaluates to true
, the resource instance satisfies the expression and
is marked as being in the result set. If the overall filter expression evaluates
to false
or null
, the data instance is not in the result set. Thus, the net effect of
evaluating a filter expression is a set of resources that satisfy the predicates
in the expression.
The Common Query Language and its text encoding are not new, but this is the first time that the language is formally specified. The Common Query Language with the acronym CQL was originally created as a text encoding for use with implementations of the OGC Catalogue Service Implementation Specification. The language is based on the capabilities in the OGC Filter Encoding Standard, which was originally part of the Web Feature Service (WFS) Standard.
The Common Query Language as specified in this document is a revision of this earlier version. While the language design including the classification of operators are consistent with the earlier specification, there have been a number of changes and existing implementations of CQL will need to be updated to process filter expressions specified by this document. This document therefore uses the acronym CQL2 to refer to the current version of the Common Query Language.
Note
|
The use of CQL2 also distinguishes the Common Query Language from other existing uses of CQL for query languages, for example, for the Cassandra Query Language. |
ii. Keywords
The following are keywords to be used by search engines and document catalogues.
OGC, common query language, filter, expression, query, SQL, CQL2, where clause, selection clause
iii. Preface
Attention is drawn to the possibility that some of the elements of this document may be the subject of patent rights. The Open Geospatial Consortium Inc. shall not be held responsible for identifying any or all such patent rights.
Recipients of this document are requested to submit, with their comments, notification of any relevant patent claims or other intellectual property rights of which they may be aware that might be infringed by any implementation of the standard set forth in this document, and to provide supporting documentation.
iv. Submitting organizations
The following organizations submitted this document to the Open Geospatial Consortium (OGC):
-
CubeWerx Inc.
-
Ecere Corporation
-
GeoSolutions di Giannecchini Simone & C. s.a.s.
-
interactive instruments GmbH
-
US Army Geospatial Center (AGC)
v. Submitters
All questions regarding this submission should be directed to the editors or the submitters:
Name |
Affiliation |
Panagiotis (Peter) A. Vretanos (editor) |
CubeWerx Inc. |
Clemens Portele (editor) |
interactive instruments GmbH |
Andrea Aime |
GeoSolutions di Giannecchini Simone & C. s.a.s. |
Jeff Harrison |
US Army Geospatial Center (AGC) |
Jérôme Jacovella-St-Louis |
Ecere Corporation |
1. Scope
This document specifies the Common Query Language (CQL2) to express filter expressions on spatial and temporal data.
This document defines
-
A text encoding for a CQL2 filter;
-
A JSON encoding for a CQL2 filter.
Note
|
The CQL2 grammar contains all the necessary language elements of a general purpose expression language, including support for spatio-temporal values. The focus of this version of the language are boolean-valued filter expressions. It is planned to potentially remove this restriction, while maintaining backward compatibility, allowing expressions that result in values of other data types, including geometries. Such expressions could be used, for example, in a styling language to specify parameter values, or to define derived properties. In this case, a particular use of CQL2 could specify the boolean-valued restriction separately, for example when used as a filter predicate expression, or as a styling rule selector. The usability of such an expression language, especially in the context of geometry types, would also greatly benefit from standardizing additional functions and/or operators e.g., to compute the geometry resulting from buffering or intersecting operations. Example files and associated schemas have been published on the OGC Schemas repository. |
2. Conformance
This standard defines the following requirements classes, grouped by their standardization target:
-
Servers that evaluate filter expressions
Note
|
"Server" is used in this Standard to identify any executable software that is able to evaluate filter expressions on data. |
The Basic CQL2 requirements class defines the minimal subset of the Common Query Language (CQL2) that all implementations must support. Basic CQL2 is intended to be a useful, but limited set of predicates that support fine-grained read-access to collections of resources.
The specific set of operators defined in this requirements class is:
-
Logical operators:
-
and
-
or
-
not
-
-
Comparison operators:
-
equal to
-
not equal to
-
less than
-
less than or equal to
-
greater than
-
greater than or equal to
-
is null
-
Basic CQL2 only requires support for property-literal comparisons. That means that servers only have to support property references as expressions on the left-hand side of an operator, and only literal values as expressions on the right-hand side.
An encoding of CQL2 may be used as the value of the filter parameters defined in the "Filter" requirements class specified in OGC API - Features - Part 3: Filtering.
The Advanced Comparison Operators requirements class specifies additional comparison operators:
-
like
-
between
-
in
The Case-insensitive Comparison requirements class adds a standardized string function to support case-insensitive string comparisons:
-
casei
The Accent-insensitive Comparison requirements class adds a standardized string function to support accent-insensitive string comparisons:
-
accenti
The Basic Spatial Functions requirements class specifies minimal requirements for servers that support standardized spatial comparison functions. Only the following spatial comparison function must be supported, and only for points and bounding boxes:
-
s_intersects
The Basic Spatial Functions with additional Spatial Literals requirements class is similar to the Basic Spatial Functions requirements class except it removes the restrictions on the spatial literals that may be used in the expression.
The Spatial Functions requirements class specifies requirements for servers that support a richer set of spatial comparison functions. The list of additional spatial comparison functions that must be supported is:
-
s_contains
-
s_crosses
-
s_disjoint
-
s_equals
-
s_overlaps
-
s_touches
-
s_within
All spatial data types from the Simple Feature Access Standard must be supported.
The Temporal Functions requirements class specifies requirements for servers that support standardized temporal comparison function. The list of temporal comparison function that must be supported is:
-
t_after
-
t_before
-
t_contains
-
t_disjoint
-
t_during
-
t_equals
-
t_finishedby
-
t_finishes
-
t_intersects
-
t_meets
-
t_metby
-
t_overlappedby
-
t_overlaps
-
t_startedby
-
t_starts
The Array Functions requirements class specifies requirements for standardized array comparison functions for sets of values. The array comparison functions that must be supported are:
-
a_containedby
-
a_contains
-
a_equals
-
a_overlaps
The Property-Property Comparisons requirements class drops the permission to restrict expressions on the left-hand side to properties and to restrict expressions on the right-hand side to literal values. This supports property-property, but also literal-literal or literal-property comparisons.
The Functions requirements class specifies requirements for supporting function calls (e.g. min, max, etc.) in a CQL2 expression. Function calls are the primary means of extending the language. Implementations should provide a capability to discover the available functions.
The Arithmetic Expressions requirements class specifies
requirements for supporting the standard set of arithmetic operators
(+
, -
, *
, /
, %
, div
, and ^
) in a CQL2 expression.
The CQL2 Text encoding requirements class defines
a text encoding for CQL2. Such an encoding is suitable for use with HTTP query
parameters such as the filter
parameter defined by the "Filter" requirements class specified
in OGC API - Features - Part 3: Filtering.
The CQL2 JSON encoding requirements class defines a JSON encoding for CQL2. Such as encoding is suitable for use as the body of an HTTP POST request.
Conformance with this standard shall be checked using all the relevant tests specified in Annex A of this document. The framework, concepts, and methodology for testing, and the criteria to be achieved to claim conformance are specified in the OGC Compliance Testing Policies and Procedures and the OGC Compliance Testing web site.
3. References
The following normative documents contain provisions that, through reference in this text, constitute provisions of this document. For dated references, subsequent amendments to, or revisions of, any of these publications do not apply. For undated references, the latest edition of the normative document referred to applies.
-
Open Geospatial Consortium (OGC). OGC 06-103r4: OpenGIS® Implementation Standard for Geographic information - Simple feature access - Part 1: Common architecture [online]. Edited by J. Herring. 2011 [viewed 2020-11-22]. Available at http://portal.opengeospatial.org/files/?artifact_id=25355
-
Internet Engineering Task Force (IETF). RFC 7946: The GeoJSON Format [online]. Edited by H. Butler, M. Daly, A. Doyle, S. Gillies, S. Hagen, T. Schaub. 2016 [viewed 2020-03-16]. Available at https://www.rfc-editor.org/rfc/rfc7946.html
-
Open Geospatial Consortium (OGC) / World Wide Web Consortium (W3C). Time Ontology in OWL [online]. Edited by S. Cox, C. Little. 2020 [viewed 2020-11-22]. Available at https://www.w3.org/TR/owl-time
-
Internet Engineering Task Force (IETF). RFC 3339: Date and Time on the Internet: Timestamps [online]. Edited by G. Klyne, C. Newman. 2002 [viewed 2020-03-16]. Available at https://www.rfc-editor.org/rfc/rfc3339.html
-
Internet Engineering Task Force (IETF). draft-handrews-json-schema-02: JSON Schema: A Media Type for Describing JSON Documents [online]. Edited by A. Wright, H. Andrews, B. Hutton, G. Dennis. 2019 [viewed 2020-11-22]. Available at https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-02
-
Unicode Consortium: Unicode® 15.0.0 [online]. Available at https://unicode.org/versions/Unicode15.0.0/
4. Terms, Definitions, Symbols and Abbreviated Terms
4.1. Terms and Definitions
This document used the terms defined in OGC Policy Directive 49, which is based on the ISO/IEC Directives, Part 2, Rules for the structure and drafting of International Standards. In particular, the word “shall” (not “must”) is the verb form used to indicate a requirement to be strictly followed to conform to this standard and OGC documents do not use the equivalent phrases in the ISO/IEC Directives, Part 2.
This document also uses terms defined in the OGC Standard for Modular specifications (OGC 08-131r3), also known as the 'ModSpec'. The definitions of terms such as standard, specification, requirement, and conformance test are provided in the ModSpec.
For the purposes of this document, the following additional terms and definitions apply.
4.1.1. boundary
set that represents the limit of an entity (ISO 19107:2019, definition 3.6)
Note
|
Boundary is most commonly used in the context of geometry, where the set is a collection of points or a collection of objects that represent those points. In other arenas, the term is used metaphorically to describe the transition between an entity and the rest of its domain of discourse. |
4.1.2. collection
a body of resources that belong or are used together; an aggregate, set, or group of related resources (OGC 20-024, OGC API - Common - Part 2: Collections).
4.1.3. custom function
function that is not specified in the CQL2 standard
Note
|
Custom functions require support for the Functions requirements class. |
4.1.4. exterior
difference between the universe and the closure (ISO 19107:2019,definition 3.37)
Note
|
The concept of exterior is applicable to both topological and geometric complexes. |
4.1.6. function
rule that associates each element from a domain (source, or domain of the function) to a unique element in another domain (target, co-domain, or range) (ISO 19107:2003, definition 4.41)
4.1.7. interior
set of all direct positions that are on a geometric object but which are not on its boundary
Note
|
The interior of a topological object is the continuous image of the interior of any of its geometric realizations. This is not included as a definition because it follows from a theorem of topology. Another way of saying this is that any point on a geometric object is in its interior if it can be placed inside a homeomorphic image of an open set in the Euclidean space of the object’s topological dimension. |
4.1.9. predicate
set of computational operations applied to a data instance which evaluate to true or false (OGC Filter Encoding 2.0 Encoding Standard - With Corrigendum)
4.1.10. queryable
a token that represents a property of a resource that can be used in a filter expression
4.1.11. resource
entity that might be identified (Dublin Core Metadata Initiative - DCMI Metadata Terms)
4.1.12. unicode case folding; case folding
process of making two texts which differ only in case identical for comparison purposes (W3C Character Model for the World Wide Web: String Matching)
Note
|
Case folding is meant for the purpose of case-insensitive string matching. |
4.1.13. unicode normalization; normalization
process of removing alternate representations of equivalent sequences from textual data, to convert the data into a form that can be binary-compared for equivalence (Glossary of Unicode Terms)
4.2. Symbols
-
∩ intersection, operation on two or more sets
-
∧ and, logical intersection
-
∅ empty set, the set having no members
-
≠ not equal
-
⬄ if and only if, logical equivalence between statements
-
⊆ is a subset of
-
dim(x) returns the maximum dimension (-1, 0, 1, or 2) of the geometric object x
-
I(x) represents the interior of the geometric object x
-
B(x) represents the boundary of the geometric object x
-
E(x) represents the exterior of the geometric object x
4.3. Abbreviated terms
- ABNF
-
Augmented Backus-Naur Form
- API
-
Application Programming Interface
- BNF
-
Backus-Naur Form
- CQL2
-
Common Query Language
- CRS
-
Coordinate Reference System
- DE-9IM
-
Dimensionally Extended Nine-Intersection Model
- HTTP
-
Hypertext Transfer Protocol
- HTTPS
-
Hypertext Transfer Protocol Secure
- IANA
-
Internet Assigned Numbers Authority
- JSON
-
JavaScript Object Notation
- OGC
-
Open Geospatial Consortium
- URI
-
Uniform Resource Identifier
- WKT
-
Well-Known Text
- YAML
-
YAML Ain’t Markup Language
5. Conventions and background
5.1. Identifiers
The normative provisions in this standard are denoted by the URI http://www.opengis.net/spec/cql2/1.0
.
All requirements and conformance tests that appear in this document are denoted by partial URIs which are relative to this base.
5.2. Use of BNF
BNF as specified in Augmented BNF for Syntax Specifications is used to formally specify the grammar of the Common Query Language (CQL2) and its text encoding (CQL2-Text).
5.3. Use of JSON Schema
JSON Schema draft 2019-09 (JSON Schema, JSON Schema Validation) is used to formally specify the schema of the JSON encoding of CQL2 (CQL2-JSON).
5.4. Dependencies to other requirements classes
The requirements classes in this document distinguish two types of dependencies to other specifications or requirements classes:
First, there are the obligatory dependencies. Every server implementing the requirements class has to conform to the referenced specification or requirements class.
In addition, requirements classes can also have conditional dependencies. Servers implementing the requirements class do not have to conform to the referenced specification or requirements class, but if they do, they have to conform to the requirements that identify the conditional dependency as a pre-condition for the normative statement.
6. Requirements Class "Basic CQL2"
6.1. Overview
Requirements Class |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
OGC Simple feature access - Part 1: Common architecture, Architecture |
Dependency |
|
Dependency |
|
Dependency |
|
Dependency |
This clause defines the core of a query language called Common Query Language
(CQL2) that may be used to construct filter expressions. This core is called Basic CQL2.
Subsequent clauses define additional filtering capabilities as well as several encodings of CQL2.
6.2. CQL2 filter expression
A CQL2 filter expression is an expression that defines a logically connected set of predicates that are evaluated for each item of a collection. Each predicate is an operator with operands where the number of operands depends on the operator. An operand is either a literal, a property, a standardized or custom function or an arithmetic expression.
A predicate is an expression that evaluates to the Boolean values of TRUE
or FALSE
or that evaluates to the value NULL
when dealing with unknown values.
Logically connected predicates are evaluated according to the following truth table:
Predicate1 | Predicate2 | Predicate1 AND Predicate2 | Predicate1 OR Predicate2 |
---|---|---|---|
TRUE |
TRUE |
TRUE |
TRUE |
TRUE |
FALSE |
FALSE |
TRUE |
FALSE |
TRUE |
FALSE |
TRUE |
FALSE |
FALSE |
FALSE |
FALSE |
TRUE |
NULL |
NULL |
TRUE |
FALSE |
NULL |
FALSE |
NULL |
NULL |
TRUE |
NULL |
TRUE |
NULL |
FALSE |
FALSE |
NULL |
NULL |
NULL |
NULL |
NULL |
A collection item that satisfies ALL the requirements of a CQL2 filter expression according to the above true table evaluates to a Boolean value of TRUE
; otherwise the CQL2 filter expression evaluates to FALSE
or NULL
.
If a CQL2 filter expression evaluates to TRUE
for an item, the item is included in the result set and is thus available for further processing such as presentation in a response document.
If a CQL2 filter expression overall evaluates to FALSE
or NULL
for an item, the item is not included in the result set and is thus not available for further processing.
Requirement 1 |
/req/basic-cql2/cql2-filter |
A |
A server SHALL support a CQL2 filter expression composed of a logically connected series of one or more predicates as described by the BNF rule |
Literal values do not have to be supported on the left-hand side of predicates and property references do not have to be supported on the right-hand side of predicates.
Permission 1 |
/per/basic-cql2/cql2-filter |
A |
In the rule |
B |
In the rule |
A Basic CQL2 filter expression can be constructed by logically connecting comparison predicates.
Support for the parts of CQL2 that are not part of Basic CQL2 is added in additional requirements classes in Common Query Language enhancements:
-
The rules
isLikePredicate
,isBetweenPredicate
andisInListPredicate
are added by requirements class Advanced Comparison Operators; -
Support for the
CASEI
function is added by requirements class Case-insensitive Comparison; -
Support for the
ACCENTI
function is added by requirements class Accent-insensitive Comparison; -
The rule
spatialPredicate
is added by requirements classes Basic Spatial Functions and Spatial Functions; -
The rule
temporalPredicate
is added by requirements class Temporal Functions. -
The rule
arrayPredicate
is added by requirements class Array Functions; -
The permission to not support the literal rules on the left-hand side of predicates and the rule
propertyName
on the right-hand side is removed by requirements class Property-Property Comparisons; -
The rule
function
is added by requirements class Functions; -
The rule
arithmeticExpression
is added by requirements class Arithmetic Expressions.
Examples of Basic CQL2 filter expressions are included in the subsequent sub-clauses.
6.3. Data types and literal values
This section documents the data types supported by Basic CQL2 and has examples of literal values for each data type.
A literal value is any part of an CQL2 filter expression that is used exactly as it is specified in the expression.
Other requirements classes add more data types. These are defined in the chapter specifying the requirements class.
6.3.1. Scalar data types
The scalar data types are:
-
"string": character strings (rule
characterLiteral
); -
"number": numbers including integers and floating point values (rule
numericLiteral
); -
"boolean": booleans (rule
booleanLiteral
); -
"timestamp": an instant with a granularity of a second or smaller (rule
timestampInstant
) -
"date": an instant with a granularity of a day (rule
dateInstant
)
For character string, numeric and boolean literals, the standard representations are used.
Conceptually, an instant is a "temporal entity with zero extent or duration" [Time Ontology in OWL]. In practice, the temporal position of an instant is described using data types where each value has some duration or granularity that is sufficient for the intended use of the data.
CQL2 supports two commonly used granularities: a second or smaller (data type "timestamp") and days (data type "date"). Literal timestamps are always in the time zone UTC ("Z"), dates are local dates without an associated time zone.
If time zone information is important for the intended use, then the "date" data type should not be used and the temporal information should be provided as an interval with start and end timestamps.
Note
|
While instants (timestamps and dates) are scalar data types that can be used with the basic comparison operators, intervals are more complex data types. Support for intervals is added in the requirements class Temporal Functions where intervals can be provided as arguments in temporal comparison functions. |
For timestamp and date values representations based on RFC 3339 are used:
-
Text: a
DATE
orTIMESTAMP
constructor with a RFC 3339date-time
orfull-date
string -
JSON: an object with a
date
ortimestamp
member with a RFC 3339date-time
orfull-date
string
-
character string
'This is a literal string.'
-
character string with an escaped embedded quote
'Via dell''Avvento'
-
number
-100 3.14159
-
boolean
true false
-
timestamp (Text)
TIMESTAMP('1969-07-20T20:17:40Z')
-
timestamp (JSON)
{ "timestamp": "1969-07-20T20:17:40Z" }
-
date (Text)
DATE('1969-07-20')
-
date (JSON)
{ "date": "1969-07-20" }
6.3.2. Escaping in string literals
In general, escaping special character sequences in a string literal will be handled according to the rules of the specific encoding being used. For example, for the JSON encoding of CQL2, an embedded newline in a string literal would be encoded as \n
. If, however, an XML encoding of CQL2 existed the embedded newline character would be encoded as 

. Furthermore, additional processing of a string literal may be necessary before it can be passed down to an underlying platform (e.g. RDBMS) for further handling.
For the text encoding of CQL2 see Requirements Class "CQL2 Text" and requirement /req/cql2-text/escaping for additional requirements concerning escaping in string literals.
6.3.3. Type casts
Permission 2 |
/per/basic-cql2/type-casts |
A |
If an operator or function has operands that have incompatible data types, the server MAY either return an error or it MAY cast the operands to compatible data types. |
This Standard does not prescribe how types are cast. The evaluation of filter expressions that involve type casts will, therefore, be system dependent.
For example, a system that evaluates an expression '5' > 4
can, for example,
-
throw an error (incompatible types in a comparison operator);
-
cast the number to a string (
'5' > '4'
); -
cast the string to a number (
5 > 4
).
6.4. Identifiers
An identifier is a token that represents a resource or a named part of a resource within a CQL2 expression that is not a CQL2 keyword or command. Identifiers are composed of a sequence of UTF-8 characters. Valid starting characters for identifiers can include the colon (i.e. ":"), the underscore (i.e. "_") and letters of the alphabet (e.g. "A-Z, a-z"). Additional continuing characters in an identifier can include the period (i.e ".") and numeric digits (i.e. "0-9"). The identifier
production in the CQL2 BNF enumerates the specific characters that can be used to start an identifier as well as additional identifier continuing characters.
6.5. Property references
Properties in an object being evaluated in the CQL2 filter expression can be
referenced by their name (rule propertyName
).
Requirement 2 |
/req/basic-cql2/property |
A |
The property name (rule |
B |
The property name reference SHALL evaluate to its corresponding value, or |
For example, a property name used in a scalar expression (rule scalarExpression
)
has to be a queryable of type string
, number
, integer
, boolean
, date
, or timestamp
.
In this example, the property windSpeed
is used in a function that receives an array of numbers and returns a number.
avg(windSpeed)
{ "op": "avg", "args": [ { "property": "windSpeed" } ] }
6.6. Standard comparison predicates
Requirement 3 |
/req/basic-cql2/binary-comparison-predicate |
A |
A binary comparison predicate as specified by rule |
B |
If the requirements of the operator are not satisfied, then the predicate SHALL evaluate to |
C |
If either scalar expression (rule |
D |
Both scalar expressions (rule |
Recommendation 1 |
/rec/core/string-normalization |
A |
For any string comparisons, the server SHOULD implement unicode normalization described in the implementation guidelines of the Unicode 15.0.0 standard (see clause 5.6 Normalization). |
B |
The recommended normalization form is canonical decomposition (NFD). |
Instants (timestamps and dates) are scalar data types. All implementations have to support the comparison of two timestamps or two dates. How this is implemented is a decision of the server and will depend on the internal representation. For example, the server could compare the RFC 3339 string representations of the two timestamps.
city='Toronto'
{
"op": "=",
"args": [
{ "property": "city" },
"Toronto"
]
}
avg(windSpeed) < 4
{
"op": "<",
"args": [
{
"op": "avg",
"args": [ { "property": "windSpeed" } ]
},
4
]
}
balance-150.0 > 0
{
"op": ">",
"args": [
{
"op": "-",
"args": [
{ "property": "balance" },
150.0
]
},
0
]
}
updated >= date('1970-01-01')
{
"op": ">=",
"args": [
{ "property": "updated" },
{ "date": "1970-01-01" }
]
}
Requirement 4 |
/req/basic-cql2/null-predicate |
A |
The null predicate (rule |
Predicate | NOT(Predicate) |
---|---|
|
|
|
|
|
|
geometry IS NOT NULL
{
"op": "not",
"args": [
{
"op": "isNull",
"args": [ { "property": "geometry" } ]
}
]
}
7. Common Query Language enhancements
7.1. Overview
This clause specifies requirements for enhancements to Basic CQL2. Specifically, this clause defines requirements for:
-
Advanced comparison operators;
-
Case-insensitive comparison;
-
Accent-insensitive comparison;
-
Spatial functions;
-
Temporal functions;
-
Array functions;
-
Property-property and literal-literal comparisons;
-
Support for functions in CQL2;
-
Support for arithmetic expression in CQL2;
In each case, this clause specifies requirements for the rules in CQL2 BNF not supported by Basic CQL2.
7.2. Requirements Class "Advanced Comparison Operators"
Requirements Class |
|
http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
This requirements class adds support for the operators LIKE, BETWEEN and IN.
Requirement 5 |
/req/advanced-comparison-operators/like-predicate |
A |
The like predicate (rule |
B |
If the value does not match the pattern ( |
C |
If the character expression (rule |
D |
The character expression (rule |
E |
The wildcard character SHALL be the percent character (ASCII x25, |
F |
The wildcard SHALL match zero of more characters in the test value. |
G |
The wildcard character SHALL not match the NULL value. |
H |
The single character wildcard SHALL be the underbar character (ASCII x5F, |
I |
The single character wildcard SHALL match one character in the test value. |
J |
The single character wildcard SHALL not match the NULL value. |
K |
The escape character SHALL be the back slash (ASCII x5C, |
Permission 3 |
/per/advanced-comparison-operators/like-predicate |
A |
The server MAY not support |
name LIKE 'Smith%'
{
"op": "like",
"args": [
{ "property": "name" },
"Smith%"
]
}
Requirement 6 |
/req/advanced-comparison-operators/between-predicate |
A |
The between predicate (rule |
B |
If the value lies outside the specified range, then the predicate SHALL evaluate to the Boolean value |
C |
If any numeric expression (rule |
D |
Any function (rule |
Permission 4 |
/per/advanced-comparison-operators/between-predicate |
A |
The server MAY not support a |
B |
The server MAY not support a |
depth BETWEEN 100.0 and 150.0
{
"op": "between",
"args": [
{ "property": "depth" },
100.0,
150.0
]
}
Requirement 7 |
/req/advanced-comparison-operators/in-predicate |
A |
The in-list predicate (rule |
B |
The items in the list of an in-list predicate (rule |
Permission 5 |
/per/advanced-comparison-operators/in-predicate |
A |
The server MAY not support |
B |
The server MAY not support |
cityName IN ('Toronto','Frankfurt','Tokyo','New York')
{
"op": "in",
"args": [
{ "property": "cityName" },
[ "Toronto", "Frankfurt", "Tokyo", "New York" ]
]
}
category NOT IN (1,2,3,4)
{
"op": "not",
"args": [
{
"op": "in",
"args": [
{ "property": "category" },
[ 1, 2, 3, 4 ]
]
}
]
}
7.3. Requirements Class "Case-insensitive Comparison"
Requirements Class |
|
http://www.opengis.net/spec/cql2/1.0/req/case-insensitive-comparison |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
The following requirements class adds support for case-insensitive string comparisons.
This capability is useful to operate across data that has not been normalized or has been normalized to values that are different than they should be. This is implemented via a standardized string function to normalize a string with respect to case (CASEI
).
For example, the CASEI
function is useful when a property is set to "PLANET", "Planet", or "planet" and one wants to match either without having to enumerate all the variations.
Implementations of the CASEI
function can be complex and depend on the locale, but in many cases the underlying datastore will provide a capability that the function can be mapped to.
Requirement 8 |
/req/case-insensitive-comparison/casei-function |
A |
The server SHALL support a function named |
B |
The function SHALL accept one argument that can be a character string literal, the name of a property that evaluates to a character string literal or a function that returns a character string literal (see rules |
C |
The function SHALL return a character string. |
D |
If the argument to the function is |
E |
The function SHALL implement the full case folding algorithm defined in the implementation guidelines of the Unicode 15.0.0 standard (see clause 5.18 Case Mappings, sub-clause Caseless Matching, CaseFolding-15.0.0.txt and SpecialCasing-15.0.0.txt). |
Note
|
Implementation Guidance for CASEI() The implementation of case folding makes use of the CaseFolding-15.0.0.txt file and replaces code points in the source string by the corresponding sequence on lines with a 'C'(ommon) or 'F'(ull). |
CASEI(road_class) IN (CASEI('Οδος'),CASEI('Straße'))
{
"op": "in",
"args": [
{
"op": "casei",
"args": [ { "property": "road_class" } ]
},
[
{ "op": "casei", "args": [ "Οδος" ] },
{ "op": "casei", "args": [ "Straße" ] }
]
]
}
The CASEI
function returns a string typed representation of the input expression that is guaranteed to be equal to any other case insensitive representation of that string. In order to ensure correct comparisons, the function should be applied to both sides of an expression. So, for example, the only durable case-insensitive equality comparison would be CASEI(some_property) = CASEI('Straße')
. An expression such as CASEI(some_property) = 'strasse'
might work but is not guaranteed to work across implementations or between versions of the same implementation.
7.4. Requirements Class "Accent-insensitive Comparison"
Requirements Class |
|
http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
This requirements class adds support for accent-insensitive string comparisons to operate across data that has not been normalized or has been normalized to values that are different than they should be.
Similar to the case-insensitive comparison, this capability is supported via a string function ACCENTI
.
For example, the ACCENTI
function is useful when accents (or, more generally, diacritics not available in ASCII) were dropped when indexing a property. This may be useful, for example, to support users that are not familiar with accents or that do not know how to type them on their keyboard. For example, "papa" would also match "papá". Note that accent-insensitive comparisons can match values with a different meaning. E.g., in Spanish "papa" is potato and "papá" is father. "papá" in an accent-insensitive comparison will match both, but this may also be intentional, because the users knows that some of the data has been processed in ASCII.
Implementations of the ACCENTI
function can be complex, but in many cases the underlying datastore will provide a capability that the function can be mapped to.
Requirement 9 |
/req/accent-insensitive-comparison/accenti-function |
A |
The server SHALL support a function named |
B |
The function SHALL accept one argument that can be a character string literal, the name of a property that evaluates to a character string literal or a function that returns a character string literal (see rules |
C |
The function SHALL return a character string. |
D |
If the argument to the function is |
E |
The function SHALL implement accent stripping and diacritic folding. |
ACCENTI(etat_vol) = ACCENTI('débárquér')
{
"op": "=",
"args": [
{
"op": "accenti",
"args": [ { "property": "etat_vol" } ]
},
{
"op": "accenti",
"args": [ "débárquér" ]
}
]
}
Like CASEI
, the ACCENTI
function returns a string typed representation of the input expression that is guaranteed to be equal to any other accent insensitive representation of that string. In order to ensure correct comparisons, the function should be applied to both sides of an expression. So, for example, the only durable accent-insensitive equality comparison would be ACCENTI(some_property) = ACCENTI('papá')
. An expression such as ACCENTI(some_property) = 'papa'
might work but is not guaranteed to work across implementations or between versions of the same implementation.
Note
|
Implementation guidance for ACCENTI() The implementation of an ACCENTI() function requires the use of fields 3 and 5 from UnicodeData.txt and the application of the Unicode Normalization Algorithm (NFD or NFKD) by:
then:
|
Recommendation 2 |
/rec/accent-insensitive-comparison/japanese-non-spacing-marks Implementations of the ACCENTI() function SHOULD not remove the Japanese non-spacing marks dakuten U+3099[ ゛] and handakuten U+309A[゜]. |
7.5. Requirements Class "Basic Spatial Functions"
Requirements Class |
|
http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
|
Dependency |
OGC Simple feature access - Part 1: Common architecture, Architecture |
A spatial predicate evaluates two geometry-valued expressions to determine if the expressions satisfy the requirements of the specified spatial comparison function.
7.5.1. Basic spatial data types and literal values
The basic spatial data types are (part of rule spatialInstance
):
-
"Point": a point;
-
"BBox": a bounding rectangle or box.
For the Point data type, the following representations are used for literal values:
-
Text: an OGC Well-Known Text (WKT) literal (see clause 7 of Simple feature access - Part 1: Common architecture)
-
JSON: a GeoJSON geometry object (see clause 3.1 of GeoJSON)
For the BBox data type:
In the Text representation, the type is encoded as a BBOX()
spatial comparison function with four or six numerical arguments, depending on whether the coordinates include a vertical axis (height or depth):
-
Lower left corner, coordinate axis 1
-
Lower left corner, coordinate axis 2
-
Minimum value, coordinate axis 3 (optional)
-
Upper right corner, coordinate axis 1
-
Upper right corner, coordinate axis 2
-
Maximum value, coordinate axis 3 (optional)
In cases where the bounding box spans the antimeridian of a geographic coordinate reference system, the lower-left value (west-most box edge) is larger than the upper-right value (east-most box edge).
If the vertical axis is included, the third and the sixth number are the bottom and the top of the 3-dimensional bounding box.
In JSON, the BBox type is encoded as a JSON object with a "bbox" member with an array with four or six numbers. This representation is consistent with the GeoJSON representation of a bounding box (see clause 5 of GeoJSON).
Since WKT and GeoJSON do not provide a capability to specify the CRS of a geometry literal, the server has to determine the CRS of the geometry literals in a filter expression through another mechanism. For example, a query parameter filter-crs
is used in OGC API - Features - Part 3: Filtering to pass the CRS information to the server.
-
spatial geometry (Text)
POINT(43.5845 -79.5442)
-
spatial geometry (JSON)
{ "type": "Point", "coordinates": [43.5845,-79.5442] }
-
bounding box (Text)
BBOX(160.6,-55.95,-170,-25.89)
-
bounding box (JSON)
{ "bbox": [160.6, -55.95, -170, -25.89] }
7.5.2. Spatial Functions
In this conformance class, the only required spatial comparison function is intersects and the only required spatial literals are point and BBox. Additional spatial literals are specified in the Basic Spatial Functions with additional Spatial Literals requirements class and additional spatial comparison functions are specified in the Spatial Functions requirements class.
Requirement 10 |
/req/basic-spatial-operators/spatial-predicate |
A |
If the requirements of the standardized spatial comparison function are satisfied, then the predicate SHALL evaluate to the Boolean value |
B |
If the requirements of the standardized spatial comparison function are not satisfied, then the predicate SHALL evaluate to the Boolean value |
C |
If either geometry expression (rule |
Requirement 11 |
/req/basic-spatial-functions/spatial-functions |
A |
The server SHALL support the standardized |
B |
All supported standardized spatial comparison functions SHALL be evaluated as defined in clause 6.1.15 of OpenGIS® Implementation Standard for Geographic information - Simple feature access - Part 1: Common architecture (except that in CQL2 the predicates evaluate to a Boolean, not an Integer). |
Permission 6 |
/per/basic-spatial-functions/spatial-predicates |
A |
The server MAY not support a |
B |
The server MAY not support a |
Permission 7 |
/per/basic-spatial-functions/spatial-data-types |
A |
The server MAY only support |
7.5.3. Examples
S_INTERSECTS(geometry,POINT(36.319836 32.288087))
{
"op": "s_intersects",
"args": [
{ "property": "geometry" },
{
"type": "Point",
"coordinates": [ 36.319836, 32.288087 ]
}
]
}
...filter-lang=cql2-text& filter-crs=http://www.opengis.net/def/crs/EPSG/0/32635& filter=S_INTERSECTS(geometry,POINT(379213.87 3610774.16))...
Note that the values of the filter-crs
and filter
parameters have not been percent-encoded (see section 2.1 of RFC 3986) in this example for better readability.
7.6. Requirements Class "Basic Spatial Functions with additional Spatial Literals"
Requirements Class |
|
http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
|
Dependency |
OGC Simple feature access - Part 1: Common architecture, Architecture |
This requirements class is similar to the Basic Spatial Functions requirements class except it removes the restrictions on the spatial literals that can participate in the expression.
7.6.1. Additional spatial data types and literal values
In addition to the spatial types listed in the Basic Spatial Functions requirements class (i.e. "Point", "BBox"), this requirements class allows the following Spatial Literals (part of rule spatialInstance
):
-
"LineString": a curve with linear interpolation between the vertices;
-
"Polygon": a planar surface bounded by closed line strings;
-
"MultiPoint": a collection of points;
-
"MultiLineString": a collection of line strings;
-
"MultiPolygon": a collection of polygons;
-
"GeometryCollection": a collection of one or more of "Point", "Polygon", "MultiPoint", "MultiLineString", or "MultiPolygon" instances;
Requirement 12 |
/req/basic-spatial-functions-plus/spatial-data-types |
A |
The server SHALL support all spatial literals as defined by the BNF rule |
The following representations are used for literal values:
-
Text: an OGC Well-Known Text (WKT) literal (see clause 7 of Simple feature access - Part 1: Common architecture)
-
JSON: a GeoJSON geometry object (see clause 3.1 of GeoJSON)
-
spatial geometry (Text)
LINESTRING(43.6776 -79.5792, 43.7089 -79.5532, 43.7184 -79.5169, 43.7314 -79.4503, 43.7592 -79.4037, 43.7681 -79.3384, 43.8118 -79.3473, 43.8118 -79.3473, 43.8416 -79.3673) POLYGON((43.5845 -79.5442, 43.6079 -79.4893, 43.5677 -79.4632, 43.6129 -79.3925, 43.6223 -79.3238, 43.6576 -79.3163, 43.7945 -79.1178, 43.8144 -79.1542, 43.8555 -79.1714, 43.7509 -79.6390, 43.5845 -79.5442))
-
spatial geometry (JSON)
{
"type": "LineString",
"coordinates": [
[43.6776,-79.5792],
[43.7089,-79.5532],
[43.7184,-79.5169],
[43.7314,-79.4503],
[43.7592,-79.4037],
[43.7681,-79.3384],
[43.8118,-79.3473],
[43.8118,-79.3473],
[43.8416,-79.3673]
]
}
{
"type": "Polygon",
"coordinates": [
[
 [43.5845,-79.5442],
[43.6079,-79.4893],
[43.5677,-79.4632],
[43.6129,-79.3925],
[43.6223,-79.3238],
[43.6576,-79.3163],
[43.7945,-79.1178],
[43.8144,-79.1542],
[43.8555,-79.1714],
[43.7509,-79.6390],
[43.5845,-79.5442]
]
]
}
S_INTERSECTS(geometry,POLYGON((43.5845 -79.5442, 43.6079 -79.4893, 43.5677 -79.4632, 43.6129 -79.3925, 43.6223 -79.3238, 43.6576 -79.3163, 43.7945 -79.1178, 43.8144 -79.1542, 43.8555 -79.1714, 43.7509 -79.6390, 43.5845 -79.5442)))
{
"op": "s_intersects",
"args": [
{ "property": "geometry" },
{
 "type": "Polygon",
 "coordinates": [
 [
 [43.5845,-79.5442],
 [43.6079,-79.4893],
 [43.5677,-79.4632],
 [43.6129,-79.3925],
 [43.6223,-79.3238],
 [43.6576,-79.3163],
 [43.7945,-79.1178],
 [43.8144,-79.1542],
 [43.8555,-79.1714],
 [43.7509,-79.6390],
 [43.5845,-79.5442]
 ]
 ]
}
]
}
...filter-lang=cql2-text& filter-crs=http://www.opengis.net/def/crs/EPSG/0/32635& filter=S_INTERSECTS(geometry,POLYGON((43.5845 -79.5442, 43.6079 -79.4893, 43.5677 -79.4632, 43.6129 -79.3925, 43.6223 -79.3238, 43.6576 -79.3163, 43.7945 -79.1178, 43.8144 -79.1542, 43.8555 -79.1714, 43.7509 -79.6390, 43.5845 -79.5442)))...
Note that the values of the filter-crs
and filter
parameters have not been percent-encoded (see section 2.1 of RFC 3986) in this example for better readability.
7.7. Requirements Class "Spatial Functions"
Requirements Class |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
|
Dependency |
Requirements Class "Basic Spatial Functions with additional Spatial Literals" |
This requirements class adds:
-
a set of Dimensionally Extended Nine-intersection Model (DE-9IM) relation operators that may be used to add spatial predicates to a CQL2 filter expression. These operators are implemented in CQL2 as standardized functions.
7.7.1. Spatial Functions
Requirement 13 |
/req/spatial-functions/spatial-functions |
A |
The server SHALL support all standardized spatial comparison functions as defined by the BNF rule |
This clause specifies a set of standardized spatial comparison functions that can be used to evaluate whether a specific spatial relationship exists between a pair of geometries.
The definition of these spatial comparison functions is based on a Dimensionally Extended 9-Intersection Model (DE-9IM) and further discussion and explanation about this model can be found at DE-9IM and Dimensionally Extended 9-Intersection Model.
Consider geometries a
and b
.
The spatial relationships between a
and b
can be represented by the following intersection matrix (see DE-9IM):
I()
represents the set of all positions in the interior of the geometry, B()
represents the set of all positions on the boundary of the geometry and E()
represents the set of all exterior positions. dim()
represents the dimension of the intersection of the interior (I
), boundary (B
) and exterior (E
) of geometries a
and b
.
The value of each cell in this intersection matrix is either:
-
0
(i.e. the dimension of the intersection is a point), -
1
(i.e. the dimension of the intersection is a line), -
2
(i.e. the dimension of the intersection is an area) or, -
∅
for the empty set or no intersection.
These values are sometimes simplified to:
-
T
representing{0,1,2}
(if the actual value of the dimension does not matter), -
F
representing the empty set and, -
*
representing a value that is not relevant to the evaluation of a spatial comparison function.
An example of such an intersection matrix is:
\$[[T,"*",F],["*","*",F],[F,F,"*"]]\$
The following table lists the mathematical definitions of each standardized spatial comparison function as described in OpenGIS® Implementation Standard for Geographic information - Simple feature access - Part 1: Common architecture and also using DE-9IM.
Spatial comparison function | Definition | Intersection matrix |
---|---|---|
S_CONTAINS |
S_CONTAINS(a,b) ⬄ b WITHIN a |
\$[[T,"*","*"],["*","*","*"],[F,F,"*"]]\$ |
S_CROSSES |
S_CROSSES(a,b) ⬄ [I(a) ∩ I(b) ≠ ∅) ∧ (a ∩ b ≠ a) ∧ (a ∩ b ≠ b)] |
\$[[T,"*",T],["*","*","*"],["*","*","*"]]\$, \$[[T,"*","*"],["*","*","*"],[T,"*","*"]]\$, \$[[0,"*","*"],["*","*","*"],["*","*","*"]]\$ |
S_DISJOINT |
S_DISJOINT(a,b) ⬄ a ∩ b = ∅ |
\$[[F,F,"*"],[F,F,"*"],["*","*","*"]]\$ |
S_EQUALS |
S_EQUALS(a,b) ⬄ a ⊆ b ∧ b ⊆ a |
\$[[T,"*",F],["*","*",F],[F,F,"*"]]\$ |
S_INTERSECTS |
S_INTERSECTS(a,b) ⬄ ! a DISJOINT b |
\$[[T,"*","*"],["*","*","*"],["*","*","*"]]\$,\$[["*",T,"*"],["*","*","*"],["*","*","*"]]\$,\$[["*","*","*"],[T,"*","*"],["*","*","*"]]\$,\$[["*","*","*"],["*",T,"*"],["*","*","*"]]\$ |
S_OVERLAPS |
S_OVERLAPS(a,b) ⬄ (dim(I(a)) = dim(I(b)) = dim(I(a) ∩ I(b))) ∧ (a ∩ b ≠ a) ∧ (a ∩ b ≠ b) |
\$[[T,"*",T],["*","*","*"],[T,"*","*"]]\$,\$[[1,"*",T],["*","*","*"],[T,"*","*"]]\$, |
S_TOUCHES |
S_TOUCHES(a,b) ⬄ (I(a) ∩ I(b) = ∅) ∧ (a ∩ b) ≠ ∅ |
\$[[F,T,"*"],["*","*","*"],["*","*","*"]]\$,\$[[F,"*","*"],[F,"*","*"],["*","*","*"]]\$,\$[[F,"*","*"],["*",T,"*"],["*","*","*"]]\$ |
S_WITHIN |
S_WITHIN(a,b) ⬄ (a ∩ b = a) ∧ (I(a) ∩ E(b) = ∅) |
\$[[T,"*",F],["*","*",F],["*","*","*"]]\$ |
The following diagrams illustrate the meaning of the S_CROSSES
, S_OVERLAPS
, S_TOUCHES
and S_WITHIN
spatial comparison functions.
Note
|
If geometry a S_CONTAINS geometry b, then geometry b is S_WITHIN geometry a.
|
S_CROSSES(road,POLYGON((43.7286 -79.2986, 43.7311 -79.2996, 43.7323 -79.2972, 43.7326 -79.2971, 43.7350 -79.2981, 43.7350 -79.2982, 43.7352 -79.2982, 43.7357 -79.2956, 43.7337 -79.2948, 43.7343 -79.2933, 43.7339 -79.2923, 43.7327 -79.2947, 43.7320 -79.2942, 43.7322 -79.2937, 43.7306 -79.2930, 43.7303 -79.2930, 43.7299 -79.2928, 43.7286 -79.2986)))
{
"op": "s_crosses",
"args": [
{ "property": "road" },
{
"type": "Polygon",
"coordinates": [
[
[ 43.7286, -79.2986 ], [ 43.7311, -79.2996 ], [ 43.7323, -79.2972 ],
[ 43.7326, -79.2971 ], [ 43.7350, -79.2981 ], [ 43.7350, -79.2982 ],
[ 43.7352, -79.2982 ], [ 43.7357, -79.2956 ], [ 43.7337, -79.2948 ],
[ 43.7343, -79.2933 ], [ 43.7339, -79.2923 ], [ 43.7327, -79.2947 ],
[ 43.7320, -79.2942 ], [ 43.7322, -79.2937 ], [ 43.7306, -79.2930 ],
[ 43.7303, -79.2930 ], [ 43.7299, -79.2928 ], [ 43.7286, -79.2986 ]
]
]
}
]
}
7.8. Requirements Class "Temporal Functions"
Requirements Class |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
|
Dependency |
W3C/OGC Time Ontology in OWL, Topological Temporal Relations |
A temporal predicate evaluates two time-valued expressions to determine, if the expressions satisfy the requirements of the specified standardized temporal comparison function.
The operands in a temporal predicate are temporal geometries. A temporal geometry is either an instant or an interval.
7.8.1. Temporal data types and instances
An instant is either a date (rule dateInstant
) or a timestamp (rule timestampInstant
) in accordance with RFC 3339 (RFC 3339 rules full-date
or date-time
). Note that since time is continuous, every instant has a duration and a start/end. Nevertheless, the geometry can be considered an instant in the temporal resolution that is applicable for the specific property.
An interval is the time between a start instant and an end instant, including both bounding instances (rule intervalInstance
). Unbounded interval ends are represented by a double-dot string ("..") based on the convention specified in ISO 8601-2.
CQL2 follows ISO 8601-1/ISO 8601-2 in defining intervals as closed at both start and end. Note that some implementations and other specifications use a different definition and it may be necessary to convert between the interval representations. For example, SQL uses half-closed intervals - closed at the start, open at the end.
Depending on the implementation environment, the underlying datastore may or may not support intervals as data types of properties. If not, intervals are typically represented by two separate properties that are instants, one for the start and one for the end of the interval.
All temporal geometries are in the Gregorian Calendar. This is a deliberate restriction to keep implementations of CQL2 simple, avoiding requirements to transform time instants to other temporal coordinate reference systems, but still cover a large number of use cases. This is consistent with the use of RFC 3339 as a key standard for expressing date and time on the internet, including in the OGC API Standards.
For intervals, the following representations are used:
-
Text: an
INTERVAL
function with two instants or double-dot strings as parameters; -
JSON: an object with an
interval
member with an array of two instants or double-dot strings as parameters.
In case two instants are provided, both instants have the same granularity (i.e., they are either timestamps or dates).
Note
|
Instants are also scalar data types; for the representations and examples of instances see Scalar data types. |
-
intervals (Text)
INTERVAL('1969-07-16', '1969-07-24') INTERVAL('1969-07-16T05:32:00Z', '1969-07-24T16:50:35Z') INTERVAL('2019-09-09', '..')
-
intervals (JSON)
{ "interval": [ "1969-07-16", "1969-07-24" ] } { "interval": [ "1969-07-16T05:32:00Z", "1969-07-24T16:50:35Z" ] } { "interval": [ "2019-09-09", ".." ] }
7.8.2. Temporal Functions
The standardized temporal comparison functions in CQL2 are based on the temporal operator definitions in the W3C/OGC Time Ontology in OWL.
Note
|
Simple temporal predicates involving time instants can also be evaluated using the standard comparison operators. |
The following table specifies the definition of the standardized temporal comparison functions where both operands may be instants or intervals, including mixed combinations.
Temporal comparison function | Definition (t1: first operand, t2: second operand) |
---|---|
T_AFTER |
See after |
T_BEFORE |
See before |
T_DISJOINT |
(t1 T_BEFORE t2) OR (t1 T_AFTER t2) |
T_EQUALS |
Start and end of t1 and t2 are coincident |
T_INTERSECTS |
NOT (t1 T_DISJOINT t2) |
Additional temporal comparison functions are available, but only applicable for intervals. Using these functions with instants will result in a client error.
Temporal comparison function | Definition |
---|---|
T_CONTAINS |
See intervalContains |
T_DURING |
See intervalDuring |
T_FINISHEDBY |
|
T_FINISHES |
See intervalFinishes |
T_MEETS |
See intervalMeets |
T_METBY |
See intervalMetBy |
T_OVERLAPPEDBY |
|
T_OVERLAPS |
See intervalOverlaps |
T_STARTEDBY |
See intervalStarts |
T_STARTS |
The following diagram illustrates the meaning of most of the standardized temporal comparison functions when applied to intervals.
Requirement 14 |
/req/temporal-operators/temporal-predicates |
A |
If the requirements of the standardized temporal comparison function are satisfied, then the predicate SHALL evaluate to the Boolean value |
B |
If the requirements of the standardized temporal comparison function are not satisfied, then the predicate SHALL evaluate to the Boolean value |
C |
If the either temporal expression (rule |
Requirement 15 |
/req/temporal-functions/temporal-functions |
A |
The server SHALL support all temporal functions as defined by the BNF rule |
B |
Permission 8 |
/per/temporal-functions/temporal-operands |
A |
The server MAY not support a |
B |
The server MAY not support a |
7.8.3. Type casts
As stated in Type casts, the evaluation of filter expressions that involve type casts is system dependent.
For example, a system that evaluates the interval INTERVAL('2022-01-01','2022-04-11T12:41:13Z')
can, for example,
-
throw an error (incompatible types in an interval);
-
cast the value to an interval of dates, e.g.,
INTERVAL('2022-01-01','2022-04-11')
; -
cast the value to an interval of timestamps, e.g.,
INTERVAL('2022-01-01Z00:00:00Z','2022-04-11T12:41:13Z')
.
7.8.4. Examples
T_INTERSECTS(event_time, INTERVAL('1969-07-16T05:32:00Z', '1969-07-24T16:50:35Z'))
{
"op": "t_intersects",
"args": [
{ "property": "event_time" },
{ "interval": [ "1969-07-16T05:32:00Z", "1969-07-24T16:50:35Z" ] }
]
}
T_DURING(INTERVAL(touchdown, liftOff), INTERVAL('1969-07-16T13:32:00Z', '1969-07-24T16:50:35Z'))
{
"op": "t_during",
"args": [
{ "interval": [ { "property": "touchdown" }, { "property": "liftOff" } ] },
{ "interval": [ "1969-07-16T13:32:00Z", "1969-07-24T16:50:35Z" ] }
]
}
7.9. Requirements class "Array Functions"
Requirements Class |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
This clause specifies requirements for supporting array expression in CQL2.
7.9.1. Arrays
An array is a bracket-delimited, comma-separated list of array elements. An array element is either a scalar value, a geometry, an interval, or another array.
-
arrays (Text)
( 'a', 'c' ) ( 'a', true, 1 ) ( DATE('1969-07-16'), DATE('1969-07-20'), DATE('1969-07-24') )
-
arrays (JSON)
[ "a", "c" ] [ "a", true, 1 ] [ { "date" : "1969-07-16" }, { "date" : "1969-07-20" }, { "date" : "1969-07-24" } ]
7.9.2. Array Functions
Array expressions can be tested in a predicate for equality, if one array is a subset of another, if one array is a superset of another or if two arrays overlap or share elements using a standardized set of array comparison functions.
Requirement 16 |
/req/array-functions/array-predicates |
A |
The server SHALL support arrays as defined by the BNF rule
|
B |
Both array expressions SHALL be evaluated as sets. No inherent order SHALL be implied in an array of values. |
C |
The semantics of the standardized array comparison functions SHALL be evaluated as follows:
|
Permission 9 |
/per/array-functions/array-predicates |
A |
The server MAY not support an |
B |
The server MAY not support a |
Note
|
Support for the BNF rule function is added by
the requirements class Functions.
Support for the BNF rule arithmeticExpression is added by
the requirements class Arithmetic Expressions.
|
7.10. Requirements Class "Property-Property Comparisons"
Requirements Class |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
This requirements class adds support for properties on the right side of predicates and for literal on the left side of predicates.
Requirement 17 |
/req/property-property/withdraw-permissions |
A |
The following permissions SHALL not apply:
|
S_CROSSES(LINESTRING(43.72992 -79.2998, 43.73005 -79.2991, 43.73006 -79.2984, 43.73140 -79.2956, 43.73259 -79.2950, 43.73266 -79.2945, 43.73320 -79.2936, 43.73378 -79.2936, 43.73486 -79.2917), POLYGON((43.7286 -79.2986, 43.7311 -79.2996, 43.7323 -79.2972, 43.7326 -79.2971, 43.7350 -79.2981, 43.7350 -79.2982, 43.7352 -79.2982, 43.7357 -79.2956, 43.7337 -79.2948, 43.7343 -79.2933, 43.7339 -79.2923, 43.7327 -79.2947, 43.7320 -79.2942, 43.7322 -79.2937, 43.7306 -79.2930, 43.7303 -79.2930, 43.7299 -79.2928, 43.7286 -79.2986)))
{
"op": "s_crosses",
"args": [
{
"type": "LineString",
"coordinates": [
[ 43.72992, -79.2998 ], [ 43.73005, -79.2991 ], [ 43.73006, -79.2984 ],
[ 43.73140, -79.2956 ], [ 43.73259, -79.2950 ], [ 43.73266, -79.2945 ],
[ 43.73320, -79.2936 ], [ 43.73378, -79.2936 ], [ 43.73486, -79.2917 ]
]
},
{
"type": "Polygon",
"coordinates": [
[
[ 43.7286, -79.2986 ], [ 43.7311, -79.2996 ], [ 43.7323, -79.2972 ],
[ 43.7326, -79.2971 ], [ 43.7350, -79.2981 ], [ 43.7350, -79.2982 ],
[ 43.7352, -79.2982 ], [ 43.7357, -79.2956 ], [ 43.7337, -79.2948 ],
[ 43.7343, -79.2933 ], [ 43.7339, -79.2923 ], [ 43.7327, -79.2947 ],
[ 43.7320, -79.2942 ], [ 43.7322, -79.2937 ], [ 43.7306, -79.2930 ],
[ 43.7303, -79.2930 ], [ 43.7299, -79.2928 ], [ 43.7286, -79.2986 ]
]
]
}
]
}
T_DURING(INTERVAL('1969-07-20T20:17:40Z', '1969-07-21T17:54:00Z'), INTERVAL('1969-07-16T13:32:00Z', '1969-07-24T16:50:35Z'))
{
"op": "t_during",
"args": [
{ "interval": [ "1969-07-20T20:17:40Z", "1969-07-21T17:54:00Z" ] },
{ "interval": [ "1969-07-16T13:32:00Z", "1969-07-24T16:50:35Z" ] }
]
}
7.11. Requirements Class "Functions"
Requirements Class |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
This sub-clause specifies requirements for supporting custom functions in CQL2. Functions allow implementations to extend the language.
Requirement 18 |
/req/functions/functions |
A |
The server SHALL support custom functions as defined by the BNF rules |
B |
The function SHALL evaluate to its return value that is allowed in the same rule in which the function is used. |
Note
|
Support for the BNF rule arithmeticExpression is added by
the requirements class Arithmetic Expressions.
|
It should be noted that the function "Buffer()" in this example is not part of CQL2 but is an example of a function that an implementation may offer that returns a geometry value.
S_WITHIN(road,Buffer(geometry,10,'m'))
{
"op": "s_within",
"args": [
{ "property": "road" },
{
"op": "Buffer",
"args": [
{ "property": "geometry" },
10,
"m"
]
}
]
}
7.12. Requirements Class "Arithmetic Expressions"
Requirements Class |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
This clause specifies requirements for supporting arithmetic expressions in CQL2.
An arithmetic expression is an expression composed of an arithmetic operand
(a property name, a number or a function that returns a number), an arithmetic
operator (i.e., one of +
, -
, *
, /
, %
, div
, or ^
) and another arithmetic operand.
+
, -
, *
, and /
are the four basic arithmetic operations (addition, subtraction, multiplication and division). In addition, the modulo operator (%
), integer division (div
), and the exponention operator (^
) are supported.
Requirement 19 |
/req/arithmetic/arithmetic |
A |
The server SHALL support arithmetic expressions as defined by the BNF rules
|
B |
Is any |
Note
|
Support for the BNF rule function is added by the requirements class Functions.
|
vehicle_height > (bridge_clearance-1)
{
"op": ">",
"args": [
{ "property": "vehicle_height" },
{
"op": "-",
"args": [
{ "property": "bridge_clearance" },
1
]
}
]
}
8. Requirements classes for encodings
8.2. Requirements Class "CQL2 Text"
Requirements Class |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
|
Conditional Dependency |
Simple feature access - Part 1: Common architecture, Well-known Text Representation for Geometry |
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
Requirements Class "Basic Spatial Functions with additional Spatial Literals" |
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
This requirements class defines a Well Known Text (WKT) encoding of CQL2. Such an
encoding would be suitable for use with the GET query parameter such as the
filter
query parameter specified by the "Filter" requirements class
in OGC API - Features - Part 3: Filtering.
The "CQL2 Text" encoding is defined by the BNF grammar defined in CQL2 BNF.
Keywords in the BNF grammar are case-insensitive. Augmented BNF for Syntax Specifications states:
ABNF strings are case insensitive and the character set for these strings is US-ASCII.
The list of CQL2 keywords includes:
-
"A_EQUALS"
-
"A_CONTAINS"
-
"A_CONTAINEDBY"
-
"A_OVERLAPS"
-
"ACCENTI"
-
"AND"
-
"BBOX"
-
"BETWEEN"
-
"CASEI"
-
"DATE"
-
"DIV"
-
"FALSE"
-
"GEOMETRYCOLLECTION"
-
"IN"
-
"IS"
-
"LIKE"
-
"LINESTRING"
-
"MULTILINESTRING"
-
"MULTIPOINT"
-
"MULTIPOLYGON"
-
"NOT"
-
"NULL"
-
"OR"
-
"POINT"
-
"POLYGON"
-
"S_INTERSECTS"
-
"S_EQUALS"
-
"S_DISJOINT"
-
"S_TOUCHES"
-
"S_WITHIN"
-
"S_OVERLAPS"
-
"S_CROSSES"
-
"S_CONTAINS"
-
"T_AFTER"
-
"T_BEFORE"
-
"T_CONTAINS"
-
"T_DISJOINT"
-
"T_DURING"
-
"T_EQUALS"
-
"T_FINISHEDBY"
-
"T_FINISHES"
-
"T_INTERSECTS"
-
"T_MEETS"
-
"T_METBY"
-
"T_OVERLAPPEDBY"
-
"T_OVERLAPS"
-
"T_STARTEDBY"
-
"T_STARTS"
-
"TIMESTAMP"
-
"TRUE"
If a queryable uses a property name that is one of the keywords, the property name can be used in double quotes to avoid conflicts with the keyword.
Requirement 20 |
/req/cql2-text/basic-cql2 |
A |
The server SHALL be able to parse and evaluate all filter expressions encoded as a text string that validate against the BNF rules identified in the Basic CQL2 requirements class. |
Requirement 21 |
/req/cql2-text/escaping |
A |
The escape character in a character literal SHALL be the backslash ( |
B |
Embedded single quotations ( |
C |
The server SHALL be able to parse the following escaped sequences for encoding control characters in a character literal:
|
Requirement 22 |
/req/cql2-text/advanced-comparison-operators |
Condition |
Server implements requirements class Advanced Comparison Operators |
A |
The server SHALL be able to parse and evaluate all spatial functions encoded as a text string that validate against the BNF production fragments identified in the Advanced Comparison Operators requirements class. |
Requirement 23 |
/req/cql2-text/case-insensitive-comparison |
Condition |
Server implements requirements class Case-insensitive Comparisons |
A |
The server SHALL be able to parse and evaluate all standardized functions encoded as a text string that validate against the BNF production fragments identified in the Case-insensitive Comparisons requirements class. |
Requirement 24 |
/req/cql2-text/accent-insensitive-comparison |
Condition |
Server implements requirements class Accent-insensitive Comparisons |
A |
The server SHALL be able to parse and evaluate all standardized functions encoded as a text string that validate against the BNF production fragments identified in the Accent-insensitive Comparisons requirements class. |
Requirement 25 |
/req/cql2-text/basic-spatial-functions |
Condition |
Server implements requirements class Basic Spatial Functions |
A |
The server SHALL be able to parse and evaluate all standardized spatial comparison functions encoded as a text string that validate against the BNF production fragments identified in the Basic Spatial Functions requirements class. |
Requirement 26 |
/req/cql2-text/basic-spatial-functions-plus |
Condition |
Server implements requirements class Basic Spatial Functions with additional Spatial Literals |
A |
The server SHALL be able to parse all spatial instances encoded as a text string that validate against the BNF production fragments identified in the Basic Spatial Functions with additional Spatial Literals requirements class. |
B |
The server SHALL support spatial literals with coordinates in a 2D or 3D CRS, independent of including the |
OGC WKT uses a "Z" character to distinguish the dimensionality of the coordinate reference system (CRS), e.g. POINT(7 51)
for a 2D CRS and POINT Z(7 51 100)
for a 3D CRS. In CQL2 Text, processors are required to be more tolerant and to determine the coordinate dimension from the coordinates.
When creating a CQL2 Text expression, it is recommended to encode a geometry literal as required by OGC WKT.
Requirement 27 |
/req/cql2-text/spatial-functions |
Condition |
Server implements requirements class Spatial Functions |
A |
The server SHALL be able to parse and evaluate all standardized spatial comparison functions encoded as a text string that validate against the BNF production fragments identified in the Spatial Functions requirements class. |
Requirement 28 |
/req/cql2-text/temporal-functions |
Condition |
Server implements requirements class Temporal Functions |
A |
The server SHALL be able to parse and evaluate all standardized temporal comparison functions encoded as a text string that validate against the BNF production fragments identified in the Temporal Functions requirements class. |
Requirement 29 |
/req/cql2-text/arrays |
Condition |
Server implements requirements class Array Functions |
A |
The server SHALL be able to parse and evaluate all array expressions encoded as a text string that validate against the BNF production fragments identified in the Array Expressions requirements class. |
Requirement 30 |
/req/cql2-text/property-property |
Condition |
Server implements requirements class Property-Property Comparisons |
A |
The server SHALL be able to parse and evaluate literal values on the left-hand side of comparison, spatial, temporal or array operators and property references on the right-hand side of such operators. |
Requirement 31 |
/req/cql2-text/functions |
Condition |
Server implements requirements class Functions |
A |
The server SHALL be able to parse and evaluate all function call expressions encoded as a text string that validate against the BNF production fragments identified in the Functions requirements class. |
Requirement 32 |
/req/cql2-text/arithmetic |
Condition |
Server implements requirements class Arithmetic Expressions |
A |
The server SHALL be able to parse and evaluate all arithmetic expressions encoded as a text string that validate against the BNF production fragments identified in the Arithmetic Expressions requirements class. |
8.3. Requirements Class "CQL2 JSON"
Requirements Class |
|
Target type |
Servers that evaluate filter expressions |
Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
Requirements Class "Basic Spatial Functions with additional Spatial Literals" |
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
This requirements class defines a JSON encoding of CQL2. Such an encoding would be suitable as the body of an HTTP POST request.
Requirement 33 |
/req/cql2-json/basic-cql2 |
A |
The server SHALL be able to parse and evaluate all filter expressions encoded as JSON that validate against the JSON Schema in JSON Schema for CQL2 and that do not use the following schema components:
|
Permission 10 |
/per/cql2-json/basic-cql2 |
A |
The server MAY not support
|
Requirement 34 |
/req/cql2-text/advanced-comparison-operators |
Condition |
Server implements requirements class Advanced Comparison Operators |
A |
In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema components:
|
Requirement 35 |
/req/cql2-text/case-insensitive-comparison |
Condition |
Server implements requirements class Case-insensitive Comparisons |
A |
In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:
|
Requirement 36 |
/req/cql2-text/accent-insensitive-comparison |
Condition |
Server implements requirements class Accent-insensitive Comparisons |
A |
In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:
|
Requirement 37 |
/req/cql2-json/basic-spatial-functions |
Condition |
Server implements requirements class Basic Spatial Functions |
A |
The server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema components:
|
Requirement 38 |
/req/cql2-json/basic-spatial-functions-plus |
Condition |
Server implements requirements class Basic Spatial Functions with additional Spatial Literals |
A |
The server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema components:
|
Requirement 39 |
/req/cql2-json/spatial-functions |
Condition |
Server implements requirements class Spatial Functions |
A |
The server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema components:
|
Requirement 40 |
/req/cql2-json/temporal-functions |
Condition |
Server implements requirements class Temporal Functions |
A |
In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema components:
|
Requirement 41 |
/req/cql2-json/arrays |
Condition |
Server implements requirements class Array Functions |
A |
In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:
|
Requirement 42 |
/req/cql2-json/property-property |
Condition |
Server implements requirements class Property-Property Comparisons |
A |
In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use
|
Requirement 43 |
/req/cql2-json/functions |
Condition |
Server implements requirements class Functions |
A |
In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:
|
Requirement 44 |
/req/cql2-json/arithmetic |
Condition |
Server implements requirements class Arithmetic Expressions |
A |
In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:
|
8.4. XML encoding
This document does not specifically define an XML-encoding for CQL2. However, it is recognized that XML is still in common use and so implementers are directed to review the OGC Filter Encoding 2.0 standard which defines an XML-encoding for filter expressions that closely matches most of the functionality of CQL2.
9. Media Types
No media type has been registered for the CQL2 encodings. The reason is the assumption that filter expressions as such will rarely be used as standalone documents, but usually be part of another document, e.g. a HTTP request or response, and be embedded in it.
Annex A: Abstract Test Suite (Normative)
This test suite uses the Given-When-Then notation to specify the tests.
Each implementation under test supports the evaluation of filter expressions on one or more data sources. A data source may be, for example, a feature collection in an OGC Web API that implements the OGC API - Features Standard. The implementation must declare the queryable properties (queryables) for each data source.
The requirements specified in this Standard can only be tested, if the test can assess whether the result of an evaluation matches the filter expression. However, in general, the queryables may not be part of the response; that is, it is not possible to perform such an assessment in general without knowledge about the data and the relationship between the queryables and the data. In addition, to assess the implementation of some requirements (e.g., case folding) the test needs to know the data.
With just the knowledge about the queryables and their data types, the tests can typically assess that valid filter expressions for a set of queryables are evaluated without an error. These tests are basic tests specified in this test suite and can be executed against any data.
In addition, to properly test an implementation, conditional tests are provided, if the implementation operates on a test dataset and where the queryables are properties of the features.
The test dataset contains feature types with point, line string and polygon geometries. It is available as a GeoPackage file with the associated queryables specified in JSON Schema for each feature collection in the OGC API Features GitHub repository. The test dataset has been derived from three layers of the Natural Earth vector dataset at scale 1:110 million (ne_110m_admin_0_countries, ne_110m_populated_places_simple, ne_110m_rivers_lake_centerlines). Some columns have been removed and a few columns have been added with random data in order to also test filter expressions on date, timestamp and boolean properties.
The tests assume that
-
all feature properties are also queryables;
-
the queryable for the feature geometry is
geom
.
All eleven conformance classes for the standardization target type "servers that evaluate filter expressions" have the following parameter:
-
Filter Language: The CQL2 encoding to be used in the test, either "CQL2 Text" or "CQL2 JSON".
General rules for the encoding of all filter expressions in tests:
-
The conformance tests in this annex are specified using the CQL2 BNF grammar. Depending on the Filter Language parameter, the filter expressions have to be instantiated in an executable test as CQL2 Text or CQL2 JSON;
-
If a property name in a filter expression is a reserved CQL2 keyword, the property name has to be placed in double quotes.
Executable test suites for the eleven conformance classes will also need to decide on the following questions and support at least one option per question:
-
How to execute the evaluation of a filter expression for a data source? At a minimum, Web API endpoints specified in OGC API - Features - Part 3: Filtering, requirements class "Filter", should be supported;
-
What are the queryables for a data source? At a minimum, queryables specified using JSON Schema, see OGC API - Features - Part 3: Filtering, requirements class "Filter", should be supported;
-
What is the format of the response that matches the filter expression? At a minimum, GeoJSON feature collections should be supported.
To qualify as an OGC Reference Implementation for CQL2, an implementation under test has to
-
support the tests with the test dataset;
-
support both CQL2 Text and CQL2 JSON;
-
support at least the conformance classes "Case-insensitive comparison", "Spatial functions" and "Temporal functions" (including all dependencies).
A.1. Conformance Class "CQL2 Text"
Conformance Class |
|
Target type |
Servers that evaluate filter expressions |
Requirements class |
|
Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
A.1.1. Conformance Test 1
Test id: |
/conf/cql2-text/validate |
---|---|
Requirements: |
all requirements |
Test purpose: |
Validate that CQL2 Text is supported by the server |
Test method: |
Given:
When: Execute conformance tests for all supported conformance classes with the parameter "Filter Language". Use the value "CQL2 Text". Then:
|
A.1.2. Conformance Test 2
Test id: |
/conf/cql2-text/escaping |
---|---|
Requirements: |
|
Test purpose: |
Test escaping in string literals. |
Test method: |
Given:
When: Decode each string literal. Then:
|
A.2. Conformance Class "CQL2 JSON"
Conformance Class |
|
Target type |
Servers that evaluate filter expressions |
Requirements class |
|
Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
A.2.1. Conformance Test 3
Test id: |
/conf/cql2-json/validate |
---|---|
Requirements: |
all requirements |
Test purpose: |
Validate that CQL2 JSON is supported by the server |
Test method: |
Given:
When: Execute conformance tests for all supported conformance classes with the parameter "Filter Language". Use the value "CQL2 JSON". Note that the filter expressions in the test cases have to be converted to a CQL2 JSON representation. Then:
|
A.3. Conformance Class "Basic-CQL2"
Conformance Class |
|
Target type |
Servers that evaluate filter expressions |
Parameter |
Filter Language: "CQL2 Text" or "CQL2 JSON" |
Requirements class |
A.3.1. Conformance Test 4
Test id: |
/conf/basic-cql2/basic-test |
---|---|
Requirements: |
n/a |
Test purpose: |
Implementation under test provides sufficient information to construct filter expressions and supports comparison predicates |
Test method: |
Given:
When: n/a Then:
|
A.3.2. Conformance Test 5
Test id: |
/conf/basic-cql2/comparison |
---|---|
Requirements: |
|
Test purpose: |
Test comparison predicates |
Test method: |
Given:
When: For each queryable
where
Then:
|
A.3.3. Conformance Test 6
Test id: |
/conf/basic-cql2/is-null |
---|---|
Requirements: |
|
Test purpose: |
Test IS NULL predicate |
Test method: |
Given:
When: For each queryable
Then:
|
A.3.4. Conformance Test 7
Test id: |
/conf/basic-cql2/boolean |
---|---|
Requirements: |
|
Test purpose: |
Test boolean filter expression |
Test method: |
Given:
When: For each data source, evaluate the following filter expressions
Then:
|
A.3.5. Conformance Test 8
Test id: |
/conf/basic-cql2/test-data |
---|---|
Requirements: |
all requirements |
Test purpose: |
Test predicates against the test dataset |
Test method: |
Given:
When: Evaluate each predicate in Predicates and expected results. Then:
|
Data Source | Predicate | Expected number of items |
---|---|---|
ne_110m_admin_0_countries |
|
1 |
ne_110m_admin_0_countries |
|
84 |
ne_110m_admin_0_countries |
|
83 |
ne_110m_admin_0_countries |
|
94 |
ne_110m_admin_0_countries |
|
93 |
ne_110m_admin_0_countries |
|
176 |
ne_110m_admin_0_countries |
|
1 |
ne_110m_admin_0_countries |
|
39 |
ne_110m_admin_0_countries |
|
38 |
ne_110m_admin_0_countries |
|
139 |
ne_110m_admin_0_countries |
|
138 |
ne_110m_admin_0_countries |
|
176 |
ne_110m_populated_places_simple |
|
243 |
ne_110m_populated_places_simple |
|
0 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
137 |
ne_110m_populated_places_simple |
|
136 |
ne_110m_populated_places_simple |
|
107 |
ne_110m_populated_places_simple |
|
106 |
ne_110m_populated_places_simple |
|
242 |
ne_110m_populated_places_simple |
|
243 |
ne_110m_populated_places_simple |
|
0 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
123 |
ne_110m_populated_places_simple |
|
122 |
ne_110m_populated_places_simple |
|
121 |
ne_110m_populated_places_simple |
|
120 |
ne_110m_populated_places_simple |
|
242 |
ne_110m_populated_places_simple |
|
3 |
ne_110m_populated_places_simple |
|
240 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
3 |
ne_110m_populated_places_simple |
|
240 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
3 |
ne_110m_populated_places_simple |
|
240 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
1 |
A.3.6. Conformance Test 9
Test id: |
/conf/basic-cql2/logical |
---|---|
Requirements: |
|
Test purpose: |
Test filter expressions with AND, OR and NOT including sub-expressions |
Test method: |
Given:
When: Evaluate each predicate in Combinations of predicates and expected results. For the data source 'ne_110m_populated_places_simple', evaluate the filter expression Then:
|
p1 | p2 | p3 | p4 | Expected number of items |
---|---|---|---|---|
|
|
|
|
1 |
|
|
|
|
107 |
|
|
|
|
124 |
|
|
|
|
121 |
|
|
|
|
2 |
|
|
|
|
2 |
|
|
|
|
242 |
|
|
|
|
122 |
|
|
|
|
2 |
|
|
|
|
120 |
|
|
|
|
137 |
|
|
|
|
3 |
|
|
|
|
243 |
|
|
|
|
3 |
|
|
|
|
138 |
|
|
|
|
62 |
|
|
|
|
243 |
|
|
|
|
122 |
|
|
|
|
243 |
|
|
|
|
3 |
|
|
|
|
2 |
|
|
|
|
243 |
|
|
|
|
3 |
|
|
|
|
2 |
|
|
|
|
122 |
|
|
|
|
2 |
|
|
|
|
2 |
|
|
|
|
2 |
|
|
|
|
107 |
|
|
|
|
1 |
|
|
|
|
122 |
|
|
|
|
3 |
|
|
|
|
243 |
|
|
|
|
3 |
|
|
|
|
2 |
|
|
|
|
3 |
|
|
|
|
243 |
|
|
|
|
2 |
|
|
|
|
243 |
|
|
|
|
2 |
|
|
|
|
241 |
|
|
|
|
2 |
|
|
|
|
124 |
|
|
|
|
1 |
|
|
|
|
137 |
|
|
|
|
1 |
|
|
|
|
198 |
|
|
|
|
107 |
|
|
|
|
2 |
|
|
|
|
1 |
|
|
|
|
181 |
|
|
|
|
121 |
|
|
|
|
79 |
|
|
|
|
240 |
|
|
|
|
199 |
|
|
|
|
106 |
|
|
|
|
121 |
|
|
|
|
137 |
|
|
|
|
1 |
|
|
|
|
184 |
|
|
|
|
241 |
|
|
|
|
2 |
|
|
|
|
1 |
|
|
|
|
241 |
|
|
|
|
2 |
|
|
|
|
1 |
|
|
|
|
1 |
|
|
|
|
3 |
|
|
|
|
1 |
|
|
|
|
241 |
|
|
|
|
2 |
|
|
|
|
2 |
|
|
|
|
2 |
|
|
|
|
242 |
|
|
|
|
122 |
|
|
|
|
121 |
|
|
|
|
44 |
A.4. Conformance Class "Advanced Comparison Operators"
Conformance Class |
|
http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators |
|
Target type |
Servers that evaluate filter expressions |
Parameter |
Filter Language: "CQL2 Text" or "CQL2 JSON" |
Requirements class |
|
Dependency |
A.4.1. Conformance Test 10
Test id: |
/conf/advanced-comparison-operators/like |
---|---|
Requirements: |
|
Test purpose: |
Test LIKE predicate |
Test method: |
Given:
When: For each queryable
Then:
|
A.4.2. Conformance Test 11
Test id: |
/conf/advanced-comparison-operators/between |
---|---|
Requirements: |
|
Test purpose: |
Test BETWEEN predicate |
Test method: |
Given:
When: for each queryable
Then:
|
A.4.3. Conformance Test 12
Test id: |
/conf/advanced-comparison-operators/in |
---|---|
Requirements: |
|
Test purpose: |
Test IN predicate |
Test method: |
Given:
When:
Then:
|
A.4.4. Conformance Test 13
Test id: |
/conf/advanced-comparison-operators/test-data |
---|---|
Requirements: |
all requirements |
Test purpose: |
Test predicates against the test dataset |
Test method: |
Given:
When: Evaluate each predicate in Predicates and expected results. Then:
|
Data Source | Predicate | Expected number of items |
---|---|---|
ne_110m_populated_places_simple |
|
3 |
ne_110m_populated_places_simple |
|
240 |
ne_110m_populated_places_simple |
|
75 |
ne_110m_populated_places_simple |
|
168 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
241 |
ne_110m_populated_places_simple |
|
3 |
ne_110m_populated_places_simple |
|
240 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
2 |
A.4.5. Conformance Test 14
Test id: |
/conf/advanced-comparison-operators/logical |
---|---|
Requirements: |
n/a |
Test purpose: |
Test filter expressions with AND, OR and NOT including sub-expressions |
Test method: |
Given:
When: For each data source, select at least 10 random combinations of four predicates ( Then:
|
A.5. Conformance Class "Case-insensitive Comparison"
Conformance Class |
|
http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison |
|
Target type |
Servers that evaluate filter expressions |
Parameter |
Filter Language: "CQL2 Text" or "CQL2 JSON" |
Requirements class |
|
Dependency |
|
Conditional Dependency |
A.5.1. Conformance Test 15
Test id: |
/conf/case-insensitive-comparison/casei |
---|---|
Requirements: |
|
Test purpose: |
Test the CASEI function in comparisons |
Test method: |
Given:
When: For each queryable
Then:
|
A.5.2. Conformance Test 16
Test id: |
/conf/case-insensitive-comparison/casei-like |
---|---|
Requirements: |
|
Test purpose: |
Test the CASEI function in LIKE predicates |
Test method: |
Given:
When: For each queryable
Then:
|
A.5.3. Conformance Test 17
Test id: |
/conf/case-insensitive-comparison/test-data |
---|---|
Requirements: |
all requirements |
Test purpose: |
Test predicates against the test dataset |
Test method: |
Given:
When: Evaluate each predicate in Predicates and expected results, if the conditional dependency is met. Then:
|
Dependency | Data Source | Predicate | Expected number of items |
---|---|---|---|
n/a |
ne_110m_populated_places_simple |
|
1 |
n/a |
ne_110m_populated_places_simple |
|
1 |
n/a |
ne_110m_populated_places_simple |
|
1 |
n/a |
ne_110m_populated_places_simple |
|
1 |
n/a |
ne_110m_populated_places_simple |
|
1 |
n/a |
ne_110m_populated_places_simple |
|
1 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
3 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
3 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
3 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
3 |
A.5.4. Conformance Test 18
Test id: |
/conf/case-insensitive-comparison/logical |
---|---|
Requirements: |
n/a |
Test purpose: |
Test filter expressions with AND, OR and NOT including sub-expressions |
Test method: |
Given:
When: For each data source, select at least 10 random combinations of four predicates ( Then:
|
A.6. Conformance Class "Accent-insensitive Comparison"
Conformance Class |
|
http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison |
|
Target type |
Servers that evaluate filter expressions |
Parameter |
Filter Language: "CQL2 Text" or "CQL2 JSON" |
Requirements class |
|
Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
A.6.1. Conformance Test 19
Test id: |
/conf/accent-insensitive-comparison/accenti |
---|---|
Requirements: |
|
Test purpose: |
Test the ACCENTI function in comparisons |
Test method: |
Given:
When: For each queryable
Then:
|
A.6.2. Conformance Test 20
Test id: |
/conf/accent-insensitive-comparison/accenti-like |
---|---|
Requirements: |
|
Test purpose: |
Test the ACCENTI function in LIKE predicates |
Test method: |
Given:
When: For each queryable
Then:
|
A.6.3. Conformance Test 21
Test id: |
/conf/accent-insensitive-comparison/accenti-casei |
---|---|
Requirements: |
|
Test purpose: |
Test the ACCENTI function with the CASEI function |
Test method: |
Given:
When: For each queryable
Then:
|
A.6.4. Conformance Test 22
Test id: |
/conf/accent-insensitive-comparison/accenti-casei-like |
---|---|
Requirements: |
|
Test purpose: |
Test the ACCENTI function with the CASEI function in LIKE predicates |
Test method: |
Given:
When: For each queryable
Then:
|
A.6.5. Conformance Test 23
Test id: |
/conf/accent-insensitive-comparison/test-data |
---|---|
Requirements: |
all requirements |
Test purpose: |
Test predicates against the test dataset |
Test method: |
Given:
When: Evaluate each predicate in Predicates and expected results, if the conditional dependency is met. Then:
|
Dependency | Data Source | Predicate | Expected number of items |
---|---|---|---|
n/a |
ne_110m_populated_places_simple |
|
1 |
n/a |
ne_110m_populated_places_simple |
|
1 |
n/a |
ne_110m_populated_places_simple |
|
1 |
Case-insensitive Comparison |
ne_110m_populated_places_simple |
|
1 |
Case-insensitive Comparison |
ne_110m_populated_places_simple |
|
1 |
Case-insensitive Comparison |
ne_110m_populated_places_simple |
|
1 |
Case-insensitive Comparison |
ne_110m_populated_places_simple |
|
1 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
2 |
Case-insensitive Comparison, Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
2 |
Case-insensitive Comparison, Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
2 |
Case-insensitive Comparison, Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
4 |
A.6.6. Conformance Test 24
Test id: |
/conf/accent-insensitive-comparison/logical |
---|---|
Requirements: |
n/a |
Test purpose: |
Test filter expressions with AND, OR and NOT including sub-expressions |
Test method: |
Given:
When: For each data source, select at least 10 random combinations of four predicates ( Then:
|
A.7. Conformance Class "Basic Spatial Functions"
Conformance Class |
|
http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions |
|
Target type |
Servers that evaluate filter expressions |
Parameter |
Filter Language: "CQL2 Text" or "CQL2 JSON" |
Requirements class |
|
Dependency |
The term "geometry data type" is used for the following data types: Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, Geometry, or GeometryCollection.
A.7.1. Conformance Test 25
Test id: |
/conf/basic-spatial-functions/s_intersects |
---|---|
Requirements: |
|
Test purpose: |
Test the S_INTERSECTS spatial comparison function with points and bounding boxes. |
Test method: |
Given:
When: For each queryable
Then:
|
A.7.2. Conformance Test 26
Test id: |
/conf/basic-spatial-functions/test-data |
---|---|
Requirements: |
all requirements |
Test purpose: |
Test predicates against the test dataset |
Test method: |
Given:
When: Evaluate each predicate in Predicates and expected results. Then:
|
Data Source | Predicate | Expected number of items |
---|---|---|
ne_110m_admin_0_countries |
|
8 |
ne_110m_admin_0_countries |
|
10 |
ne_110m_admin_0_countries |
|
1 |
ne_110m_admin_0_countries |
|
3 |
ne_110m_admin_0_countries |
|
5 |
ne_110m_admin_0_countries |
|
10 |
ne_110m_populated_places_simple |
|
7 |
ne_110m_rivers_lake_centerlines |
|
4 |
A.7.3. Conformance Test 27
Test id: |
/conf/basic-spatial-functions/logical |
---|---|
Requirements: |
n/a |
Test purpose: |
Test filter expressions with AND, OR and NOT including sub-expressions |
Test method: |
Given:
When: For each data source, select at least 10 random combinations of four predicates ( Then:
|
A.8. Conformance Class "Basic Spatial Functions with additional Spatial Literals"
Conformance Class |
|
http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus |
|
Target type |
Servers that evaluate filter expressions |
Parameter |
Filter Language: "CQL2 Text" or "CQL2 JSON" |
Requirements class |
|
Dependency |
The term "geometry data type" is used for the following data types: Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, or GeometryCollection.
A.8.1. Conformance Test 28
Test id: |
/conf/basic-spatial-functions-plus/s_intersects |
---|---|
Requirements: |
|
Test purpose: |
Test the S_INTERSECTS spatial comparison function with points, multi-points, line strings, multi-line string, polygons, multi-polygons, geometry collections and bounding boxes. |
Test method: |
Given:
When: For each queryable
Then:
|
A.8.2. Conformance Test 29
Test id: |
/conf/basic-spatial-functions-plus/test-data |
---|---|
Requirements: |
all requirements |
Test purpose: |
Test predicates against the test dataset |
Test method: |
Given:
When: Evaluate each predicate in Predicates and expected results. Then:
|
Data Source | Predicate | Expected number of items |
---|---|---|
ne_110m_admin_0_countries |
|
2 |
ne_110m_admin_0_countries |
|
14 |
ne_110m_admin_0_countries |
|
8 |
ne_110m_admin_0_countries |
|
15 |
ne_110m_admin_0_countries |
|
8 |
ne_110m_admin_0_countries |
|
15 |
ne_110m_admin_0_countries |
|
3 |
A.9. Conformance Class "Spatial Functions"
Conformance Class |
|
Target type |
Servers that evaluate filter expressions |
Parameter |
Filter Language: "CQL2 Text" or "CQL2 JSON" |
Requirements class |
|
Dependency |
A.9.1. Conformance Test 30
Test id: |
/conf/spatial-functions/s_intersects |
---|---|
Requirements: |
|
Test purpose: |
Test the S_INTERSECTS spatial function |
Test method: |
Given:
When: For each queryable
Then:
|
A.9.2. Conformance Test 31
Test id: |
/conf/spatial-functions/s_disjoint |
---|---|
Requirements: |
|
Test purpose: |
Test the S_DISJOINT spatial function |
Test method: |
Given:
When: for each queryable
Then:
|
A.9.3. Conformance Test 32
Test id: |
/conf/spatial-functions/s_equals |
---|---|
Requirements: |
|
Test purpose: |
Test the S_EQUALS spatial function |
Test method: |
Given:
When: for each queryable
Then:
|
A.9.4. Conformance Test 33
Test id: |
/conf/spatial-functions/s_touches |
---|---|
Requirements: |
|
Test purpose: |
Test the S_TOUCHES spatial function |
Test method: |
Given:
When: for each queryable
Then:
|
A.9.5. Conformance Test 34
Test id: |
/conf/spatial-functions/s_crosses |
---|---|
Requirements: |
|
Test purpose: |
Test the S_CROSSES spatial function |
Test method: |
Given:
When: for each queryable
Then:
|
A.9.6. Conformance Test 35
Test id: |
/conf/spatial-functions/s_within |
---|---|
Requirements: |
|
Test purpose: |
Test the S_WITHIN spatial function |
Test method: |
Given:
When: for each queryable
Then:
|
A.9.7. Conformance Test 36
Test id: |
/conf/spatial-functions/s_contains |
---|---|
Requirements: |
|
Test purpose: |
Test the S_CONTAINS spatial function |
Test method: |
Given:
When: for each queryable
Then:
|
A.9.8. Conformance Test 37
Test id: |
/conf/spatial-functions/s_overlaps |
---|---|
Requirements: |
|
Test purpose: |
Test the S_OVERLAPS spatial function |
Test method: |
Given:
When:
Then:
|
A.9.9. Conformance Test 38
Test id: |
/conf/spatial-functions/test-data |
---|---|
Requirements: |
all requirements |
Test purpose: |
Test predicates against the test dataset |
Test method: |
Given:
When: Evaluate each predicate in Predicates and expected results. Then:
|
Data Source | Predicate | Expected number of items |
---|---|---|
ne_110m_admin_0_countries |
|
8 |
ne_110m_admin_0_countries |
|
4 |
ne_110m_populated_places_simple |
|
7 |
ne_110m_rivers_lake_centerlines |
|
2 |
ne_110m_admin_0_countries |
|
169 |
ne_110m_admin_0_countries |
|
169 |
ne_110m_admin_0_countries |
|
173 |
ne_110m_admin_0_countries |
|
176 |
ne_110m_populated_places_simple |
|
236 |
ne_110m_populated_places_simple |
|
236 |
ne_110m_rivers_lake_centerlines |
|
9 |
ne_110m_rivers_lake_centerlines |
|
11 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_admin_0_countries |
|
3 |
ne_110m_admin_0_countries |
|
3 |
ne_110m_admin_0_countries |
|
2 |
ne_110m_admin_0_countries |
|
3 |
ne_110m_rivers_lake_centerlines |
|
1 |
ne_110m_rivers_lake_centerlines |
|
2 |
ne_110m_admin_0_countries |
|
44 |
ne_110m_populated_places_simple |
|
74 |
ne_110m_rivers_lake_centerlines |
|
4 |
ne_110m_admin_0_countries |
|
1 |
ne_110m_admin_0_countries |
|
1 |
ne_110m_admin_0_countries |
|
1 |
ne_110m_admin_0_countries |
|
11 |
A.9.10. Conformance Test 39
Test id: |
/conf/spatial-functions/logical |
---|---|
Requirements: |
n/a |
Test purpose: |
Test filter expressions with AND, OR and NOT including sub-expressions |
Test method: |
Given:
When: For each data source, select at least 10 random combinations of four predicates ( Then:
|
A.10. Conformance Class "Temporal Functions"
Conformance Class |
|
http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions |
|
Target type |
Servers that evaluate filter expressions |
Parameter |
Filter Language: "CQL2 Text" or "CQL2 JSON" |
Requirements class |
|
Dependency |
The term "temporal data type" is used for the following data types: Timestamp, Date, or Interval.
A.10.1. Conformance Test 40
Test id: |
/conf/temporal-functions/temporal-functions-1 |
---|---|
Requirements: |
|
Test purpose: |
Test the T_AFTER, T_BEFORE, T_DISJOINT, T_EQUALS, T_INTERSECTS temporal comparison functions. |
Test method: |
Given:
When: For each queryable
For each queryable
Then:
|
A.10.2. Conformance Test 41
Test id: |
/conf/temporal-functions/temporal-functions-2 |
---|---|
Requirements: |
|
Test purpose: |
Test the temporal comparison functions with intervals |
Test method: |
Given:
When: For each pair of queryables
For each pair of queryables
Then:
|
A.10.3. Conformance Test 42
Test id: |
/conf/temporal-functions/test-data |
---|---|
Requirements: |
all requirements |
Test purpose: |
Test predicates against the test dataset |
Test method: |
Given:
When: Evaluate each predicate in Predicates and expected results. Then:
|
Data Source | Predicate | Expected number of items |
---|---|---|
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
0 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
0 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
0 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
0 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
2 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
1 |
ne_110m_populated_places_simple |
|
0 |
A.10.4. Conformance Test 43
Test id: |
/conf/temporal-functions/logical |
---|---|
Requirements: |
n/a |
Test purpose: |
Test filter expressions with AND, OR and NOT including sub-expressions |
Test method: |
Given:
When: For each data source, select at least 10 random combinations of four predicates ( Then:
|
A.11. Conformance Class "Array Functions"
Conformance Class |
|
Target type |
Servers that evaluate filter expressions |
Parameter |
Filter Language: "CQL2 Text" or "CQL2 JSON" |
Requirements class |
|
Dependency |
A.11.1. Conformance Test 44
Test id: |
/conf/array-functions/array-predicates |
---|---|
Requirements: |
|
Test purpose: |
Test the array comparison functions |
Test method: |
Given:
When: For each queryable
Then:
|
A.11.2. Conformance Test 45
Test id: |
/conf/array-functions/logical |
---|---|
Requirements: |
n/a |
Test purpose: |
Test filter expressions with AND, OR and NOT including sub-expressions |
Test method: |
Given:
When: For each data source, select at least 10 random combinations of four predicates ( Then:
|
A.12. Conformance Class "Property-Property Comparisons"
Conformance Class |
|
Target type |
Servers that evaluate filter expressions |
Parameter |
Filter Language: "CQL2 Text" or "CQL2 JSON" |
Requirements class |
|
Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
A.12.1. Conformance Test 46
Test id: |
/conf/property-property/comparison-value-property |
---|---|
Requirements: |
|
Test purpose: |
Test comparison predicates with properties on the right-hand side and values on the left-hand side |
Test method: |
Given:
When: For each queryable
where
Then:
|
A.12.2. Conformance Test 47
Test id: |
/conf/property-property/comparison-property-property |
---|---|
Requirements: |
|
Test purpose: |
Test comparison predicates with properties on both sides |
Test method: |
Given:
When: For each queryable
Then:
|
A.12.3. Conformance Test 48
Test id: |
/conf/property-property/comparison-value-value |
---|---|
Requirements: |
|
Test purpose: |
Test comparison predicates with values on both sides |
Test method: |
Given:
When: Evaluate the following filter expressions
for each
Then:
|
A.12.4. Conformance Test 49
Test id: |
/conf/property-property/test-data |
---|---|
Requirements: |
all requirements |
Test purpose: |
Test predicates against the test dataset |
Test method: |
Given:
When: Evaluate each predicate in Predicates and expected results, if the conditional dependency is met. Then:
|
Dependency | Data Source | Predicate | Expected number of items |
---|---|---|---|
n/a |
ne_110m_populated_places_simple |
|
1 |
n/a |
ne_110m_populated_places_simple |
|
137 |
n/a |
ne_110m_populated_places_simple |
|
136 |
n/a |
ne_110m_populated_places_simple |
|
107 |
n/a |
ne_110m_populated_places_simple |
|
106 |
n/a |
ne_110m_populated_places_simple |
|
242 |
n/a |
ne_110m_populated_places_simple |
|
230 |
n/a |
ne_110m_populated_places_simple |
|
243 |
n/a |
ne_110m_populated_places_simple |
|
13 |
n/a |
ne_110m_populated_places_simple |
|
230 |
n/a |
ne_110m_populated_places_simple |
|
0 |
n/a |
ne_110m_populated_places_simple |
|
13 |
n/a |
ne_110m_populated_places_simple |
|
1 |
n/a |
ne_110m_populated_places_simple |
|
123 |
n/a |
ne_110m_populated_places_simple |
|
122 |
n/a |
ne_110m_populated_places_simple |
|
121 |
n/a |
ne_110m_populated_places_simple |
|
120 |
n/a |
ne_110m_populated_places_simple |
|
242 |
n/a |
ne_110m_populated_places_simple |
|
27 |
n/a |
ne_110m_populated_places_simple |
|
243 |
n/a |
ne_110m_populated_places_simple |
|
216 |
n/a |
ne_110m_populated_places_simple |
|
27 |
n/a |
ne_110m_populated_places_simple |
|
0 |
n/a |
ne_110m_populated_places_simple |
|
216 |
n/a |
ne_110m_populated_places_simple |
|
0 |
n/a |
ne_110m_populated_places_simple |
|
3 |
n/a |
ne_110m_populated_places_simple |
|
3 |
n/a |
ne_110m_populated_places_simple |
|
0 |
n/a |
ne_110m_populated_places_simple |
|
0 |
n/a |
ne_110m_populated_places_simple |
|
3 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
243 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
0 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
94 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
149 |
Basic Spatial Functions |
ne_110m_admin_0_countries |
|
8 |
Basic Spatial Functions |
ne_110m_admin_0_countries |
|
10 |
Basic Spatial Functions |
ne_110m_admin_0_countries |
|
1 |
Basic Spatial Functions |
ne_110m_populated_places_simple |
|
7 |
Basic Spatial Functions |
ne_110m_rivers_lake_centerlines |
|
4 |
Spatial Functions |
ne_110m_admin_0_countries |
|
8 |
Spatial Functions |
ne_110m_admin_0_countries |
|
4 |
Spatial Functions |
ne_110m_populated_places_simple |
|
7 |
Spatial Functions |
ne_110m_rivers_lake_centerlines |
|
2 |
Spatial Functions |
ne_110m_admin_0_countries |
|
169 |
Spatial Functions |
ne_110m_admin_0_countries |
|
169 |
Spatial Functions |
ne_110m_admin_0_countries |
|
173 |
Spatial Functions |
ne_110m_admin_0_countries |
|
176 |
Spatial Functions |
ne_110m_populated_places_simple |
|
236 |
Spatial Functions |
ne_110m_populated_places_simple |
|
236 |
Spatial Functions |
ne_110m_rivers_lake_centerlines |
|
9 |
Spatial Functions |
ne_110m_rivers_lake_centerlines |
|
11 |
Spatial Functions |
ne_110m_populated_places_simple |
|
1 |
Spatial Functions |
ne_110m_admin_0_countries |
|
3 |
Spatial Functions |
ne_110m_admin_0_countries |
|
3 |
Spatial Functions |
ne_110m_admin_0_countries |
|
2 |
Spatial Functions |
ne_110m_admin_0_countries |
|
3 |
Spatial Functions |
ne_110m_rivers_lake_centerlines |
|
1 |
Spatial Functions |
ne_110m_rivers_lake_centerlines |
|
2 |
Spatial Functions |
ne_110m_admin_0_countries |
|
44 |
Spatial Functions |
ne_110m_populated_places_simple |
|
74 |
Spatial Functions |
ne_110m_rivers_lake_centerlines |
|
4 |
Spatial Functions |
ne_110m_admin_0_countries |
|
1 |
Spatial Functions |
ne_110m_admin_0_countries |
|
1 |
Spatial Functions |
ne_110m_admin_0_countries |
|
1 |
Spatial Functions |
ne_110m_admin_0_countries |
|
11 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
2 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
2 |
Temporal Functions |
ne_110m_populated_places_simple |
|
0 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
2 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
0 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
0 |
Temporal Functions |
ne_110m_populated_places_simple |
|
2 |
Temporal Functions |
ne_110m_populated_places_simple |
|
2 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
2 |
Temporal Functions |
ne_110m_populated_places_simple |
|
2 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
0 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
Temporal Functions |
ne_110m_populated_places_simple |
|
0 |
Temporal Functions |
ne_110m_populated_places_simple |
|
0 |
Temporal Functions |
ne_110m_populated_places_simple |
|
0 |
Temporal Functions |
ne_110m_populated_places_simple |
|
0 |
Temporal Functions |
ne_110m_populated_places_simple |
|
1 |
A.12.5. Conformance Test 50
Test id: |
/conf/property-property/logical |
---|---|
Requirements: |
n/a |
Test purpose: |
Test filter expressions with AND, OR and NOT including sub-expressions |
Test method: |
Given:
When: For each data source, select at least 10 random combinations of four predicates ( Then:
|
A.13. Conformance Class "Functions"
Conformance Class |
|
Target type |
Servers that evaluate filter expressions |
Parameter |
Filter Language: "CQL2 Text" or "CQL2 JSON" |
Requirements class |
|
Dependency |
A.13.1. Conformance Test 51
Test id: |
/conf/functions/functions |
---|---|
Requirements: |
|
Test purpose: |
Test predicates with functions |
Test method: |
Given:
When:
Then:
|
A.14. Conformance Class "Arithmetic Expressions"
Conformance Class |
|
Target type |
Servers that evaluate filter expressions |
Parameter |
Filter Language: "CQL2 Text" or "CQL2 JSON" |
Requirements class |
|
Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
A.14.1. Conformance Test 52
Test id: |
/conf/arithmetic/arithmetic |
---|---|
Requirements: |
|
Test purpose: |
Test predicates with arithmetic expressions |
Test method: |
Given:
When:
Then:
|
A.14.2. Conformance Test 53
Test id: |
/conf/arithmetic/test-data |
---|---|
Requirements: |
all requirements |
Test purpose: |
Test predicates against the test dataset |
Test method: |
Given:
When: Evaluate each predicate in Predicates and expected results, if the conditional dependency is met. Then:
|
Dependency | Data Source | Predicate | Expected number of items |
---|---|---|---|
n/a |
ne_110m_populated_places_simple |
|
1 |
n/a |
ne_110m_populated_places_simple |
|
123 |
n/a |
ne_110m_populated_places_simple |
|
122 |
n/a |
ne_110m_populated_places_simple |
|
122 |
n/a |
ne_110m_populated_places_simple |
|
122 |
n/a |
ne_110m_populated_places_simple |
|
121 |
n/a |
ne_110m_populated_places_simple |
|
120 |
n/a |
ne_110m_populated_places_simple |
|
242 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
75 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
168 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
3 |
Advanced Comparison Operators |
ne_110m_populated_places_simple |
|
240 |
Property-Property Comparisons |
ne_110m_populated_places_simple |
|
1 |
A.14.3. Conformance Test 54
Test id: |
/conf/arithmetic/logical |
---|---|
Requirements: |
n/a |
Test purpose: |
Test filter expressions with AND, OR and NOT including sub-expressions |
Test method: |
Given:
When: For each data source, select at least 10 random combinations of four predicates ( Then:
|
Annex B: CQL2 BNF (Normative)
Note
|
Because there are many variations of EBNF, this standard has focused on verifying that this grammar validates using the following online validator: If other tools are used (e.g. ANTLR), the grammar will likely need to be adapted to suit the target implementation context. |
#
# MODULE: cql2.bnf
# PURPOSE: A BNF grammar for the Common Query Language (CQL2).
# HISTORY:
# DATE EMAIL DESCRIPTION
# 13-SEP-2019 pvretano[at]cubewerx.com Initial creation
# 28-OCT-2019 pvretano[at]cubewerx.com Initial check-in into github
# 22-DEC-2020 pvretano[at]cubewerx.com 1.0.0-draft.1 (version for public review)
# portele[at]interactive-instruments.de
# 07-MAR-2024 pvretano[at]cubewerx.com 1.0.0-rc.1 (release candidate)
# portele[at]interactive-instruments.de
# 02-JUL-2024 pvretano[at]cubewerx.com 1.0.0 (final release)
# portele[at]interactive-instruments.de
#=============================================================================#
# A CQL2 filter is a logically connected expression of one or more predicates.
# Predicates include scalar or comparison predicates, spatial predicates or
# temporal predicates.
#
# *** DISCLAIMER: ***
# Because there are many variations of EBNF, this standard has focused
# on verifying that this grammar validates using the following online
# validator:
#
# https://www.icosaedro.it/bnf_chk/bnf_chk-on-line.html
#
# If other tools are used (e.g. ANTLR), the grammar will likely need to be
# adapted to suite the target implementation context.
#=============================================================================#
booleanExpression = booleanTerm [ {"OR" booleanTerm} ];
booleanTerm = booleanFactor [ {"AND" booleanFactor} ];
booleanFactor = ["NOT"] booleanPrimary;
booleanPrimary = function
| predicate
| booleanLiteral
| "(" booleanExpression ")";
predicate = comparisonPredicate
| spatialPredicate
| temporalPredicate
| arrayPredicate;
#=============================================================================#
# A comparison predicate evaluates if two scalar expression statisfy the
# specified comparison operator. The comparion operators includes an operator
# to evaluate pattern matching expressions (LIKE), a range evaluation operator
# and an operator to test if a scalar expression is NULL or not.
#=============================================================================#
comparisonPredicate = binaryComparisonPredicate
| isLikePredicate
| isBetweenPredicate
| isInListPredicate
| isNullPredicate;
# Binary comparison predicate
#
binaryComparisonPredicate = scalarExpression
comparisonOperator
scalarExpression;
scalarExpression = characterClause
| numericLiteral
| instantInstance
| arithmeticExpression
| booleanLiteral
| propertyName
| function;
comparisonOperator = "=" # equal
| "<" ">" # not equal
| "<" # less than
| ">" # greater than
| "<" "=" # less than or equal
| ">" "="; # greater than or equal
# LIKE predicate
#
isLikePredicate = characterExpression ["NOT"] "LIKE" patternExpression;
patternExpression = "CASEI" "(" patternExpression ")"
| "ACCENTI" "(" patternExpression ")"
| characterLiteral;
# BETWEEN predicate
#
isBetweenPredicate = numericExpression ["NOT"] "BETWEEN"
numericExpression "AND" numericExpression;
numericExpression = arithmeticExpression
| numericLiteral
| propertyName
| function;
# IN LIST predicate
#
isInListPredicate = scalarExpression ["NOT"] "IN" "(" inList ")";
inList = scalarExpression [ {"," scalarExpression} ];
# IS NULL predicate
#
isNullPredicate = isNullOperand "IS" ["NOT"] "NULL";
isNullOperand = characterClause
| numericLiteral
| temporalInstance
| spatialInstance
| arithmeticExpression
| booleanExpression
| propertyName
| function;
#=============================================================================#
# A spatial predicate evaluates if two spatial expressions satisfy the
# condition implied by a standardized spatial comparison function. If the
# conditions of the spatial comparison function are met, the function returns
# a Boolean value of true. Otherwise the function returns false.
#=============================================================================#
spatialPredicate = spatialFunction "(" geomExpression "," geomExpression ")";
# NOTE: The buffer functions (DWITHIN and BEYOND) are not included because
# these are outside the scope of a "simple" core for CQL2. These
# can be added as extensions.
#
spatialFunction = "S_INTERSECTS"
| "S_EQUALS"
| "S_DISJOINT"
| "S_TOUCHES"
| "S_WITHIN"
| "S_OVERLAPS"
| "S_CROSSES"
| "S_CONTAINS";
# A geometric expression is a property name of a geometry-valued property,
# a geometric literal (expressed as WKT) or a function that returns a
# geometric value.
#
geomExpression = spatialInstance
| propertyName
| function;
#=============================================================================#
# A temporal predicate evaluates if two temporal expressions satisfy the
# condition implied by a standardized temporal comparison function. If the
# conditions of the temporal comparison function are met, the function returns
# a Boolean value of true. Otherwise the function returns false.
#=============================================================================#
temporalPredicate = temporalFunction
"(" temporalExpression "," temporalExpression ")";
temporalExpression = temporalInstance
| propertyName
| function;
temporalFunction = "T_AFTER"
| "T_BEFORE"
| "T_CONTAINS"
| "T_DISJOINT"
| "T_DURING"
| "T_EQUALS"
| "T_FINISHEDBY"
| "T_FINISHES"
| "T_INTERSECTS"
| "T_MEETS"
| "T_METBY"
| "T_OVERLAPPEDBY"
| "T_OVERLAPS"
| "T_STARTEDBY"
| "T_STARTS";
#=============================================================================#
# An array predicate evaluates if two array expressions satisfy the
# condition implied by a standardized array comparison function. If the
# conditions of the array comparison function are met, the function returns
# a Boolean value of true. Otherwise the function returns false.
#=============================================================================#
arrayPredicate = arrayFunction
"(" arrayExpression "," arrayExpression ")";
arrayExpression = array
| propertyName
| function;
# An array is a parentheses-delimited, comma-separated list of array
# elements.
array = "(" ")"
| "(" arrayElement [ { "," arrayElement } ] ")";
# An array element is either a character literal, a numeric literal,
# a geometric literal, a temporal instance, a property name, a function,
# an arithmetic expression or an array.
arrayElement = characterClause
| numericLiteral
| temporalInstance
| spatialInstance
| array
| arithmeticExpression
| booleanExpression
| propertyName
| function;
arrayFunction = "A_EQUALS"
| "A_CONTAINS"
| "A_CONTAINEDBY"
| "A_OVERLAPS";
#=============================================================================#
# An arithmetic expression is an expression composed of an arithmetic
# operand (a property name, a number or a function that returns a number),
# an arithmetic operators (+,-,*,/,%,div,^) and another arithmetic operand.
#=============================================================================#
arithmeticExpression = arithmeticTerm [ {arithmeticOperatorPlusMinus arithmeticTerm} ];
arithmeticOperatorPlusMinus = "+" | "-";
arithmeticTerm = powerTerm [ {arithmeticOperatorMultDiv powerTerm} ];
arithmeticOperatorMultDiv = "*" | "/" | "%" | "div";
powerTerm = arithmeticFactor [ "^" arithmeticFactor ];
arithmeticFactor = "(" arithmeticExpression ")"
| [ "-" ] arithmeticOperand;
arithmeticOperand = numericLiteral
| propertyName
| function;
#=============================================================================#
# Definition of a PROPERTYNAME
# Production copied from: https://www.w3.org/TR/REC-xml/#sec-common-syn,
# "Names and Tokens".
#=============================================================================#
propertyName = identifier | "\"" identifier "\"";
identifier = identifierStart [ { identifierPart } ];
identifierPart = identifierStart
| "." # "\x002E"
| digit # 0-9
| "\x0300".."\x036F" # combining and diacritical marks
| "\x203F".."\x2040"; # ‿ and ⁀
identifierStart = "\x003A" # colon
| "\x005F" # underscore
| "\x0041".."\x005A" # A-Z
| "\x0061".."\x007A" # a-z
| "\x00C0".."\x00D6" # À-Ö Latin-1 Supplement Letters
| "\x00D8".."\x00F6" # Ø-ö Latin-1 Supplement Letters
| "\x00F8".."\x02FF" # ø-ÿ Latin-1 Supplement Letters
| "\x0370".."\x037D" # Ͱ-ͽ Greek and Coptic (without ";")
| "\x037F".."\x1FFE" # See note 1.
| "\x200C".."\x200D" # zero width non-joiner and joiner
| "\x2070".."\x218F" # See note 2.
| "\x2C00".."\x2FEF" # See note 3.
| "\x3001".."\xD7FF" # See note 4.
| "\xF900".."\xFDCF" # See note 5.
| "\xFDF0".."\xFFFD" # See note 6.
| "\x10000".."\xEFFFF"; # See note 7.
# See: https://unicode-table.com/en/blocks/
# Note 1: Greek, Coptic, Cyrillic, Cyrillic Supplement, Armenian, Hebrew,
# Arabic, Syriac, Arabic Supplement, Thaana, NKo, Samaritan, Mandaic,
# Syriac Supplement, Arabic Extended-A, Devanagari, Bengali, Gurmukhi,
# Gujarati, Oriya, Tamil, Telugu, Kannada, Malayalam, Sinhala, Thai,
# Lao, Tibetan, Myanmar, Georgian, Hangul Jamo, Ethiopic, Ethiopic
# Supplement, Cherokee, Unified Canadian Aboriginal Syllabics, Ogham,
# Runic, Tagalog, Hanunoo, Buhid, Tagbanwa, Khmer, Mongolian, Unified
# Canadian Aboriginal Syllabics Extended, Limbu, Tai Le, New Tai Lue,
# Khmer Symbols, Buginese, Tai Tham, Combining Diacritical Marks
# Extended, Balinese, Sundanese, Batak, Lepcha, Ol Chiki, Cyrillic
# Extended C, Georgian Extended, Sundanese Supplement, Vedic
# Extensions, Phonetic Extensions, Phonetic Extensions Supplement,
# Combining Diacritical Marks Supplement, Latin Extended Additional,
# Greek Extended
#
# Note 2: Superscripts and Subscripts, Currency Symbols, Combining Diacritical
# Marks for Symbols, Letterlike Symbols, Number Forms (e.g. Roman
# numbers)
#
# Note 3: Glagolitic, Latin Extended-C, Coptic, Georgian Supplement, Tifinagh,
# Ethiopic Extended, Cyrillic Extended-A, Supplemental Punctuation,
# CJK Radicals Supplement, Kangxi Radicals
#
# Note 4: CJK Symbols and Punctuation Hiragana, Katakana, Bopomofo, Hangul
# Compatibility Jamo, Kanbun, Bopomofo Extended, CJK Strokes, Katakana
# Phonetic Extensions, Enclosed CJK Letters and Months, CJK
# Compatibility, CJK Unified Ideographs Extension A, Yijing Hexagram
# Symbols, CJK Unified Ideographs, Yi Syllables, Yi Radicals, Lisu,
# Vai, Cyrillic Extended-B, Bamum, Modifier Tone Letters, Latin
# Extended-D, Syloti Nagri, Common Indic Number Forms, Phags-pa,
# Saurashtra, Devanagari Extended, Kayah Li, Rejang, Hangul Jamo
# Extended-A, Javanese, Myanmar Extended-B, Cham, Myanmar Extended-A,
# Tai Viet, Meetei Mayek Extensions, Ethiopic Extended-A, Latin
# Extended-E, Cherokee Supplement, Meetei Mayek, Hangul Syllables,
# Hangul Jamo Extended-B
#
# Note 5: CJK Compatibility Ideographs, Alphabetic Presentation Forms,
# Arabic Presentation Forms-A
#
# Note 6: Arabic Presentation Forms-A, Variation Selectors, Vertical Forms,
# Combining Half Marks, CJK Compatibility Forms, Small Form Variants,
# Arabic Presentation Forms-B, Halfwidth and Fullwidth Forms, Specials
#
# Note 7: Linear B Syllabary, Linear B Ideograms, Aegean Numbers, Ancient
# Greek Numbers, Ancient Symbols, Phaistos Disc, Lycian, Carian,
# Coptic Epact Numbers, Old Italic, Gothic, Old Permic, Ugaritic, Old
# Persian, Deseret, Shavian, Osmanya, Osage, Elbasan, Caucasian
# Albanian, Linear A, Cypriot Syllabary, Imperial Aramaic, Palmyrene,
# Nabataean, Hatran, Phoenician, Lydian, Meroitic Hieroglyphs,
# Meroitic Cursive, Kharoshthi, Old South Arabian, Old North Arabian,
# Manichaean, Avestan, Inscriptional Parthian, Inscriptional Pahlavi,
# Psalter Pahlavi, Old Turkic, Old Hungarian, Hanifi Rohingya, Rumi
# Numeral Symbols, Yezidi, Old Sogdian, Sogdian, Chorasmian, Elymaic,
# Brahmi, Kaithi, Sora Sompeng, Chakma, Mahajani, Sharada, Sinhala
# Archaic Numbers, Khojki, Multani, Khudawadi, Grantha, Newa, Tirhuta,
# Siddham, Modi, Mongolian Supplement, Takri, Ahom, Dogra, Warang Citi,
# Dives Akuru, Nandinagari, Zanabazar Square, Soyombo, Pau Cin Hau,
# Bhaiksuki, Marchen, Masaram Gondi, Gunjala Gondi, Makasar, Lisu
# Supplement, Tamil Supplement, Cuneiform, Cuneiform Numbers and
# Punctuation, Early Dynastic Cuneiform, Egyptian Hieroglyphs,
# Egyptian Hieroglyph Format Controls, Anatolian Hieroglyphs,Bamum
# Supplement, Mro, Bassa Vah, Pahawh Hmong, Medefaidrin, Miao,
# Ideographic Symbols and Punctuation, Tangut, Tangut Components,
# Khitan Small Script, Tangut Supplement, Kana Supplement, Kana
# Extended-A, Small Kana Extension, Nushu, Duployan, Shorthand Format
# Controls, Byzantine Musical Symbols, Musical Symbols, Ancient Greek
# Musical Notation, Mayan Numerals, Tai Xuan Jing Symbols, Counting
# Rod Numerals, Mathematical Alphanumeric Symbols, Sutton SignWriting,
# Glagolitic Supplement, Nyiakeng Puachue Hmong, Wancho, Mende Kikakui,
# Adlam, Indic Siyaq Numbers, Ottoman Siyaq Numbers, Arabic
# Mathematical Alphabetic Symbols, Mahjong Tiles, Domino Tiles,
# Playing Cards, Enclosed Alphanumeric Supplement, Enclosed Ideographic
# Supplement, Miscellaneous Symbols and Pictographs, Emoticons (Emoji),
# Ornamental Dingbats, Transport and Map Symbols, Alchemical Symbols,
# Geometric Shapes Extended, Supplemental Arrows-C, Supplemental
# Symbols and Pictographs, Chess Symbols, Symbols and Pictographs
# Extended-A, Symbols for Legacy Computing, CJK Unified Ideographs
# Extension B, CJK Unified Ideographs Extension C, CJK Unified
# Ideographs Extension D, CJK Unified Ideographs Extension E, CJK
# Unified Ideographs Extension F, CJK Compatibility Ideographs
# Supplement, CJK Unified Ideographs Extension G, Tags, Variation
# Selectors Supplement
#=============================================================================#
# Definition of a FUNCTION
#=============================================================================#
function = identifier "(" {argumentList} ")";
argumentList = argument [ { "," argument } ];
argument = characterClause
| numericLiteral
| temporalInstance
| spatialInstance
| array
| arithmeticExpression
| booleanExpression
| propertyName
| function;
#=============================================================================#
# Character expression
#=============================================================================#
characterExpression = characterClause
| propertyName
| function;
characterClause = "CASEI" "(" characterExpression ")"
| "ACCENTI" "(" characterExpression ")"
| characterLiteral;
#=============================================================================#
# Definition of CHARACTER literals
#=============================================================================#
characterLiteral = "'" [ {character} ] "'";
character = alpha | digit | whitespace | escapeQuote;
escapeQuote = "''" | "\\'";
# character & digit productions copied from:
# https://www.w3.org/TR/REC-xml/#charsets
#
alpha = "\x0007".."\x0008" # bell, bs
| "\x0021".."\x0026" # !, ", #, $, %, &
| "\x0028".."\x002F" # (, ), *, +, comma, -, ., /
| "\x003A".."\x0084" # --+
| "\x0086".."\x009F" # |
| "\x00A1".."\x167F" # |
| "\x1681".."\x1FFF" # |
| "\x200B".."\x2027" # +-> :,;,<,=,>,?,@,A-Z,[,\,],^,_,`,a-z,...
| "\x202A".."\x202E" # |
| "\x2030".."\x205E" # |
| "\x2060".."\x2FFF" # |
| "\x3001".."\xD7FF" # --+
| "\xE000".."\xFFFD" # See note 8.
| "\x10000".."\x10FFFF"; # See note 9.
# Note 8: Private Use, CJK Compatibility Ideographs, Alphabetic Presentation
# Forms, Arabic Presentation Forms-A, Combining Half Marks, CJK
# Compatibility Forms, Small Form Variants, Arabic Presentation Forms-B,
# Specials, Halfwidth and Fullwidth Forms, Specials
# Note 9: Linear B Syllabary, Linear B Ideograms, Aegean Numbers, Ancient Greek
# Numbers, Ancient Symbols, Phaistos Disc, Lycian, Carian, Coptic
# Epact Numbers, Old Italic, Gothic, Old Permic, Ugaritic, Old Persian,
# Deseret, Shavian, Osmanya, Osage, Elbasan, Caucasian Albanian,
# Vithkuqi, Linear A, Latin Extended-F, Cypriot Syllabary, Imperial
# Aramaic, Palmyrene, Nabataean, Hatran, Phoenician, Lydian, Meroitic
# Hieroglyphs, Meroitic Cursive, Kharoshthi, Old South Arabian, Old
# North Arabian, Manichaean, Avestan, Inscriptional Parthian,
# Inscriptional Pahlavi, Psalter Pahlavi, Old Turkic, Old Hungarian,
# Hanifi Rohingya, Rumi Numeral Symbols, Yezidi, Arabic Extended-C,
# Old Sogdian, Sogdian, Old Uyghur, Chorasmian, Elymaic, Brahmi,
# Kaithi, Sora Sompeng, Chakma, Mahajani, Sharada, Sinhala Archaic
# Numbers, Khojki, Multani, Khudawadi, Grantha, Newa, Tirhuta, Siddham,
# Modi, Mongolian Supplement, Takri, Ahom, Dogra, Warang Citi, Dives
# Akuru, Nandinagari, Zanabazar Square, Soyombo, Unified Canadian
# Aboriginal Syllabics Extended-A, Pau Cin Hau, Devanagari Extended-A,
# Bhaiksuki, Marchen, Masaram Gondi, Gunjala Gondi, Makasar, Kawi,
# Lisu Supplement, Tamil Supplement, Cuneiform, Cuneiform Numbers and
# Punctuation, Early Dynastic Cuneiform, Cypro-Minoan, Egyptian
# Hieroglyphs, Egyptian Hieroglyph Format Controls, Anatolian
# Hieroglyphs, Bamum Supplement, Mro, Tangsa, Bassa Vah, Pahawh Hmong,
# Medefaidrin, Miao, Ideographic Symbols and Punctuation, Tangut,
# Tangut Components, Khitan Small Script, Tangut Supplement, Kana
# Extended-B, Kana Supplement, Kana Extended-A, Small Kana Extension,
# Nushu, Duployan, Shorthand Format Controls, Znamenny Musical Notation,
# Byzantine Musical Symbols, Musical Symbols, Ancient Greek Musical
# Notation, Kaktovik Numerals, Mayan Numerals, Tai Xuan Jing Symbols,
# Counting Rod Numerals, Mathematical Alphanumeric Symbols, Sutton
# SignWriting, Latin Extended-G, Glagolitic Supplement, Cyrillic
# Extended-D, Nyiakeng Puachue Hmong, Toto, Wancho, Nag Mundari,
# Ethiopic Extended-B, Mende Kikakui, Adlam, Indic Siyaq Numbers,
# Ottoman Siyaq Numbers, Arabic Mathematical Alphabetic Symbols,
# Mahjong Tiles, Domino Tiles, Playing Cards, Enclosed Alphanumeric
# Supplement, Enclosed Ideographic Supplement, Miscellaneous Symbols
# and Pictographs, Emoticons, Ornamental Dingbats, Transport and Map
# Symbols, Alchemical Symbols, Geometric Shapes Extended, Supplemental
# Arrows-C, Supplemental Symbols and Pictographs, Chess Symbols, Symbols
# and Pictographs Extended-A, Symbols for Legacy Computing, CJK Unified
# Ideographs Extension B, CJK Unified Ideographs Extension C, CJK
# Unified Ideographs Extension D, CJK Unified Ideographs Extension E,
# CJK Unified Ideographs Extension F, CJK Compatibility Ideographs
# Supplement, CJK Unified Ideographs Extension G, CJK Unified
# Ideographs Extension H, Tags, Variation Selectors Supplement,
# Supplementary Private Use Area-A, Supplementary Private Use Area-B
digit = "\x0030".."\x0039";
whitespace = "\x0009" # Character tabulation
| "\x000A" # Line feed
| "\x000B" # Line tabulation
| "\x000C" # Form feed
| "\x000D" # Carriage return
| "\x0020" # Space
| "\x0085" # Next line
| "\x00A0" # No-break space
| "\x1680" # Ogham space mark
| "\x2000" # En quad
| "\x2001" # Em quad
| "\x2002" # En space
| "\x2003" # Em space
| "\x2004" # Three-per-em space
| "\x2005" # Four-per-em space
| "\x2006" # Six-per-em space
| "\x2007" # Figure space
| "\x2008" # Punctuation space
| "\x2009" # Thin space
| "\x200A" # Hair space
| "\x2028" # Line separator
| "\x2029" # Paragraph separator
| "\x202F" # Narrow no-break space
| "\x205F" # Medium mathematical space
| "\x3000"; # Ideographic space
#=============================================================================#
# Definition of NUMERIC literals
#=============================================================================#
numericLiteral = unsignedNumericLiteral | signedNumericLiteral;
unsignedNumericLiteral = decimalNumericLiteral | scientificNumericLiteral;
signedNumericLiteral = [sign] unsignedNumericLiteral;
decimalNumericLiteral = unsignedInteger [ "." [ unsignedInteger ] ]
| "." unsignedInteger;
scientificNumericLiteral = mantissa "E" exponent;
mantissa = decimalNumericLiteral;
exponent = signedInteger;
signedInteger = [ sign ] unsignedInteger;
unsignedInteger = {digit};
sign = "+" | "-";
#=============================================================================#
# Boolean literal
#=============================================================================#
#
booleanLiteral = "TRUE" | "FALSE";
#=============================================================================#
# Definition of GEOMETRIC literals
#
# NOTE: This is basically BNF that define WKT encoding. It would be nice
# to instead reference some normative BNF for WKT.
#=============================================================================#
spatialInstance = geometryLiteral
| geometryCollectionTaggedText
| bboxTaggedText;
geometryLiteral = pointTaggedText
| linestringTaggedText
| polygonTaggedText
| multipointTaggedText
| multilinestringTaggedText
| multipolygonTaggedText;
pointTaggedText = "POINT" ["Z"] pointText;
linestringTaggedText = "LINESTRING" ["Z"] lineStringText;
polygonTaggedText = "POLYGON" ["Z"] polygonText;
multipointTaggedText = "MULTIPOINT" ["Z"] multiPointText;
multilinestringTaggedText = "MULTILINESTRING" ["Z"] multiLineStringText;
multipolygonTaggedText = "MULTIPOLYGON" ["Z"] multiPolygonText;
geometryCollectionTaggedText = "GEOMETRYCOLLECTION" ["Z"] geometryCollectionText;
pointText = "(" point ")";
point = xCoord yCoord [zCoord];
xCoord = signedNumericLiteral;
yCoord = signedNumericLiteral;
zCoord = signedNumericLiteral;
lineStringText = "(" point "," point {"," point} ")";
linearRingText = emptySet | "(" point "," point "," point "," point {"," point } ")";
polygonText = "(" linearRingText {"," linearRingText} ")";
multiPointText = "(" pointText {"," pointText} ")";
multiLineStringText = "(" lineStringText {"," lineStringText} ")";
multiPolygonText = "(" polygonText {"," polygonText} ")";
geometryCollectionText = "(" geometryLiteral {"," geometryLiteral} ")";
bboxTaggedText = "BBOX" bboxText;
bboxText = "(" westBoundLon "," southBoundLat "," [minElev ","] eastBoundLon "," northBoundLat ["," maxElev] ")";
westBoundLon = signedNumericLiteral;
eastBoundLon = signedNumericLiteral;
northBoundLat = signedNumericLiteral;
southBoundLat = signedNumericLiteral;
minElev = signedNumericLiteral;
maxElev = signedNumericLiteral;
temporalInstance = instantInstance | intervalInstance;
instantInstance = dateInstant | timestampInstant;
dateInstant = "DATE"
"(" dateInstantString ")";
dateInstantString = "'" fullDate "'";
timestampInstant = "TIMESTAMP"
"(" timestampInstantString ")";
timestampInstantString = "'" fullDate "T" utcTime "'";
intervalInstance = "INTERVAL" "(" instantParameter "," instantParameter ")";
instantParameter = dateInstantString
| timestampInstantString
| "'..'"
| propertyName
| function;
fullDate = dateYear "-" dateMonth "-" dateDay;
dateYear = digit digit digit digit;
dateMonth = digit digit;
dateDay = digit digit;
utcTime = timeHour ":" timeMinute ":" timeSecond "Z";
timeHour = digit digit;
timeMinute = digit digit;
timeSecond = digit digit ["." digit {digit}];
Annex C: JSON schemas for CQL2 (Normative)
C.1. JSON Schema for CQL2
The following document specifies the schema for CQL2 according to JSON Schema version '2020-12':
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$dynamicAnchor": "cql2expression",
"oneOf": [
{"$ref": "#/$defs/andOrExpression" },
{"$ref": "#/$defs/notExpression" },
{"$ref": "#/$defs/comparisonPredicate"},
{"$ref": "#/$defs/spatialPredicate" },
{"$ref": "#/$defs/temporalPredicate" },
{"$ref": "#/$defs/arrayPredicate" },
{"$ref": "#/$defs/functionRef" },
{"type": "boolean" }
],
"$defs": {
"andOrExpression": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op": { "type": "string", "enum": ["and", "or"] },
"args": {
"type": "array",
"minItems": 2,
"items": {"$dynamicRef": "#cql2expression"}
}
}
},
"notExpression": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op": { "type": "string", "enum": ["not"] },
"args": {
"type": "array",
"minItems": 1,
"maxItems": 1,
"items": {"$dynamicRef": "#cql2expression"}
}
}
},
"comparisonPredicate": {
"oneOf": [
{"$ref": "#/$defs/binaryComparisonPredicate"},
{"$ref": "#/$defs/isLikePredicate" },
{"$ref": "#/$defs/isBetweenPredicate" },
{"$ref": "#/$defs/isInListPredicate" },
{"$ref": "#/$defs/isNullPredicate" }
]
},
"binaryComparisonPredicate": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op": { "type": "string", "enum": ["=", "<>", "<", ">", "<=", ">="] },
"args": {"$ref": "#/$defs/scalarOperands"}
}
},
"scalarOperands": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {"$ref": "#/$defs/scalarExpression"}
},
"scalarExpression": {
"oneOf": [
{"$ref": "#/$defs/characterExpression"},
{"$ref": "#/$defs/numericExpression"} ,
{"type": "boolean"} ,
{"$ref": "#/$defs/instantInstance"} ,
{"$ref": "#/$defs/functionRef"},
{"$ref": "#/$defs/propertyRef"}
]
},
"isLikePredicate": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op" : { "type": "string", "enum": ["like"] },
"args": {"$ref": "#/$defs/isLikeOperands"}
}
},
"isLikeOperands": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"prefixItems": [
{
"oneOf": [
{"$ref": "#/$defs/characterExpression"},
{"$ref": "#/$defs/propertyRef" },
{"$ref": "#/$defs/functionRef" }
]
},
{"$ref": "#/$defs/patternExpression"}
]
},
"patternExpression": {
"oneOf": [
{
"type": "object",
"required": ["op", "args"],
"properties": {
"op": { "type": "string", "enum": ["casei"] },
"args": {
"type": "array",
"items": {"$ref": "#/$defs/patternExpression"},
"minItems": 1,
"maxItems": 1
}
}
},
{
"type": "object",
"required": ["op", "args"],
"properties": {
"op": { "type": "string", "enum": ["accenti"] },
"args": {
"type": "array",
"items": {"$ref": "#/$defs/patternExpression"},
"minItems": 1,
"maxItems": 1
}
}
},
{"type": "string"}
]
},
"isBetweenPredicate": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op" : { "type": "string", "enum": ["between"] },
"args": {"$ref": "#/$defs/isBetweenOperands"}
}
},
"isBetweenOperands": {
"type": "array",
"minItems": 3,
"maxItems": 3,
"items": {
"oneOf": [
{"$ref": "#/$defs/numericExpression"},
{"$ref": "#/$defs/propertyRef" },
{"$ref": "#/$defs/functionRef" }
]
}
},
"numericExpression": {
"oneOf": [ {"$ref": "#/$defs/arithmeticExpression"}, {"type": "number"} ]
},
"isInListPredicate": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op" : { "type": "string", "enum": ["in"] },
"args": {"$ref": "#/$defs/inListOperands"}
}
},
"inListOperands": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"prefixItems": [
{"$ref": "#/$defs/scalarExpression"} ,
{ "type": "array", "items": {"$ref": "#/$defs/scalarExpression"} }
]
},
"isNullPredicate": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op" : { "type": "string", "enum": ["isNull"] },
"args": {"$ref": "#/$defs/isNullOperand"}
}
},
"isNullOperand": {
"type": "array",
"minItems": 1,
"maxItems": 1,
"items": {
"oneOf": [
{"$ref": "#/$defs/characterExpression"},
{"$ref": "#/$defs/numericExpression"} ,
{"$dynamicRef": "#cql2expression"} ,
{"$ref": "#/$defs/spatialInstance"} ,
{"$ref": "#/$defs/temporalInstance"} ,
{"$ref": "#/$defs/propertyRef"}
]
}
},
"spatialPredicate": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op": {
"type": "string",
"enum": [
"s_contains" , "s_crosses" , "s_disjoint" , "s_equals" ,
"s_intersects", "s_overlaps" , "s_touches" , "s_within"
]
},
"args": {"$ref": "#/$defs/spatialOperands"}
}
},
"spatialOperands": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"oneOf": [
{"$ref": "#/$defs/spatialInstance"},
{"$ref": "#/$defs/propertyRef" },
{"$ref": "#/$defs/functionRef" }
]
}
},
"temporalPredicate": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op": {
"type": "string",
"enum": [
"t_after" , "t_before" , "t_contains" ,
"t_disjoint" , "t_during" , "t_equals" ,
"t_finishedBy" , "t_finishes" , "t_intersects" ,
"t_meets" , "t_metBy" , "t_overlappedBy",
"t_overlaps" , "t_startedBy" , "t_starts"
]
},
"args": {"$ref": "#/$defs/temporalOperands"}
}
},
"temporalOperands": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"oneOf": [
{"$ref": "#/$defs/temporalInstance"},
{"$ref": "#/$defs/propertyRef" },
{"$ref": "#/$defs/functionRef" }
]
}
},
"arrayPredicate": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op": {
"type": "string",
"enum": ["a_containedBy", "a_contains", "a_equals", "a_overlaps"]
},
"args": {"$ref": "#/$defs/arrayExpression"}
}
},
"arrayExpression": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"oneOf": [
{"$ref": "#/$defs/array" },
{"$ref": "#/$defs/propertyRef"},
{"$ref": "#/$defs/functionRef"}
]
}
},
"array": {
"type": "array",
"items": {
"oneOf": [
{"$ref": "#/$defs/characterExpression"},
{"$ref": "#/$defs/numericExpression"} ,
{"$dynamicRef": "#cql2expression"} ,
{"$ref": "#/$defs/spatialInstance"} ,
{"$ref": "#/$defs/temporalInstance"} ,
{"$ref": "#/$defs/array"} ,
{"$ref": "#/$defs/propertyRef"}
]
}
},
"arithmeticExpression": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op": {
"type": "string",
"enum": ["+", "-", "*", "/", "^", "%", "div"]
},
"args": {"$ref": "#/$defs/arithmeticOperands"}
}
},
"arithmeticOperands": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"oneOf": [
{"$ref": "#/$defs/arithmeticExpression" },
{"$ref": "#/$defs/propertyRef" },
{"$ref": "#/$defs/functionRef" },
{ "type": "number"}
]
}
},
"propertyRef": {
"type": "object",
"required": ["property"],
"properties": { "property": {"type": "string"} }
},
"casei": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op": { "type": "string", "enum": ["casei"] },
"args": {
"type": "array",
"items": {
"oneOf": [
{"$ref": "#/$defs/characterExpression"},
{"$ref": "#/$defs/propertyRef" },
{"$ref": "#/$defs/functionRef" }
]
},
"minItems": 1,
"maxItems": 1
}
}
},
"accenti": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op": { "type": "string", "enum": ["accenti"] },
"args": {
"type": "array",
"items": {
"oneOf": [
{"$ref": "#/$defs/characterExpression"},
{"$ref": "#/$defs/propertyRef" },
{"$ref": "#/$defs/functionRef" }
]
},
"minItems": 1,
"maxItems": 1
}
}
},
"characterExpression": {
"oneOf": [
{"$ref": "#/$defs/casei" },
{"$ref": "#/$defs/accenti" },
{ "type": "string"}
]
},
"functionRef": {
"type": "object",
"required": ["op", "args"],
"properties": {
"op": {
"type": "string",
"not": {
"enum": [
"and" , "or" , "not" ,
"=" , "<>" , "<" ,
">" , "<=" , ">=" ,
"like" , "between" , "in" ,
"isNull" , "casei" , "accenti" ,
"s_contains" , "s_crosses" , "s_disjoint" ,
"s_equals" , "s_intersects" , "s_overlaps" ,
"s_touches" , "s_within" , "t_after" ,
"t_before" , "t_contains" , "t_disjoint" ,
"t_during" , "t_equals" , "t_finishedBy" ,
"t_finishes" , "t_intersects" , "t_meets" ,
"t_metBy" , "t_overlappedBy", "t_overlaps" ,
"t_startedBy" , "t_starts" , "a_containedBy" ,
"a_contains" , "a_equals" , "a_overlaps" ,
"+" , "-" , "*" ,
"/" , "^" , "%" ,
"div"
]
}
},
"args": {
"type": "array",
"items": {
"oneOf": [
{"$ref": "#/$defs/characterExpression"},
{"$ref": "#/$defs/numericExpression"} ,
{"$dynamicRef": "#cql2expression"} ,
{"$ref": "#/$defs/spatialInstance"} ,
{"$ref": "#/$defs/temporalInstance"} ,
{"$ref": "#/$defs/array"} ,
{"$ref": "#/$defs/propertyRef"}
]
}
}
}
},
"spatialInstance": {
"oneOf": [
{"$ref": "#/$defs/geometryLiteral"},
{"$ref": "#/$defs/bboxLiteral" }
]
},
"geometryLiteral": {
"oneOf": [
{"$ref": "#/$defs/point" },
{"$ref": "#/$defs/linestring" },
{"$ref": "#/$defs/polygon" },
{"$ref": "#/$defs/multipoint" },
{"$ref": "#/$defs/multilinestring" },
{"$ref": "#/$defs/multipolygon" },
{"$ref": "#/$defs/geometrycollection"}
]
},
"point": {
"title": "GeoJSON Point",
"type": "object",
"required": ["type", "coordinates"],
"properties": {
"type": { "type": "string", "enum": ["Point"] },
"coordinates": {
"type": "array",
"minItems": 2,
"items": {"type": "number"}
},
"bbox": { "type": "array", "minItems": 4, "items": {"type": "number"} }
}
},
"linestring": {
"title": "GeoJSON LineString",
"type": "object",
"required": ["type", "coordinates"],
"properties": {
"type": { "type": "string", "enum": ["LineString"] },
"coordinates": {
"type": "array",
"minItems": 2,
"items": {
"type": "array",
"minItems": 2,
"items": {"type": "number"}
}
},
"bbox": { "type": "array", "minItems": 4, "items": {"type": "number"} }
}
},
"polygon": {
"title": "GeoJSON Polygon",
"type": "object",
"required": ["type", "coordinates"],
"properties": {
"type": { "type": "string", "enum": ["Polygon"] },
"coordinates": {
"type": "array",
"items": {
"type": "array",
"minItems": 4,
"items": {
"type": "array",
"minItems": 2,
"items": {"type": "number"}
}
}
},
"bbox": { "type": "array", "minItems": 4, "items": {"type": "number"} }
}
},
"multipoint": {
"title": "GeoJSON MultiPoint",
"type": "object",
"required": ["type", "coordinates"],
"properties": {
"type": { "type": "string", "enum": ["MultiPoint"] },
"coordinates": {
"type": "array",
"items": {
"type": "array",
"minItems": 2,
"items": {"type": "number"}
}
},
"bbox": { "type": "array", "minItems": 4, "items": {"type": "number"} }
}
},
"multilinestring": {
"title": "GeoJSON MultiLineString",
"type": "object",
"required": ["type", "coordinates"],
"properties": {
"type": { "type": "string", "enum": ["MultiLineString"] },
"coordinates": {
"type": "array",
"items": {
"type": "array",
"minItems": 2,
"items": {
"type": "array",
"minItems": 2,
"items": {"type": "number"}
}
}
},
"bbox": { "type": "array", "minItems": 4, "items": {"type": "number"} }
}
},
"multipolygon": {
"title": "GeoJSON MultiPolygon",
"type": "object",
"required": ["type", "coordinates"],
"properties": {
"type": { "type": "string", "enum": ["MultiPolygon"] },
"coordinates": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "array",
"minItems": 4,
"items": {
"type": "array",
"minItems": 2,
"items": {"type": "number"}
}
}
}
},
"bbox": { "type": "array", "minItems": 4, "items": {"type": "number"} }
}
},
"geometrycollection": {
"title": "GeoJSON GeometryCollection",
"type": "object",
"required": ["type", "geometries"],
"properties": {
"type": { "type": "string", "enum": ["GeometryCollection"] },
"geometries": {
"type": "array",
"minItems": 2,
"items": {
"oneOf": [
{"$ref": "#/$defs/point" },
{"$ref": "#/$defs/linestring" },
{"$ref": "#/$defs/polygon" },
{"$ref": "#/$defs/multipoint" },
{"$ref": "#/$defs/multilinestring"},
{"$ref": "#/$defs/multipolygon" }
]
}
}
}
},
"bboxLiteral": {
"type": "object",
"required": ["bbox"],
"properties": { "bbox": {"$ref": "#/$defs/bbox"} }
},
"bbox": {
"type": "array",
"oneOf": [
{"minItems": 4, "maxItems": 4},
{"minItems": 6, "maxItems": 6}
],
"items": {"type": "number"}
},
"temporalInstance": {
"oneOf": [
{"$ref": "#/$defs/instantInstance" },
{"$ref": "#/$defs/intervalInstance"}
]
},
"instantInstance": {
"oneOf": [
{"$ref": "#/$defs/dateInstant" },
{"$ref": "#/$defs/timestampInstant"}
]
},
"dateInstant": {
"type": "object",
"required": ["date"],
"properties": { "date": {"$ref": "#/$defs/dateString"} }
},
"timestampInstant": {
"type": "object",
"required": ["timestamp"],
"properties": { "timestamp": {"$ref": "#/$defs/timestampString"} }
},
"instantString": {
"oneOf": [
{"$ref": "#/$defs/dateString" },
{"$ref": "#/$defs/timestampString"}
]
},
"dateString": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$"},
"timestampString": {
"type" : "string" ,
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$"
},
"intervalInstance": {
"type": "object",
"required": ["interval"],
"properties": { "interval": {"$ref": "#/$defs/intervalArray"} }
},
"intervalArray": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"oneOf": [
{"$ref": "#/$defs/instantString"} ,
{ "type": "string", "enum": [".."] },
{"$ref": "#/$defs/propertyRef"} ,
{"$ref": "#/$defs/functionRef"}
]
}
}
}
}
C.2. OpenAPI 3.0 schema for CQL2
The following document specifies the schema for CQL2 as an OpenAPI 3.0 schema in YAML:
---
openapi: 3.0.3
info:
title: Schema of Common Query Language (CQL2)
description: 'For use in OpenAPI 3.0 documents.'
version: '1.0.0-SNAPSHOT'
paths: {}
components:
schemas:
booleanExpression:
oneOf:
- $ref: '#/components/schemas/andOrExpression'
- $ref: '#/components/schemas/notExpression'
- $ref: '#/components/schemas/comparisonPredicate'
- $ref: '#/components/schemas/spatialPredicate'
- $ref: '#/components/schemas/temporalPredicate'
- $ref: '#/components/schemas/arrayPredicate'
- $ref: '#/components/schemas/functionRef'
- type: boolean
andOrExpression:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- and
- or
args:
type: array
minItems: 2
items:
$ref: '#/components/schemas/booleanExpression'
notExpression:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- not
args:
type: array
minItems: 1
maxItems: 1
items:
$ref: '#/components/schemas/booleanExpression'
comparisonPredicate:
oneOf:
- $ref: '#/components/schemas/binaryComparisonPredicate'
- $ref: '#/components/schemas/isLikePredicate'
- $ref: '#/components/schemas/isBetweenPredicate'
- $ref: '#/components/schemas/isInListPredicate'
- $ref: '#/components/schemas/isNullPredicate'
binaryComparisonPredicate:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- '='
- <>
- <
- '>'
- <=
- '>='
args:
$ref: '#/components/schemas/scalarOperands'
scalarOperands:
type: array
minItems: 2
maxItems: 2
items:
$ref: '#/components/schemas/scalarExpression'
scalarExpression:
oneOf:
- $ref: '#/components/schemas/characterExpression'
- $ref: '#/components/schemas/numericExpression'
- type: 'boolean'
- $ref: '#/components/schemas/instantInstance'
- $ref: '#/components/schemas/functionRef'
- $ref: '#/components/schemas/propertyRef'
isLikePredicate:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- like
args:
$ref: '#/components/schemas/isLikeOperands'
isLikeOperands:
type: array
minItems: 2
maxItems: 2
items:
oneOf:
- oneOf:
- $ref: '#/components/schemas/characterExpression'
- $ref: '#/components/schemas/propertyRef'
- $ref: '#/components/schemas/functionRef'
- $ref: '#/components/schemas/patternExpression'
patternExpression:
oneOf:
- type: object
required:
- op
- args
properties:
op:
type: string
enum:
- casei
args:
type: array
items:
$ref: '#/components/schemas/patternExpression'
minItems: 1
maxItems: 1
- type: object
required:
- op
- args
properties:
op:
type: string
enum:
- accenti
args:
type: array
items:
$ref: '#/components/schemas/patternExpression'
minItems: 1
maxItems: 1
- type: string
isBetweenPredicate:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- between
args:
$ref: '#/components/schemas/isBetweenOperands'
isBetweenOperands:
type: array
minItems: 3
maxItems: 3
items:
oneOf:
- $ref: '#/components/schemas/numericExpression'
- $ref: '#/components/schemas/propertyRef'
- $ref: '#/components/schemas/functionRef'
numericExpression:
oneOf:
- $ref: '#/components/schemas/arithmeticExpression'
- type: number
isInListPredicate:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- in
args:
$ref: '#/components/schemas/inListOperands'
inListOperands:
type: array
minItems: 2
maxItems: 2
items:
oneOf:
- $ref: '#/components/schemas/scalarExpression'
- type: array
items:
$ref: '#/components/schemas/scalarExpression'
isNullPredicate:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- isNull
args:
$ref: '#/components/schemas/isNullOperand'
isNullOperand:
type: array
minItems: 1
maxItems: 1
items:
oneOf:
- $ref: '#/components/schemas/characterExpression'
- $ref: '#/components/schemas/numericExpression'
- $ref: '#/components/schemas/booleanExpression'
- $ref: '#/components/schemas/spatialInstance'
- $ref: '#/components/schemas/temporalInstance'
- $ref: '#/components/schemas/propertyRef'
spatialPredicate:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- s_contains
- s_crosses
- s_disjoint
- s_equals
- s_intersects
- s_overlaps
- s_touches
- s_within
args:
$ref: '#/components/schemas/spatialOperands'
spatialOperands:
type: array
minItems: 2
maxItems: 2
items:
oneOf:
- $ref: '#/components/schemas/spatialInstance'
- $ref: '#/components/schemas/propertyRef'
- $ref: '#/components/schemas/functionRef'
temporalPredicate:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- t_after
- t_before
- t_contains
- t_disjoint
- t_during
- t_equals
- t_finishedBy
- t_finishes
- t_intersects
- t_meets
- t_metBy
- t_overlappedBy
- t_overlaps
- t_startedBy
- t_starts
args:
$ref: '#/components/schemas/temporalOperands'
temporalOperands:
type: array
minItems: 2
maxItems: 2
items:
oneOf:
- $ref: '#/components/schemas/temporalInstance'
- $ref: '#/components/schemas/propertyRef'
- $ref: '#/components/schemas/functionRef'
arrayPredicate:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- a_containedBy
- a_contains
- a_equals
- a_overlaps
args:
$ref: '#/components/schemas/arrayExpression'
arrayExpression:
type: array
minItems: 2
maxItems: 2
items:
oneOf:
- $ref: '#/components/schemas/array'
- $ref: '#/components/schemas/propertyRef'
- $ref: '#/components/schemas/functionRef'
array:
type: array
items:
oneOf:
- $ref: '#/components/schemas/characterExpression'
- $ref: '#/components/schemas/numericExpression'
- $ref: '#/components/schemas/booleanExpression'
- $ref: '#/components/schemas/spatialInstance'
- $ref: '#/components/schemas/temporalInstance'
- $ref: '#/components/schemas/array'
- $ref: '#/components/schemas/propertyRef'
arithmeticExpression:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- +
- '-'
- '*'
- /
- ^
- '%'
- div
args:
$ref: '#/components/schemas/arithmeticOperands'
arithmeticOperands:
type: array
minItems: 2
maxItems: 2
items:
oneOf:
- $ref: '#/components/schemas/arithmeticExpression'
- $ref: '#/components/schemas/propertyRef'
- $ref: '#/components/schemas/functionRef'
- type: number
propertyRef:
type: object
required:
- property
properties:
property:
type: string
casei:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- casei
args:
type: array
items:
oneOf:
- $ref: '#/components/schemas/characterExpression'
- $ref: '#/components/schemas/propertyRef'
- $ref: '#/components/schemas/functionRef'
minItems: 1
maxItems: 1
accenti:
type: object
required:
- op
- args
properties:
op:
type: string
enum:
- accenti
args:
type: array
items:
oneOf:
- $ref: '#/components/schemas/characterExpression'
- $ref: '#/components/schemas/propertyRef'
- $ref: '#/components/schemas/functionRef'
minItems: 1
maxItems: 1
characterExpression:
oneOf:
- $ref: '#/components/schemas/casei'
- $ref: '#/components/schemas/accenti'
- type: string
functionRef:
type: object
required:
- op
- args
properties:
op:
type: string
not:
enum:
- and
- or
- not
- '='
- <>
- <
- '>'
- <=
- '>='
- like
- between
- in
- isNull
- casei
- accenti
- s_contains
- s_crosses
- s_disjoint
- s_equals
- s_intersects
- s_overlaps
- s_touches
- s_within
- t_after
- t_before
- t_contains
- t_disjoint
- t_during
- t_equals
- t_finishedBy
- t_finishes
- t_intersects
- t_meets
- t_metBy
- t_overlappedBy
- t_overlaps
- t_startedBy
- t_starts
- a_containedBy
- a_contains
- a_equals
- a_overlaps
- +
- '-'
- '*'
- /
- ^
- '%'
- div
args:
type: array
items:
oneOf:
- $ref: '#/components/schemas/characterExpression'
- $ref: '#/components/schemas/numericExpression'
- $ref: '#/components/schemas/booleanExpression'
- $ref: '#/components/schemas/spatialInstance'
- $ref: '#/components/schemas/temporalInstance'
- $ref: '#/components/schemas/array'
- $ref: '#/components/schemas/propertyRef'
spatialInstance:
oneOf:
- $ref: '#/components/schemas/geometryLiteral'
- $ref: '#/components/schemas/bboxLiteral'
geometryLiteral:
oneOf:
- $ref: '#/components/schemas/point'
- $ref: '#/components/schemas/linestring'
- $ref: '#/components/schemas/polygon'
- $ref: '#/components/schemas/multipoint'
- $ref: '#/components/schemas/multilinestring'
- $ref: '#/components/schemas/multipolygon'
- $ref: '#/components/schemas/geometrycollection'
point:
title: GeoJSON Point
type: object
required:
- type
- coordinates
properties:
type:
type: string
enum:
- Point
coordinates:
type: array
minItems: 2
items:
type: number
bbox:
type: array
minItems: 4
items:
type: number
linestring:
title: GeoJSON LineString
type: object
required:
- type
- coordinates
properties:
type:
type: string
enum:
- LineString
coordinates:
type: array
minItems: 2
items:
type: array
minItems: 2
items:
type: number
bbox:
type: array
minItems: 4
items:
type: number
polygon:
title: GeoJSON Polygon
type: object
required:
- type
- coordinates
properties:
type:
type: string
enum:
- Polygon
coordinates:
type: array
items:
type: array
minItems: 4
items:
type: array
minItems: 2
items:
type: number
bbox:
type: array
minItems: 4
items:
type: number
multipoint:
title: GeoJSON MultiPoint
type: object
required:
- type
- coordinates
properties:
type:
type: string
enum:
- MultiPoint
coordinates:
type: array
items:
type: array
minItems: 2
items:
type: number
bbox:
type: array
minItems: 4
items:
type: number
multilinestring:
title: GeoJSON MultiLineString
type: object
required:
- type
- coordinates
properties:
type:
type: string
enum:
- MultiLineString
coordinates:
type: array
items:
type: array
minItems: 2
items:
type: array
minItems: 2
items:
type: number
bbox:
type: array
minItems: 4
items:
type: number
multipolygon:
title: GeoJSON MultiPolygon
type: object
required:
- type
- coordinates
properties:
type:
type: string
enum:
- MultiPolygon
coordinates:
type: array
items:
type: array
items:
type: array
minItems: 4
items:
type: array
minItems: 2
items:
type: number
bbox:
type: array
minItems: 4
items:
type: number
geometrycollection:
title: GeoJSON GeometryCollection
type: object
required:
- type
- geometries
properties:
type:
type: string
enum:
- GeometryCollection
geometries:
type: array
minItems: 2
items:
oneOf:
- $ref: '#/components/schemas/point'
- $ref: '#/components/schemas/linestring'
- $ref: '#/components/schemas/polygon'
- $ref: '#/components/schemas/multipoint'
- $ref: '#/components/schemas/multilinestring'
- $ref: '#/components/schemas/multipolygon'
bboxLiteral:
type: object
required:
- bbox
properties:
bbox:
$ref: '#/components/schemas/bbox'
bbox:
type: array
oneOf:
- minItems: 4
maxItems: 4
- minItems: 6
maxItems: 6
items:
type: number
temporalInstance:
oneOf:
- $ref: '#/components/schemas/instantInstance'
- $ref: '#/components/schemas/intervalInstance'
instantInstance:
oneOf:
- $ref: '#/components/schemas/dateInstant'
- $ref: '#/components/schemas/timestampInstant'
dateInstant:
type: object
required:
- date
properties:
date:
$ref: '#/components/schemas/dateString'
timestampInstant:
type: object
required:
- timestamp
properties:
timestamp:
$ref: '#/components/schemas/timestampString'
instantString:
oneOf:
- $ref: '#/components/schemas/dateString'
- $ref: '#/components/schemas/timestampString'
dateString:
type: string
pattern: ^\d{4}-\d{2}-\d{2}$
timestampString:
type: string
pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$
intervalInstance:
type: object
required:
- interval
properties:
interval:
$ref: '#/components/schemas/intervalArray'
intervalArray:
type: array
minItems: 2
maxItems: 2
items:
oneOf:
- $ref: '#/components/schemas/instantString'
- type: string
enum:
- ..
- $ref: '#/components/schemas/propertyRef'
- $ref: '#/components/schemas/functionRef'
Annex D: Revision History
Date | Release | Editor | Primary clauses modified | Description |
---|---|---|---|---|
2021-09-27 |
1.0.0-SNAPSHOT |
C. Portele |
all |
split from OGC API - Features - Part 3: Filtering |
2024-03-07 |
1.0.0-rc.1 |
C. Portele, P. Vretanos |
all |
release candidate, submission for the OGC approval process |
2024-03-26 |
1.0.0-rc.2 |
C. Portele, P. Vretanos |
all |
|
2024-06-29 |
1.0.0 |
C. Portele, P. Vretanos, G. Hobona |
all |
prepare for publication |
Annex E: Bibliography
-
Internet Engineering Task Force (IETF). RFC 5234: Augmented BNF for Syntax Specifications: ABNF [online]. Edited by D. Crocker, P. Overell. 2008. Available at https://www.rfc-editor.org/rfc/rfc5234.html
-
Internet Engineering Task Force (IETF). draft-bhutton-json-schema-validation-01: JSON Schema Validation: A Vocabulary for Structural Validation of JSON [online]. Edited by A. Wright, H. Andrews, B. Hutton. 2020. Available at https://json-schema.org/draft/2020-12/json-schema-validation
-
ISO 8601-1:2019, Date and time — Representations for information interchange — Part 1: Basic rules
-
ISO 8601-2:2019, Date and time — Representations for information interchange — Part 2: Extensions
-
ISO 15836-2:2019, Information and documentation — The Dublin Core metadata element set — Part 2: DCMI Properties and classes
-
Open Geospatial Consortium (OGC). OGC API - Features - Part 3: Filtering [online]. Edited by P. Vretanos, C. Portele. Available at https://docs.ogc.org/is/19-079r2/19-079r2.html
-
PostGIS. Dimensionally Extended 9-Intersection Model [online]. Available at https://postgis.net/workshops/postgis-intro/de9im.html.
-
Wikipedia. DE-9IM [online]. Available at https://en.wikipedia.org/wiki/DE-9IM.