Open Geospatial Consortium |
Submission Date: <yyyy-mm-dd> |
Approval Date: <yyyy-mm-dd> |
Publication Date: <yyyy-mm-dd> |
External identifier of this OGC® document: http://www.opengis.net/doc/IS/ogcapi-features-3/1.0 |
Internal reference number of this OGC® document: 19-079 |
Version: 1.0.0-draft.2 |
Latest Published Draft: n/a |
Category: OGC® Implementation Specification |
Editors: Panagiotis (Peter) A. Vretanos, Clemens Portele |
OGC API - Features - Part 3: Filtering and the Common Query Language (CQL) |
Copyright notice |
Copyright © 2020 Open Geospatial Consortium |
To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ |
Warning |
This document is not an OGC Standard. This document is distributed for review and comment. This document is subject to change without notice and may not be referred to as an OGC Standard.
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: Draft |
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 and Symbols
- 5. Conventions and background
- 6. Requirements Class "Filter"
- 7. Requirements Class "Features Filter"
- 8. Requirements Class "Simple CQL"
- 9. Common Query Language enhancements
- 10. Requirements classes for encodings
- 11. Media Types
- 12. Security Considerations
- Annex A: Abstract Test Suite (Normative)
- Annex B: CQL BNF (Normative)
- Annex C: JSON schemas for CQL (Normative)
- Annex D: Revision History
- Annex E: Bibliography
i. Abstract
OGC API standards define modular API building blocks to spatially enable Web APIs in a consistent way. The OpenAPI specification is used to define the API building blocks.
OGC API - Features provides API building blocks to create, modify and query features on the Web. OGC API Features is comprised of multiple parts. Each part is a separate standard.
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. Part three of the OGC API - Feature Standard defines
-
Query parameters (
filter
,filter-lang
,filter-crs
) to specify filter criteria in a request to an API; -
A filter grammar called Common Query Language (CQL) for specifying enhanced filtering criteria beyond what is supported in the Core;
-
Two encodings for CQL - a text and a JSON encoding.
The Common Query Language (CQL) 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, CQL is used in query operations to identify the subset of resources, such as features, that should be included in a response document. However, CQL 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.
CQL and its text encoding are not new, but this is the first time CQL is properly specified. CQL was created as a text encoding based on the capabilities defined in the OGC Filter Encoding standard for use in the OGC Catalogue Service standard. It was one of the design goals to keep CQL as compatible as possible with existing implementations. For example, the classification of operators into logical, comparison, spatial and temporal operators as well as their names and syntax are unchanged from the original definitions in OGC Filter Encoding. For the spatial and temporal operators this document either defines the operator or references to definition of the operator.
Caution
|
This is a DRAFT version of the 3rd part of the OGC API - Features standards. This draft is not complete and there are open issues that are still under discussion. |
ii. Keywords
The following are keywords to be used by search engines and document catalogues.
OGC, common query language, filter, expression, query, SQL, CQL, where clause, selection clause, OGC API
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.
-
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) |
1. Scope
This document specifies an extension to the OGC API - Features - Part 1: Core standard that defines the behavior of a server that supports enhanced filtering capabilities expressed using a Common Query Language (CQL).
Enhanced filtering capabilities in this case means that the server supports
the ability to define selection clauses using predicates beyond those supported
by Part 1 (i.e., bbox
and datetime
).
This document defines
-
Query parameters for specifying a filter in a request to a Web API;
-
A text encoding for a CQL filter suitable for use as a query parameter in a URL;
-
A JSON encoding for a CQL filter suitable for use in a HTTP POST body;
-
How the set of properties or keys that can be used to construct CQL expressions ("queryables") are published by a Web API.
2. Conformance
This standard defines the following conformance classes:
The Filter conformance class defines a set of HTTP query parameters that may be used to specify complex filter expressions on HTTP requests. The specific set of parameters defined in this conformance class is:
-
filter
- The filter expression. -
filter-lang
- The language used in the filter expression. -
filter-crs
- The Coordinate Reference System used in the filter expression.
This conformance class also defines the Queryables resource (at paths
/queryables
and /collections/{collectionId}/queryables
) that can be
used to determine the list of property names and types that may be used
to construct filter expressions.
The Features Filter conformance class defines the binding between the Filter conformance class and the OGC API - Features - Part 1: Core standard.
The Simple CQL conformance class defines the minimal subset
of the Common Query Language (CQL) that all implementations must support
("Simple CQL"). Simple CQL is intended to be a minimal useful set of
predicates that support enhanced fine-grained read-access to collections of
resources. In this case, "enhanced" means filtering capabilities beyond those
supported by the core OGC API Common standard (i.e., bbox
, datetime
and optionally collection-specific properties).
Note
|
OGC API - Common is still in draft form and is not an official OGC standard. |
The specific set of operators defined in this conformance class is:
-
Logical operators:
-
and
-
or
-
not
-
-
Comparison operators:
-
equal to
-
less than
-
less than or equal to
-
greater than
-
greater than or equal to
-
like
-
is null
-
between
-
in
-
-
Spatial operators:
-
intersects
-
-
Temporal operators:
-
anyinteracts
-
Note
|
The anyinteracts temporal operator is defined in this document by requirement /req/simple-cql/temporal-predicate.
|
An encoding of CQL may be used as the value of the filter parameters defined in the Filter conformance class.
The Enhanced Spatial Operators conformance
class specifies requirements for servers that support spatial operators in
addition to the intersects
operator that is defined in the
Simple CQL conformance class. The list of
additional spatial operators that must be supported is:
-
equals
-
disjoint
-
touches
-
within
-
overlaps
-
crosses
-
contains
The Enhanced Temporal Operators conformance
class specifies requirements for servers that support temporal operators in
addition to the anyinteracts
operator defined in the
Simple CQL conformance class. The list of
additional temporal operators that must be supported is:
-
after
-
before
-
begins
-
begunby
-
tcontains
-
during
-
endedby
-
ends
-
tequals
-
meets
-
metby
-
toverlaps
-
overlappedby
-
intersects
The Functions conformance class specifies requirements for
supporting function calls (e.g. min, max, etc.) in a CQL expression. Function
calls are the primary means of extending the language. This conformance class
also defined a Functions resource (at path /functions
) that may be used to
discover the list of available functions.
The Arithmetic operators conformance class specifies requirements for supporting the standard set of arithmetic operators, \(+, -, *, /\) in a CQL expression.
The Arrays conformance class specifies requirements for comparison operators for sets of values. The operators that must be supported are:
-
aequals
-
acontains
-
containedby
-
aoverlaps
The CQL Text encoding conformance class defines
a text encoding for CQL. Such an encoding is suitable for use with HTTP query
parameters such as the filter
parameter defined by the Filter
conformance class.
The CQL JSON encoding conformance class defines a JSON encoding for CQL. Such as encoding is suitable for use with 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.
2.1. Roadmap
The content of this sub-clause is informative.
Because CQL is not exclusively useful for features, it is anticipated that the following conformance classes:
will eventually become parts of the OGC API Common suite of standards thus leaving the Features Filter conformance class as part 3 of the OGC API Features specifications.
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 17-069r3: OGC API - Features - Part 1: Core [online]. Edited by C. Portele, P. Vretanos, C. Heazel. 2019 [viewed 2020-11-22]. Available at http://docs.opengeospatial.org/is/17-069r3/17-069r3.html
-
Open Geospatial Consortium (OGC). OGC 18-058: OGC API - Features - Part 2: Coordinate Reference Systems by Reference [online]. Edited by C. Portele, P. Vretanos. 2020 [viewed 2020-12-03]. Available at http://docs.opengeospatial.org/is/18-058/18-058.html
-
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
-
Open Geospatial Consortium (OGC) / World Wide Web Consortium (W3C). OGC 16-071r3: 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
-
Egenhofer M.J., Herring J.R., A Mathematical Framework for the Definition of Topological Relationships, Fourth International Symposium on Spatial Data Handling, Zurich, Switzerland, July 1990
4. Terms, Definitions and Symbols
4.1. Terms and Definitions
This document uses the terms defined in Sub-clause 5.3 of [OGC 06-121r9], 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.
For the purposes of this document, the following additional terms and definitions apply in addition to the terms defined in OGC API - Features - Part 1: Core.
4.1.1. 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.4. 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.5. publisher
entity responsible for making a resource available (Dublic Core Metadata Initiative - DCMI Metadata Terms)
Note
|
As content of OGC API standards, a resource is typically published at an endpoint. |
4.1.6. queryable
a token that represents a property of a resource that can be used in a filter expression
4.1.7. resource / web resource
any information that can be named and is the intended conceptual target of a hypertext reference (Architectural Styles and the Design of Network-based Software Architectures)
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
5. Conventions and background
5.1. General remarks
See OGC API - Features - Part 1: Core, Clauses 5 and 6.
5.2. Identifiers
The normative provisions in this standard are denoted by the URI http://www.opengis.net/spec/ogcapi-features-3/1.0
.
All requirements and conformance tests that appear in this document are denoted by partial URIs which are relative to this base.
5.3. Additional link relation types
The following OGC link relation types are introduced in this document (no applicable registered link relation type could be identified):
-
http://www.opengis.net/def/rel/ogc/1.0/queryables: Refers to a resource that lists properties that can be used to query items in the collection represented by the link’s context.
5.4. Use of BNF
BNF as specified in Augmented BNF for Syntax Specifications is used to formally specify the grammar of the Common Query Language (CQL).
5.5. Use of JSON Schema
JSON Schema draft 2019-09 ([JSONSCHEMA], [JSONSCHEMAVALIDATION]) is used to formally specify the schema of the JSON encoding of CQL (CQL-JSON).
5.6. Dependencies to other requirements classes
The requirements classes in this extension distinguish two types of dependencies to other specifications or requirements classes:
First, there are the "regular" 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 "Filter"
6.1. Overview
Requirements Class |
|
http://www.opengis.net/spec/ogcapi-features-3/1.0/req/filter |
|
Target type |
Web API |
Conditional Dependency |
OGC API - Features - Part 2: Coordinate Reference Systems by Reference |
OGC API - Features - Part 1: Core (and the draft OGC API - Common - Part 2: Geospatial Data standard) define two filtering parameters on the resource at path /collections/{collectionId}/items
: bbox
and datetime
. OGC API - Features - Part 1: Core also adds support for simple equality predicates logically joined using the AND
operator. These capabilities offer simple resource filtering for HTTP requests.
The Filter requirements class defines additional query parameters that allow more complex filtering expressions to be specified when querying server resources.
Specifically, this clause defines the parameters, filter
, filter-lang
and
filter-crs
.
The Filter requirements class also defines resources for discovering the list of resource properties (and their types) that may be used to construct filter expressions.
6.2. Queryables
This standard does not assume that the content schema of a resource being queried is available for inspection. Therefore, a means needs to exist to interrogate an endpoint to determine the names and types of the properties or keys that may be used to construct a filter expression ("queryables").
In addition, a publisher may want to support queryables that are not directly represented as resource properties in the content schema of the resource. Or the publisher may want to restrict filtering on certain properties. For example, because the backend datastore has not been configured to allow high-performance queries on those properties.
Requirement 1 |
/req/filter/get-queryables-op-global |
A |
A server that implements this requirements class SHALL support the HTTP GET operation at the path |
B |
The queryables accessed at this path SHALL be valid for all collections identified in the Collections resource (path |
C |
The Queryables resource SHALL be referenced from the Landing Page resource
with a link with the link relation type |
Requirement 2 |
/req/filter/get-queryables-op-local |
A |
For every collection identified in the Collections resource (path
|
B |
The parameter |
C |
The Queryable resource SHALL be referenced from the Collection resource
with a link with the link relation type |
Requirement 3 |
/req/filter/get-queryables-response |
A |
A successful execution of the operation SHALL be reported as a response
with a HTTP status code |
B |
For responses that use
|
To support clients, providing additional detail about the meaning of the property and the possible values is recommended:
Recommendation 1 |
/rec/filter/queryables-schema |
A |
Each property SHOULD have a human readable title ( |
B |
Each property SHOULD have a single type ( |
C |
For string properties |
D |
For numeric properties |
E |
For integer properties that represent enumerated values, |
F |
For temporal properties, the property SHOULD be a |
G |
For spatial properties, the property SHOULD reference a well-known JSON schema of the geometry object. |
H |
For geometry types according to the Simple Features standard, the
JSON Schema of the GeoJSON geometry object SHOULD be referenced;
for example, |
I |
For array properties, the property SHOULD consist of items that are strings or numbers. |
{
"$schema" : "https://json-schema.org/draft/2019-09/schema",
"$id" : "https://demo.ldproxy.net/daraa/collections/CulturePnt/queryables",
"type" : "object",
"title" : "Cultural (Points)",
"description" : "Cultural: Information about features on the landscape with a point geometry that have been constructed by man.",
"properties" : {
"F_CODE" : {
"title" : "Feature Type",
"type" : "string",
"enum" : [ "AK121", "AL012", "AL030", "AL130", "BH075" ]
},
"ZI001_SDV" : {
"title" : "Last Change",
"type" : "string",
"format" : "date-time"
},
"ZI037_REL" : {
"title" : "Religious Designation",
"type" : "integer",
"enum" : [ -999999, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]
},
"geometry" : {
"$ref" : "https://geojson.org/schema/Point.json"
}
}
}
6.3. Parameter filter
The Filter requirements class defines a general parameter, filter
, whose
value is a filter expression to be applied when retrieving resources. This
is necessary to determine which resources should be included in a result set.
Requirement 4 |
/req/filter/filter-param |
A |
The HTTP GET operation on the path that fetches resource instances (e.g.
|
6.4. Cross-collection queries
The only filterable resource defined in OGC API - Features - Part 1: Core
is the Features resource at /collections/{collectionId}/items
which operates
on a single collection. However an API can provide other, higher level, resources that potentially operate on multiple collections.
The simplest approach for handling such cross-collection queries is one that is
consistent with one-collection queries. Specifically, the filter
parameter, if
provided, applies to all referenced collections. Of course this implies that all
properties referenced in the filter expression are valid for all referenced collections
and should be taken from the global queryables list.
Requirement 5 |
/req/filter/filter-param-multiple-collections |
A |
A server that implements this extension and also supports queries across multiple collections SHALL only allow properties from the global list of queryables to be referenced in a filter expression. |
B |
If a cross-collection filter expression references properties that are not listed in the global list of queryables,
then the server SHALL respond with an HTTP status code of |
The following example illustrates a notional query on a hypothetical Query resource that uses a CQL filter and references multiple collections:
http://www.someserver.com/ogcapi/search? collections=collection1,collection3& filter-lang=cql-text& filter=prop1=10 AND prop2>45
Note
|
Arrays of filter expressions that operate on each collection specified in a query (or subsets thereof) are out of scope for this extension and would be the subject of a different part of the "OGC API - Features" suite of specifications. |
6.5. Parameter filter-lang
Any predicate language that can be suitably expressed as the value of an
HTTP query parameter may be specified as the value of the filter
parameter.
In order to specify that specific language that is being used, this clause
defines the filter-lang
parameter.
Requirement 6 |
/req/filter/filter-lang-param |
A |
The HTTP GET operation on the path that fetches resource instances (e.g.
|
B |
The |
C |
The |
The enumerated value cql-text
is used to indicate that the value of the
filter
parameter is the text encoding of CQL.
The enumerated value cql-json
is used to indicate that the value of the
filter
parameter is the JSON encoding of CQL.
Servers that support other filtering languages can extend this list of values as necessary although the meaning of any additional values are not described in this standard.
6.6. Parameter filter-crs
For reasons discussed in the W3C/OGC Spatial Data on the Web Best Practices document,
OGC API - Features - Part 1: Core uses WGS 84 longitude and latitude and the default Coordinate Reference System. OGC API - Features - Part 2: Coordinate Reference Systems by Reference extends the capabilities of Part 1 to allow other coordinate systems to be used. The filter-crs
parameter defined in this clause allows clients to indicate to servers that support other CRSs, which CRS is being used to encode geometric values in a filter expression.
Requirement 7 |
/req/filter/filter-crs-wgs84 |
A |
If a HTTP GET operation on the path that fetches resource instances (e.g. |
Requirement 8 |
/req/filter/filter-crs-param |
Condition |
Server implements OGC API - Features - Part 2: Coordinate Reference Systems by Reference |
A |
The HTTP GET operation on the path that fetches resource instances (e.g.
|
B |
If a HTTP GET operation on the path that fetches resource instances (e.g. |
C |
The server SHALL return an error, if it does not support the CRS identified in |
6.7. Interaction with other predicates
OGC API - Features - Part 1: Core defines the parameters bbox
, datetime
and parameters for filtering on feature properties. This clause defines how the filter
parameter and these core parameters should interact if specified in a single request.
Requirement 9 |
/req/filter/mixing-expression |
A |
Other filter predicates supported by the server (e.g. |
6.8. Filter expression languages
This standard defines a filter expression language called the Common Query Language (CQL). However, support for this filter expression language is not mandatory and other languages can be used as the value of the filter parameter, too.
A simple CQL core is defined along with a number of enhancements that add additional, more advanced capabilities to the language. Two encodings, a text encoding and a JSON encoding are also defined and recommended if they are suitable for the intended use.
6.9. Response
A filter expression defines a subset of items from a collection that should be presented in a query response.
Requirement 10 |
/req/filter/response |
A |
The filter expression SHALL be evaluated for each item of the collection being queried. |
B |
If the filter expression evaluates to |
C |
If the filter expression evaluates to |
7. Requirements Class "Features Filter"
7.1. Overview
Requirements Class |
|
http://www.opengis.net/spec/ogcapi-features-3/1.0/req/features-filter |
|
Target type |
Web API |
Dependency |
|
Dependency |
OGC API - Features - Part 1: Core, Requirements Class "Core" |
Conditional Dependency |
OGC API - Features - Part 2: Coordinate Reference Systems by Reference |
This clause defines the binding between the OGC API - Features - Part 1: Core standard and the filter parameters defined in the Filter conformance class.
7.2. Features
7.2.1. Operation
As per the OGC API - Features - Part 1: Core Standard, features are accessed using the HTTP GET method via the /collections/{collectionId}/items
path (see Features). The following additional requirements bind the parameters filter, filter-lang and filter-crs to the GET operation on this path.
Requirement 11 |
/req/features-filter/filter-param |
A |
The HTTP GET operation on the |
Requirement 12 |
/req/features-filter/filter-lang-param |
A |
The HTTP GET operation on the |
Recommendation 2 |
/rec/features-filter/text-encoding |
A |
If a filter expression can be represented for its intended use as text, servers SHOULD consider supporting the CQL text encoding. |
Recommendation 3 |
/rec/features-filter/JSON-encoding |
A |
If a filter expression can be represented for its intended use as JSON, servers SHOULD consider supporting the CQL JSON encoding. |
Requirement 13 |
/req/features-filter/filter-crs-param |
Condition |
Server implements OGC API - Features - Part 2: Coordinate Reference Systems by Reference |
A |
The HTTP GET operation on the |
7.2.2. Response
Requirement 14 |
/req/features-filter/response |
A |
A filter expression SHALL be evaluated for each feature of a collection. |
B |
All other filtering parameters specified (i.e. zero or more of bbox, datetime and property filters) SHALL be evaluated for each feature of a collection. |
C |
If the filter expression AND all other specified filtering parameters (i.e. zero or more of bbox, datetime and property filters) evaluate to |
D |
If the filter expression OR any other specified filtering parameter (i.e. zero or more of bbox, datetime and property filters) evaluates to |
8. Requirements Class "Simple CQL"
8.1. Overview
Requirements Class |
|
http://www.opengis.net/spec/ogcapi-features-3/1.0/req/simple-cql |
|
Target type |
Web API |
This clause defines the core of a query language called Common Query Language
(CQL) that may be used to construct filter expressions. This core is called Simple CQL.
Subsequent clauses define additional filtering capabilities as well as several encodings of CQL.
8.2. CQL filter expression
A CQL filter expression is an expression that defines a logically connected set of predicates that are evaluated for each item of a collection.
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.
If a predicate evaluates to TRUE
for an item, the item qualifies for
further processing such as presentation in the result set, being passed on
to the next predicate in the filter for further evaluation, and so forth.
If the predicate evaluates to FALSE
or NULL
for an item, the item is not
available for further processing.
A collection item that satisfies ALL the requirements of a CQL filter expression
evaluates to a Boolean value of TRUE
; otherwise the CQL filter expression
evaluates to FALSE
.
Requirement 15 |
/req/simple-cql/cqlfilter |
A |
A server SHALL support a CQL filter expression composed of a logically connected series of one or more predicates as described by the BNF rule
|
A Simple CQL filter expression can be constructed by logically connecting one or more of the following classes of predicates:
-
comparison predicates
-
spatial predicates
-
temporal predicates
Support for the parts of CQL that are not part of Simple CQL is added in additional requirements classes in Common Query Language enhancements:
-
The rule
arrayPredicate
is added by requirements class Arrays; -
The rule
function
is added by requirements class Functions; -
The rule
arithmeticExpression
is added by requirements class Arithmetic Expressions; -
The additional values in rule
spatialOperator
are added by requirements class Enhanced Spatial Operators; -
The additional values in rule
temporalOperator
are added by requirements class Enhanced Temporal Operators.
Examples of Simple CQL filter expressions are included in the subsequent sub-clauses.
8.3. Literal values
A literal value is any part of an CQL filter expression that is used exactly as it is specified in the expression. Literal values include:
-
character strings (rule
characterLiteral
), -
numbers (rule
numericLiteral
), -
booleans (rule
booleanLiteral
), -
spatial geometries (rule
spatialLiteral
) and -
temporal geometries (rule
temporalLiteral
).
-
character string
'This is a literal string.'
-
number
-100 3.14159
-
boolean
true false t f
-
spatial geometry (text)
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": "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] ] ] }
-
temporal geometry (instants, text)
1969-07-20 1969-07-20T20:17:40Z
-
temporal geometry (instants, JSON)
"1969-07-20" "1969-07-20T20:17:40Z"
-
temporal geometry (intervals, text)
1969-07-16/1969-07-24 1969-07-16T05:32:00Z/1969-07-24T16:50:35Z 2019-09-09/..
-
temporal geometry (intervals, JSON)
[ "1969-07-16", "1969-07-24" ] [ "1969-07-16T05:32:00Z", "1969-07-24T16:50:35Z" ] [ "2019-09-09", ".." ]
Note
|
The current BNF rule for temporal literals supports timestamps in any time zone. Should this be restricted to UTC ("Z"), at least in Simple CQL? See issue 483. |
8.4. Property references
Properties in an object being evaluated in the CQL filter expression can be
referenced by their name (rule propertyName
).
Requirement 16 |
/req/simple-cql/property |
A |
The property name (rule |
B |
The property name reference SHALL evaluate to a literal value or |
C |
The data type of the literal value SHALL match the expected data type for the expression within which the property name reference appears. |
For example, a property name used in a scalar expression (rule scalarExpression
)
has to be a queryable of type string
, number
, integer
or boolean
.
In this example, the property windSpeed
is used in a function that returns a number.
avg(windSpeed)
{ "function": { "name": "avg", "arguments": [ { "property": "windSpeed" } ] } }
8.5. Comparison predicates
Requirement 17 |
/req/simple-cql/binary-comparison-predicate |
A |
A binary comparison predicate as specified by rule |
B |
Both scalar expressions (rules |
city='Toronto'
{ "eq": [ { "property": "city" }, "Toronto" ] }
avg(windSpeed) < 4
{
"lt": [
{ "function": { "name": "avg", "arguments": [ { "property": "windSpeed" } ] } },
4
]
}
balance-150.0 > 0
{
"gt": [
{ "-": [ { "property": "windSpeed" }, 150.0 ] },
0
]
}
Requirement 18 |
/req/simple-cql/like-predicate |
A |
The like predicate (rule |
B |
The scalar expression (rule |
C |
The character specified using the |
D |
The wildchar character SHALL not match the NULL value. |
E |
If the |
F |
The character specified using the |
G |
If the |
H |
The character specified using the |
I |
If the |
J |
If |
name LIKE 'Smith.' SINGLECHAR '.' NOCASE true
{
"like": [
{ "property": "name" },
"Smith."
],
"singleChar": ".",
"nocase": true
}
Requirement 19 |
/req/simple-cql/between-predicate |
A |
The between predicate (rule |
B |
Any function (rule |
depth BETWEEN 100.0 and 150.0
{
"between": {
"value": { "property": "depth" },
"lower": 100.0,
"upper": 150.0
}
}
Requirement 20 |
/req/simple-cql/in-predicate |
A |
The in-list predicate (rule |
B |
The items in the list of an in-list predicate (rule |
cityName IN ('Toronto','Franfurt','Tokyo','New York') NOCASE false
{
"in": {
"value": { "property": "cityName" },
"list": [ "Toronto", "Franfurt", "Tokyo", "New York" ],
"nocase": false
}
}
category NOT IN (1,2,3,4)
{
"not": {
"in": {
"value": { "property": "category" },
"list": [ 1, 2, 3, 4 ]
}
}
}
Requirement 21 |
/req/simple-cql/null-predicate |
A |
The null predicate (rule |
geometry IS NOT NULL
{ "not": { "isNull" : { "property": "geometry" } } }
8.6. Spatial predicates
A spatial predicate evaluates two geometry-valued expressions to determine if the expressions satisfy the requirements of the specified spatial operator.
In this conformance class, the only required spatial operator is intersects. Additional spatial operators are specified in the Enhanced Spatial Operators requirements class.
Requirement 22 |
/req/simple-cql/spatial-predicate |
A |
If the requirements of the spatial operator are satisfied, then the predicate SHALL evaluate to the Boolean value |
B |
The |
Note
|
The spatial predicates currently use a different pattern than the comparison and temporal predicates and are written like function calls. This difference is inherited from previous versions of CQL. It is an open issue, whether this version of CQL should change the spatial predicates to be consistent with the other predicates or to keep the legacy because of existing CQL implementations. Comments are welcome in the GitHub issue on this topic. |
CQL uses Well-Known-Text (WKT) to encode geometry literals. Since WKT does 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. In this standard, the filter-crs
query parameter
is used to pass the CRS information to the server.
INTERSECTS(geometry,POLYGON((36.319836 32.288087,36.320041 32.288032,36.320210 32.288402,36.320008 32.288458,36.319836 32.288087)))
{ "intersects": [
{ "property": "geometry" },
{
"type": "Polygon",
"coordinates": [
[
[36.319836, 32.288087],
[36.320041, 32.288032],
[36.320210, 32.288402],
[36.320008, 32.288458],
[36.319836, 32.288087]
]
]
}
] }
...filter-lang=cql-text& filter-crs=http://www.opengis.net/def/crs/EPSG/0/32635& filter=INTERSECTS(geometry,POLYGON((1379213.867288 3610774.164192,1379233.837424 3610769.696029,1379246.149564 3610812.389132,1379226.494235 3610816.884823,1379213.867288 3610774.164192)))...
8.7. Temporal predicates
A temporal predicate evaluates two time-valued expressions to determine if the expressions satisfy the requirements of the specified temporal operator.
In this conformance class, the only required temporal operator is anyinteracts. The anyinteracts operator is not defined in any of the cited references. Rather, it is defined in this standard as an analogous temporal operator to the intersects spatial operator.
Additional temporal operators are specified in the Enhanced Temporal Operators requirements class.
Requirement 23 |
/req/simple-cql/temporal-predicate |
A |
If the requirements of the temporal operator are satisfied, then the predicate SHALL evaluate to the Boolean value |
B |
The ANYINTERACTS(i,j) = NOT( BEFORE(i,j) OR MEETS(i,j) OR METBY(i,j) OR AFTER(i,j) ) |
All temporal literals are in the Gregorian Calendar.
Note
|
This is a deliberate restriction to keep implementations of CQL simple, avoiding requirements to transformation 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. |
event_date ANYINTERACTS 1969-07-16T05:32:00Z/1969-07-24T16:50:35Z
{
"anyinteracts": [
{ "property": "event_date" },
[ "1969-07-16T05:32:00Z","1969-07-24T16:50:35Z" ]
]
}
9. Common Query Language enhancements
9.1. Overview
This clause specifies requirements for enhancements to Simple CQL. Specifically, this clause defines requirements for:
-
Additional spatial operators;
-
Additional temporal operators;
-
Support for functions in CQL;
-
Support for arithmetic expression in CQL;
-
Support for arrays in CQL.
In each case, this clause specifies requirements for the rules in CQL BNF not supported by Simple CQL.
9.2. Requirements Class "Enhanced Spatial Operators"
Requirements Class |
|
http://www.opengis.net/spec/ogcapi-features-3/1.0/req/enhanced-spatial-operators |
|
Target type |
Web API |
Dependency |
The Simple CQL clause specifies the use of the INTERSECTS
spatial operator. This requirement adds additional Dimensionally Extended
Nine-intersection Model (DE-9IM) relation operators to the list of spatial
operators that an implementation of this extension might offer.
Requirement 24 |
/req/enhanced/spatial-operators |
A |
The server SHALL support all spatial operators as defined by the BNF rule |
B |
The spatial operators in addition to |
Note
|
The spatial predicates currently use a different pattern than the comparison and temporal predicates and are written like function calls. This difference is inherited from previous versions of CQL. This is an open issue: Whether this version of CQL used in the OGC API - Features - Part 3 standard should change the spatial predicates to be consistent with the other predicates or to keep the legacy because of existing CQL implementations. Comments are welcome in the GitHub issue on this topic. |
The following table lists the mathematical definitions of each spatial operator as described in OpenGIS® Implementation Standard for Geographic information - Simple feature access - Part 1: Common architecture.
Spatial operator | Definition |
---|---|
EQUALS |
EQUALS(a,b) ⬄ a ⊆ b ∧ b ⊆ a |
DISJOINT |
DISJOINT(a,b) ⬄ a ∩ b = ∅ |
TOUCHES |
TOUCHES(a,b) ⬄ (I(a) ∩ I(b) = ∅) ∧ (a ∩ b) ≠ ∅ |
WITHIN |
WITHIN(a,b) ⬄ (a ∩ b = a) ∧ (I(a) ∩ E(b) ≠ ∅) |
OVERLAPS |
OVERLAPS(a,b) ⬄ (dim(I(a)) = dim(I(b)) = dim(I(a) ∩ I(b))) ∧ (a ∩ b ≠ a) ∧ (a ∩ b ≠ b) |
CROSSES |
CROSSES(a,b) ⬄ [I(a) ∩ I(b) = ∅) ∧ (a ∩ b ≠ a) ∧ (a ∩ b ≠ b)] |
INTERSECTS |
INTERSECTS(a,b) ⬄ ! a DISJOINT b |
CONTAINS |
CONTAINS(a,b) ⬄ b CONTAINS a |
The following diagrams illustrate the meaning of the TOUCHES
, WITHIN
, OVERLAPS
,
and CROSSES
operators.
Note
|
If geometry a CONTAINS geometry b, then geometry b is WITHIN geometry a.
|
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)))
{
"crosses": [
{
"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]
]
}
]
}
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)))
{
"crosses": [
{"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]
]
}
]
}
It should be noted that the function "Buffer()" in this example is not part of CQL but is an example of a function that an implementation may offer that returns a geometry value.
WITHIN(road,Buffer(geometry,10,"m"))
{
"within": [{"property": "road"},
{"function": {"name":"Buffer",
"arguments": [{"property": "geometry"},10,"m"]}}
]
}
9.3. Requirements Class "Enhanced Temporal Operators"
Requirements Class |
|
http://www.opengis.net/spec/ogcapi-features-3/1.0/req/enhanced-temporal-operators |
|
Target type |
Web API |
Dependency |
The Simple CQL clause specifies the use of the ANYINTERACTS
temporal operator. This requirements class adds additional commonly used temporal
operators that an implementation of this extension might offer.
Requirement 25 |
/req/enhanced-temporal-operators |
A |
The server SHALL support all temporal operators as defined by the BNF rule |
B |
The spatial operators in addition to
|
CQL supports date and timestamps as time instants, but even the smallest "instant" has a duration and can also be evaluated as an interval. For the purposes of determining the temporal relationship between two temporal expressions, an instant is treated as the interval from the beginning to the end of the instant. The following diagram illustrates the meaning of the temporal operators.
1969-07-20T20:17:40Z DURING 1969-07-16T13:32:00Z/1969-07-24T16:50:35Z
{
"during": ["1969-07-20T20:17:40Z",["1969-07-16T13:32:00Z",
"1969-07-24T16:50:35Z"]]
}
touchdown DURING 1969-07-16T13:32:00Z/1969-07-24T16:50:35Z
{
"during": [{"property": "touchdown"},["1969-07-16T13:32:00Z",
"1969-07-24T16:50:35Z"]]
}
9.4. Requirements Class "Functions"
Requirements Class |
|
http://www.opengis.net/spec/ogcapi-features-3/1.0/req/functions |
|
Target type |
Web API |
Dependency |
This sub-clause specifies requirements for supporting functions in CQL. Functions allow implementations to extend the language.
Requirement 26 |
/req/functions/functions |
A |
The server SHALL support functions as defined by the BNF rules |
B |
The function SHALL evaluate to a literal 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.
|
A resource, /functions
is also defined that allows clients to discover the
list of function that a server offers.
Requirement 27 |
/req/functions/get-functions-operation |
A |
A server SHALL support the HTTP GET operation at the |
Requirement 28 |
/req/functions/get-functions-response-json |
A |
A successful execution of the operation SHALL be reported as a response with
a HTTP status code |
B |
The content of that response SHALL be based upon the following OpenAPI 3.0 schema and list all functions that the server supports:
|
{
"functions": [
{
"name": "min",
"arguments": [
{
"type": ["string","number","datetime"]
},
{
"type": ["string","number","datetime"]
},
],
"retuns": ["string","number","datetime"]
},
{
"name": "max",
"arguments": [
{
"type": ["string","number","datetime"]
},
{
"type": ["string","number","datetime"]
},
],
"retuns": ["string","number","datetime"]
},
{
"name": "geometryType",
"arguments": [
{
"type": ["geometry"]
}
],
"returns": ["string"]
}
]
}
9.5. Requirements Class "Arithmetic Expressions"
Requirements Class |
|
http://www.opengis.net/spec/ogcapi-features-3/1.0/req/arithmetic |
|
Target type |
Web API |
Dependency |
This clause specifies requirements for supporting arithmetic expressions in CQL. 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 +,-,*,/) and another arithmetic operand.
Requirement 29 |
/req/arithmetic/arithmetic |
A |
The server SHALL support arithmetic expressions as defined by the BNF rules
|
Note
|
Support for the BNF rule function is added by the requirements class Functions.
|
vehicle_height > (bridge_height-1)
{
"gt": [{"property":"vehicle_height"},{"-":[{"property":"bridge_height"},1]}]
}
9.6. Requirements class "Arrays"
Requirements Class |
|
http://www.opengis.net/spec/ogcapi-features-3/1.0/req/arrays |
|
Target type |
Web API |
Dependency |
This clause specifies requirements for supporting array expression in CQL. 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.
Requirement 30 |
/req/arrays/array-predicate |
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 a array of values. |
C |
The semantics of the array operators SHALL be evaluated as follows:
|
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.
|
layer:ids ACONTAINS ["layers-ca","layers-us"]
{
"acontains": [{"property": "layer:ids"},["layers-ca","layers-us"]]
}
10. Requirements classes for encodings
10.2. Requirements Class "CQL Text"
Requirements Class |
|
http://www.opengis.net/spec/ogcapi-features-3/1.0/req/cql-text |
|
Target type |
Web API |
Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
This requirements class defines a Well Known Text (WKT) encoding of CQL. Such an
encoding would be suitable for use with the GET query parameter such as the
filter
parameter.
The "CQL Text" encoding is defined by the BNF grammar defined in CQL 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 CQL keywords includes:
-
"ACONTAINS"
-
"AEQUALS"
-
"AFTER"
-
"AND"
-
"ANYINTERACTS"
-
"AOVERLAPS"
-
"B"
-
"BEFORE"
-
"BEGINS"
-
"BEGUNBY"
-
"BETWEEN"
-
"CONTAINED BY"
-
"CONTAINS"
-
"CROSSES"
-
"DISJOINT"
-
"DURING"
-
"E"
-
"ENDEDBY"
-
"ENDS"
-
"ENVELOPE"
-
"EQUALS"
-
"F"
-
"FALSE"
-
"GEOMETRYCOLLECTION"
-
"IN"
-
"INTERSECTS"
-
"LIKE"
-
"LINESTRING"
-
"MEETS"
-
"METBY"
-
"MULTILINESTRING"
-
"MULTIPOINT"
-
"MULTIPOLYGON"
-
"NOCASE"
-
"NOT"
-
"NULL";
-
"OR"
-
"OVERLAPPEDBY"
-
"OVERLAPS"
-
"POINT"
-
"POLYGON"
-
"T"
-
"TCONTAINS"
-
"TEQUALS"
-
"TOUCHES"
-
"TOVERLAPS"
-
"TRUE"
-
"WITHIN"
-
"X"
-
"Z"
Requirement 31 |
/req/cql-text/filter-lang |
Condition |
Server implements requirements class Filter |
A |
If a filter expression is encoded as text, this SHALL be indicated using the value |
Requirement 32 |
/req/cql-text/simple-cql |
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 Simple CQL requirements class. |
Requirement 33 |
/req/cql-text/enhanced-spatial-operators |
Condition |
Server implements requirements class Enhanced Spatial Operators |
A |
The server SHALL be able to parse and evaluate all spatial operators encoded as a text string that validate against the BNF production fragment identified in the Enhanced Spatial Operators requirement. |
Requirement 34 |
/req/cql-text/temporal-operators |
Condition |
Server implements requirements class Enhanced Temporal Operators |
A |
The server SHALL be able to parse and evaluate all spatial operators encoded as a text string that validate against the BNF production fragment identified in the Enhanced Temporal Operators requirement. |
Requirement 35 |
/req/cql-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 fragment identified in the Functions requirement. |
The list of supported functions can be discovered via the Functions resource (i.e. path /functions
).
Requirement 36 |
/req/cql-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 fragment identified in the Arithmetic Expressions requirement. |
Requirement 37 |
/req/cql-text/arrays |
Condition |
Server implements requirements class Arrays |
A |
The server SHALL be able to parse and evaluate all array expressions encoded as a text string that validate against the BNF production fragment identified in the Array Expressions requirement. |
10.3. Requirements Class "CQL JSON"
Requirements Class |
|
http://www.opengis.net/spec/ogcapi-features-3/1.0/req/cql-json |
|
Target type |
Web API |
Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
|
Conditional Dependency |
This requirements class defines a JSON encoding of CQL. Such an encoding would be suitable as the body of an HTTP POST request.
Note
|
Attention is drawn to the fact that there exists an alternative JSON encoding for CQL based on the use of arrays that can be found here: https://github.com/tschaub/ogcapi-features/tree/json-array-expression/extensions/cql/jfe. The OGC API - Features Standards Working Group will review both encodings and decide which one to adopt. Feedback from implementers is welcome. |
Requirement 38 |
/req/cql-json/filter-lang |
Condition |
Server implements requirements class Filter |
A |
If a filter expression is encoded as JSON, this SHALL be indicated using the value |
Requirement 39 |
/req/cql-json/simple-cql |
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 CQL and that do not use the following schema components:
|
Requirement 40 |
/req/cql-json/enhanced-spatial-operators |
Condition |
Server implements requirements class Enhanced Spatial Operators |
A |
In addition to the Simple CQL requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema components:
|
Requirement 41 |
/req/cql-json/enhanced-temporal-operators |
Condition |
Server implements requirements class Enhanced Temporal Operators |
A |
In addition to the Simple CQL requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema components:
|
Requirement 42 |
/req/cql-json/functions |
Condition |
Server implements requirements class Functions |
A |
In addition to the Simple CQL requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:
|
The list of supported functions can be discovered via the Functions resource (i.e. path /functions
).
Requirement 43 |
/req/cql-json/arithmetic |
Condition |
Server implements requirements class Arithmetic Expressions |
A |
In addition to the Simple CQL requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:
|
Requirement 44 |
/req/cql-json/arrays |
Condition |
Server implements requirements class Arrays |
A |
In addition to the Simple CQL requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:
|
10.4. XML encoding
This OGC API - Features - Part 3 standard does not specifically define an XML-encoding for CQL. 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 a XML-encoding for filter expressions that closely matches most of the functionality of CQL.
11. Media Types
See OGC API - Features - Part 1: Core, Clause 10.
Note
|
Currently, there have not been plans to register media types for the CQL encodings. The reason is the assumption that filter expressions as such will rarely be used as requests or responses, but usually be part of a request or response and be embedded in it. If you have use cases where a CQL media type would be important, please consider adding a comment in this GitHub issue. |
12. Security Considerations
See OGC API - Features - Part 1: Core, Clause 11.
Annex A: Abstract Test Suite (Normative)
Note
|
Add conformance classes and test cases for all requirements classes and requirements once the requirements are final. |
Annex B: CQL BNF (Normative)
#
# MODULE: cql.bnf
# PURPOSE: A BNF grammar for the Common Query Language (CQL).
# HISTORY:
# DATE EMAIL DESCRIPTION
# 13-SEP-2019 pvretano[at]cubewerx.com Initial creation
# 28-OCT-2019 pvretano[at]cubewerx.com Initial checkin into github
# 22-NOV-2020 pvretano[at]cubewerx.com Updates based on issues
# 22-NOV-2020 portele[at]interactive-instruments.de Document restructuring
# 21-DEC-2020 pvretano[at]cubewerx.com Updates to resolve issues
#=============================================================================#
# A CQL filter is a logically connected expression of one or more predicates.
# Predicates include scalar or comparison predicates, spatial predicates or
# temporal predicates.
#=============================================================================#
booleanValueExpression = andExpression
| orExpression
| notExpression
| comparisonPredicate
| spatialPredicate
| temporalPredicate
| arrayPredicate
| subExpression;
andExpression = booleanValueExpression "AND" booleanValueExpression;
orExpression = booleanValueExpression "OR" booleanValueExpression;
notExpression = "NOT" booleanValueExpression;
subExpression = leftParen booleanValueExpression rightParen;
#=============================================================================#
# 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 = characterLiteral
| numericLiteral
| booleanLiteral
| propertyName
| function
| arithmeticExpression;
comparisonOperator = eq | neq | lt | gt | lteq | gteq;
neq = lt gt;
gteq = gt eq;
lteq = lt eq;
# LIKE predicate
#
isLikePredicate = scalarExpression "LIKE" patternExpression
["WILDCARD" quote alpha quote]
["SINGLECHAR" quote alpha quote]
["ESCAPECHAR" quote alpha quote]
["NOCASE" booleanLiteral] ;
patternExpression = characterLiteral;
# BETWEEN predicate
#
isBetweenPredicate = numericExpression ["NOT"] "BETWEEN"
numericExpression "AND" numericExpression;
numericExpression = numericLiteral
| propertyName
| function
| arithmeticExpression;
# IN LIST predicate
#
isInListPredicate = inListOperand ["NOT"] "IN" leftParen inList rightParen;
inList = inListOperand [ {comma inListOperand} ];
inListOperand = scalarExpression
| temporalLiteral
| spatialLiteral;
# IS NULL predicate
#
isNullPredicate = scalarExpression "IS" ["NOT"] "NULL";
#=============================================================================#
# A spatial predicate evaluates if two spatial expressions satisfy the
# specified spatial operator.
#=============================================================================#
spatialPredicate = spatialOperator
leftParen geomExpression comma geomExpression rightParen;
# NOTE: The buffer operators (DWITHIN and BEYOND) are not included because
# these are outside the scope of a "simple" core for CQL. These
# can be added as extensions.
#
spatialOperator = "INTERSECTS"
| "EQUALS"
| "DISJOINT"
| "TOUCHES"
| "WITHIN"
| "OVERLAPS"
| "CROSSES"
| "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 = spatialLiteral
| propertyName
| function;
#=============================================================================#
# A temporal predicate evaluates if two temporal expressions satisfy the
# specified temporal operator.
#=============================================================================#
temporalPredicate = temporalExpression temporalOperator temporalExpression;
temporalExpression = temporalLiteral
| propertyName
| function;
temporalOperator = "ANYINTERACTS"
| "BEFORE"
| "AFTER"
| "MEETS"
| "METBY"
| "TOVERLAPS"
| "OVERLAPPEDBY"
| "BEGINS"
| "BEGUNBY"
| "DURING"
| "TCONTAINS"
| "ENDS"
| "ENDEDBY"
| "TEQUALS";
#=============================================================================#
# An array predicate evaluates if two array expressions statisfy the
# specified comparison operator. The comparion operators include equality,
# not equal, less than, greater than, less than or equal, greater than or equal,
# superset, subset and overlap operators.
#=============================================================================#
arrayPredicate = arrayExpression arrayOperator arrayExpression;
# An array expression is a bracket-delimited, comma-separated list of array
# elements. An array element is either a character literal, a numeric literal,
# a geometric literal, a temporal literal, a property name, a function, an
# arithmetic expression or an array.
#
arrayExpression = propertyName | function | arrayLiteral;
arrayLiteral = leftBracket rightBracket
| leftBracket arrayElement [ { comma arrayElement } ] rightBracket;
arrayElement = characterLiteral
| numericLiteral
| booleanLiteral
| spatialLiteral
| temporalLiteral
| propertyName
| function
| arithmeticExpression
| arrayLiteral;
arrayOperator = "AEQUALS"
| "ACONTAINS"
| "CONTAINED BY"
| "AOVERLAPS";
#=============================================================================#
# An arithemtic expression is an expression composed of an arithmetic
# operand (a property name, a number or a function that returns a number),
# an arithmetic operators (+,-,*,/) and another arithmetic operand.
#=============================================================================#
arithmeticExpression = arithmeticOperand arithmeticOperator arithmeticOperand
| leftParen arithmeticExpression rightParen;
arithmeticOperator = plusSign | minusSign | asterisk | solidus;
arithmeticOperand = numericLiteral
| propertyName
| function;
#=============================================================================#
# Definition of a PROPERTYNAME
#=============================================================================#
propertyName = identifier;
identifier = identifierStart [ {colon | period | identifierPart} ]
| doubleQuote identifier doubleQuote;
identifierStart = alpha;
identifierPart = alpha | digit | dollar | underscore;
#=============================================================================#
# Definition of a FUNCTION
# The functions offered by an implementation are provided at `/functions`
#=============================================================================#
function = identifier leftParen {argumentList} rightParen;
argumentList = argument [ { comma argument } ];
argument = characterLiteral
| numericLiteral
| booleanLiteral
| spatialLiteral
| temporalLiteral
| propertyName
| function
| arithmeticExpression
| arrayExpression;
#=============================================================================#
# Definition of CHARACTER literals
#=============================================================================#
characterLiteral = characterStringLiteral
| bitStringLiteral
| hexStringLiteral;
characterStringLiteral = quote [ {character} ] quote;
bitStringLiteral = "B" quote [ {bit} ] quote;
hexStringLiteral = "X" quote [ {hexit} ] quote;
character = alpha | digit | extendedDigit | ideographic |
combiningChar | extender;
# alpha, digit, extendedDigit, ideographic, combiningChar and extender
# productions copied from https://www.w3.org/TR/REC-xml/#CharClasses
#
alpha = "\x0041".."\x005A" | "\x0061".."\x007A" | "\x00C0".."\x00D6" |
"\x00D8".."\x00F6" | "\x00F8".."\x00FF" | "\x0100".."\x0131" |
"\x0134".."\x013E" | "\x0141".."\x0148" | "\x014A".."\x017E" |
"\x0180".."\x01C3" | "\x01CD".."\x01F0" | "\x01F4".."\x01F5" |
"\x01FA".."\x0217" | "\x0250".."\x02A8" | "\x02BB".."\x02C1" |
"\x0386" | "\x0388".."\x038A" | "\x038C" |
"\x038E".."\x03A1" | "\x03A3".."\x03CE" | "\x03D0".."\x03D6" |
"\x03DA" | "\x03DC" | "\x03DE" |
"\x03E0" | "\x03E2".."\x03F3" | "\x0401".."\x040C" |
"\x040E".."\x044F" | "\x0451".."\x045C" | "\x045E".."\x0481" |
"\x0490".."\x04C4" | "\x04C7".."\x04C8" | "\x04CB".."\x04CC" |
"\x04D0".."\x04EB" | "\x04EE".."\x04F5" | "\x04F8".."\x04F9" |
"\x0531".."\x0556" | "\x0559" | "\x0561".."\x0586" |
"\x05D0".."\x05EA" | "\x05F0".."\x05F2" | "\x0621".."\x063A" |
"\x0641".."\x064A" | "\x0671".."\x06B7" | "\x06BA".."\x06BE" |
"\x06C0".."\x06CE" | "\x06D0".."\x06D3" | "\x06D5" |
"\x06E5".."\x06E6" | "\x0905".."\x0939" | "\x093D" |
"\x0958".."\x0961" | "\x0985".."\x098C" | "\x098F".."\x0990" |
"\x0993".."\x09A8" | "\x09AA".."\x09B0" | "\x09B2" |
"\x09B6".."\x09B9" | "\x09DC".."\x09DD" | "\x09DF".."\x09E1" |
"\x09F0".."\x09F1" | "\x0A05".."\x0A0A" | "\x0A0F".."\x0A10" |
"\x0A13".."\x0A28" | "\x0A2A".."\x0A30" | "\x0A32".."\x0A33" |
"\x0A35".."\x0A36" | "\x0A38".."\x0A39" | "\x0A59".."\x0A5C" |
"\x0A5E" | "\x0A72".."\x0A74" | "\x0A85".."\x0A8B" |
"\x0A8D" | "\x0A8F".."\x0A91" | "\x0A93".."\x0AA8" |
"\x0AAA".."\x0AB0" | "\x0AB2".."\x0AB3" | "\x0AB5".."\x0AB9" |
"\x0ABD" | "\x0AE0" | "\x0B05".."\x0B0C" |
"\x0B0F".."\x0B10" | "\x0B13".."\x0B28" | "\x0B2A".."\x0B30" |
"\x0B32".."\x0B33" | "\x0B36".."\x0B39" | "\x0B3D" |
"\x0B5C".."\x0B5D" | "\x0B5F".."\x0B61" | "\x0B85".."\x0B8A" |
"\x0B8E".."\x0B90" | "\x0B92".."\x0B95" | "\x0B99".."\x0B9A" |
"\x0B9C" | "\x0B9E".."\x0B9F" | "\x0BA3".."\x0BA4" |
"\x0BA8".."\x0BAA" | "\x0BAE".."\x0BB5" | "\x0BB7".."\x0BB9" |
"\x0C05".."\x0C0C" | "\x0C0E".."\x0C10" | "\x0C12".."\x0C28" |
"\x0C2A".."\x0C33" | "\x0C35".."\x0C39" | "\x0C60".."\x0C61" |
"\x0C85".."\x0C8C" | "\x0C8E".."\x0C90" | "\x0C92".."\x0CA8" |
"\x0CAA".."\x0CB3" | "\x0CB5".."\x0CB9" | "\x0CDE" |
"\x0CE0".."\x0CE1" | "\x0D05".."\x0D0C" | "\x0D0E".."\x0D10" |
"\x0D12".."\x0D28" | "\x0D2A".."\x0D39" | "\x0D60".."\x0D61" |
"\x0E01".."\x0E2E" | "\x0E30" | "\x0E32".."\x0E33" |
"\x0E40".."\x0E45" | "\x0E81".."\x0E82" | "\x0E84" |
"\x0E87".."\x0E88" | "\x0E8A" | "\x0E8D" |
"\x0E94".."\x0E97" | "\x0E99".."\x0E9F" | "\x0EA1".."\x0EA3" |
"\x0EA5" | "\x0EA7" | "\x0EAA".."\x0EAB" |
"\x0EAD".."\x0EAE" | "\x0EB0" | "\x0EB2".."\x0EB3" |
"\x0EBD" | "\x0EC0".."\x0EC4" | "\x0F40".."\x0F47" |
"\x0F49".."\x0F69" | "\x10A0".."\x10C5" | "\x10D0".."\x10F6" |
"\x1100" | "\x1102".."\x1103" | "\x1105".."\x1107" |
"\x1109" | "\x110B".."\x110C" | "\x110E".."\x1112" |
"\x113C" | "\x113E" | "\x1140" |
"\x114C" | "\x114E" | "\x1150" |
"\x1154".."\x1155" | "\x1159" | "\x115F".."\x1161" |
"\x1163" | "\x1165" | "\x1167" |
"\x1169" | "\x116D".."\x116E" | "\x1172".."\x1173" |
"\x1175" | "\x119E" | "\x11A8" |
"\x11AB" | "\x11AE".."\x11AF" | "\x11B7".."\x11B8" |
"\x11BA" | "\x11BC".."\x11C2" | "\x11EB" |
"\x11F0" | "\x11F9" | "\x1E00".."\x1E9B" |
"\x1EA0".."\x1EF9" | "\x1F00".."\x1F15" | "\x1F18".."\x1F1D" |
"\x1F20".."\x1F45" | "\x1F48".."\x1F4D" | "\x1F50".."\x1F57" |
"\x1F59" | "\x1F5B" | "\x1F5D" |
"\x1F5F".."\x1F7D" | "\x1F80".."\x1FB4" | "\x1FB6".."\x1FBC" |
"\x1FBE" | "\x1FC2".."\x1FC4" | "\x1FC6".."\x1FCC" |
"\x1FD0".."\x1FD3" | "\x1FD6".."\x1FDB" | "\x1FE0".."\x1FEC" |
"\x1FF2".."\x1FF4" | "\x1FF6".."\x1FFC" | "\x2126" |
"\x212A".."\x212B" | "\x212E" | "\x2180".."\x2182" |
"\x3041".."\x3094" | "\x30A1".."\x30FA" | "\x3105".."\x312C" |
"\xAC00".."\xD7A3";
digit = "\x0030".."\x0039";
ideographic = "\x4E00".."\x9FA5" | "\x3007" | "\x3021".."\x3029";
combiningChar = "\x0300".."\x0345" | "\x0360".."\x0361" | "\x0483".."\x0486" |
"\x0591".."\x05A1" | "\x05A3".."\x05B9" | "\x05BB".."\x05BD" |
"\x05BF" | "\x05C1".."\x05C2" | "\x05C4" |
"\x064B".."\x0652" | "\x0670" | "\x06D6".."\x06DC" |
"\x06DD".."\x06DF" | "\x06E0".."\x06E4" | "\x06E7".."\x06E8" |
"\x06EA".."\x06ED" | "\x0901".."\x0903" | "\x093C" |
"\x093E".."\x094C" | "\x094D" | "\x0951".."\x0954" |
"\x0962".."\x0963" | "\x0981".."\x0983" | "\x09BC" |
"\x09BE" | "\x09BF" | "\x09C0".."\x09C4" |
"\x09C7".."\x09C8" | "\x09CB".."\x09CD" | "\x09D7" |
"\x09E2".."\x09E3" | "\x0A02" | "\x0A3C" |
"\x0A3E" | "\x0A3F" | "\x0A40".."\x0A42" |
"\x0A47".."\x0A48" | "\x0A4B".."\x0A4D" | "\x0A70".."\x0A71" |
"\x0A81".."\x0A83" | "\x0ABC" | "\x0ABE".."\x0AC5" |
"\x0AC7".."\x0AC9" | "\x0ACB".."\x0ACD" | "\x0B01".."\x0B03" |
"\x0B3C" | "\x0B3E".."\x0B43" | "\x0B47".."\x0B48" |
"\x0B4B".."\x0B4D" | "\x0B56".."\x0B57" | "\x0B82".."\x0B83" |
"\x0BBE".."\x0BC2" | "\x0BC6".."\x0BC8" | "\x0BCA".."\x0BCD" |
"\x0BD7" | "\x0C01".."\x0C03" | "\x0C3E".."\x0C44" |
"\x0C46".."\x0C48" | "\x0C4A".."\x0C4D" | "\x0C55".."\x0C56" |
"\x0C82".."\x0C83" | "\x0CBE".."\x0CC4" | "\x0CC6".."\x0CC8" |
"\x0CCA".."\x0CCD" | "\x0CD5".."\x0CD6" | "\x0D02".."\x0D03" |
"\x0D3E".."\x0D43" | "\x0D46".."\x0D48" | "\x0D4A".."\x0D4D" |
"\x0D57" | "\x0E31" | "\x0E34".."\x0E3A" |
"\x0E47".."\x0E4E" | "\x0EB1" | "\x0EB4".."\x0EB9" |
"\x0EBB".."\x0EBC" | "\x0EC8".."\x0ECD" | "\x0F18".."\x0F19" |
"\x0F35" | "\x0F37" | "\x0F39" |
"\x0F3E" | "\x0F3F" | "\x0F71".."\x0F84" |
"\x0F86".."\x0F8B" | "\x0F90".."\x0F95" | "\x0F97" |
"\x0F99".."\x0FAD" | "\x0FB1".."\x0FB7" | "\x0FB9" |
"\x20D0".."\x20DC" | "\x20E1" | "\x302A".."\x302F" |
"\x3099" | "\x309A";
extendedDigit = "\x0660".."\x0669" | "\x06F0".."\x06F9" | "\x0966".."\x096F" |
"\x09E6".."\x09EF" | "\x0A66".."\x0A6F" | "\x0AE6".."\x0AEF" |
"\x0B66".."\x0B6F" | "\x0BE7".."\x0BEF" | "\x0C66".."\x0C6F" |
"\x0CE6".."\x0CEF" | "\x0D66".."\x0D6F" | "\x0E50".."\x0E59" |
"\x0ED0".."\x0ED9" | "\x0F20".."\x0F29";
extender = "\x00B7" | "\x02D0" | "\x02D1" |
"\x0387" | "\x0640" | "\x0E46" |
"\x0EC6" | "\x3005" | "\x3031".."\x3035" |
"\x309D".."\x309E" | "\x30FC".."\x30FE";
dollar = "$";
underscore = "_";
doubleQuote = "\"";
quote = "'";
leftBracket = "[";
rightBracket = "]";
leftParen = "(";
rightParen = ")";
asterisk = "*";
plusSign = "+";
comma = ",";
minusSign = "-";
period = ".";
dotdot = "..";
solidus = "/";
colon = ":";
lt = "<";
eq = "=";
gt = ">";
bit = "0" | "1";
hexit = digit | "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f";
#=============================================================================#
# Definition of NUMERIC literals
#=============================================================================#
numericLiteral = unsignedNumericLiteral | signedNumericLiteral;
unsignedNumericLiteral = exactNumericLiteral | approximateNumericLiteral;
signedNumericLiteral = [sign] exactNumericLiteral | approximateNumericLiteral;
exactNumericLiteral = unsignedInteger [ period [ unsignedInteger ] ]
| period unsignedInteger;
approximateNumericLiteral = mantissa "E" exponent;
mantissa = exactNumericLiteral;
exponent = signedInteger;
signedInteger = [ sign ] unsignedInteger;
unsignedInteger = {digit};
sign = plusSign | minusSign;
#=============================================================================#
# Boolean literal
#=============================================================================#
#
booleanLiteral = "TRUE" | "true" | "FALSE" | "false" |
"T" | "t" | "F" | "f" | "1" | "0";
#=============================================================================#
# 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.
#=============================================================================#
spatialLiteral = pointTaggedText
| linestringTaggedText
| polygonTaggedText
| multipointTaggedText
| multilinestringTaggedText
| multipolygonTaggedText
| geometryCollectionTaggedText
| envelopeTaggedText;
pointTaggedText = "POINT" pointText;
linestringTaggedText = "LINESTRING" lineStringText;
polygonTaggedText = "POLYGON" polygonText;
multipointTaggedText = "MULTIPOINT" multiPointText;
multilinestringTaggedText = "MULTILINESTRING" multiLineStringText;
multipolygonTaggedText = "MULTIPOLYGON" multiPolygonText;
geometryCollectionTaggedText = "GEOMETRYCOLLECTION" geometryCollectionText;
pointText = leftParen point rightParen;
point = xCoord yCoord [zCoord];
xCoord = signedNumericLiteral;
yCoord = signedNumericLiteral;
zCoord = signedNumericLiteral;
lineStringText = leftParen point {comma point} rightParen;
polygonText = leftParen lineStringText {comma lineStringText} rightParen;
multiPointText = leftParen pointText {comma pointText} rightParen;
multiLineStringText = leftParen lineStringText {comma lineStringText} rightParen;
multiPolygonText = leftParen polygonText {comma polygonText} rightParen;
geometryCollectionText = leftParen
spatialLiteral {comma spatialLiteral} rightParen;
envelopeTaggedText = "ENVELOPE" envelopeText;
envelopeText = leftParen westBoundLon comma southBoundLat comma [minElev comma] eastBoundLon comma northBoundLat [comma maxElev] rightParen;
westBoundLon = signedNumericLiteral;
eastBoundLon = signedNumericLiteral;
northBoundLat = signedNumericLiteral;
southBoundLat = signedNumericLiteral;
minElev = signedNumericLiteral;
maxElev = signedNumericLiteral;
#=============================================================================#
# Definition of TEMPORAL literals
#
# NOTE: Is the fact the time zones are supported too complicated for a
# simple CQL? Perhaps the "core" of CQL should just support UTC.
#=============================================================================#
temporalLiteral = instant | interval;
instant = fullDate | fullDate "T" utcTime;
interval = solidus
| solidus dotdot
| dotdot solidus
| instant solidus
| solidus instant
| instant solidus dotdot
| dotdot solidus instant
| instant solidus instant;
fullDate = dateYear "-" dateMonth "-" dateDay;
dateYear = digit digit digit digit;
dateMonth = digit digit;
dateDay = digit digit;
utcTime = timeHour ":" timeMinute ":" timeSecond [timeZoneOffset];
timeZoneOffset = "Z" | sign timeHour [[colon] timeMinute];
timeHour = digit digit;
timeMinute = digit digit;
timeSecond = digit digit [period digit {digit}];
Annex C: JSON schemas for CQL (Normative)
C.1. JSON Schema for CQL
The following document specifies the schema for CQL according to JSON Schema version '2019-09':
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"oneOf": [
{"$ref": "#/$defs/andExpression"},
{"$ref": "#/$defs/orExpression"},
{"$ref": "#/$defs/notExpression"},
{"$ref": "#/$defs/comparisonPredicate"},
{"$ref": "#/$defs/spatialPredicate"},
{"$ref": "#/$defs/temporalPredicate"},
{"$ref": "#/$defs/arrayPredicate"}
],
"$recursiveAnchor": true,
"$defs": {
"$comment": "=======================================================",
"$comment": "= BOOLEAN VALUE EXPRESSION =",
"$comment": "=======================================================",
"andExpression": {
"type": "object",
"required": ["and"],
"properties": {
"and": {
"type": "array",
"minItems": 2,
"items": {
"$recursiveRef": "#"
}
}
}
},
"orExpression": {
"type": "object",
"required": ["or"],
"properties": {
"or": {
"type": "array",
"minItems": 2,
"items": {
"$recursiveRef": "#"
}
}
}
},
"notExpression": {
"type": "object",
"required": ["not"],
"properties": {
"not": {
"type": "array",
"minItems": 1,
"maxItems": 1,
"items": {
"$recursiveRef": "#"
}
}
}
},
"$comment": "=======================================================",
"$comment": "= COMPARISON PREDICATES =",
"$comment": "=======================================================",
"comparisonPredicate" : {
"oneOf": [
{"$ref": "#/$defs/binaryComparisonPredicate"},
{"$ref": "#/$defs/isLikePredicate" },
{"$ref": "#/$defs/isBetweenPredicate"},
{"$ref": "#/$defs/isInListPredicate" },
{"$ref": "#/$defs/isNullPredicate" }
]
},
"binaryComparisonPredicate": {
"oneOf": [
{ "$ref": "#/$defs/eqExpression" },
{ "$ref": "#/$defs/ltExpression" },
{ "$ref": "#/$defs/gtExpression" },
{ "$ref": "#/$defs/lteExpression" },
{ "$ref": "#/$defs/gteExpression" }
]
},
"eqExpression": {
"type": "object",
"required": ["eq"],
"properties": {
"eq": { "$ref": "#/$defs/scalarOperands" }
}
},
"ltExpression": {
"type": "object",
"required": ["lt"],
"properties": {
"lt": { "$ref": "#/$defs/scalarOperands" }
}
},
"gtExpression": {
"type": "object",
"required": ["gt"],
"properties": {
"gt": { "$ref": "#/$defs/scalarOperands" }
}
},
"lteExpression": {
"type": "object",
"required": ["lte"],
"properties": {
"lte": { "$ref": "#/$defs/scalarOperands" }
}
},
"gteExpression": {
"type": "object",
"required": ["gte"],
"properties": {
"gte": { "$ref": "#/$defs/scalarOperands" }
}
},
"isBetweenPredicate": {
"type": "object",
"required": ["between"],
"properties": {
"between": {
"type": "object",
"required" : [ "value", "lower", "upper" ],
"properties": {
"value": { "$ref": "#/$defs/valueExpression" },
"lower": { "$ref": "#/$defs/scalarExpression" },
"upper": { "$ref": "#/$defs/scalarExpression" }
}
}
}
},
"isLikePredicate": {
"type": "object",
"required": ["like"],
"properties": {
"like": { "$ref": "#/$defs/scalarOperands" },
"wildcard": { "type": "string", "default": "%" },
"singleChar": { "type": "string", "default": "." },
"escapeChar": { "type": "string", "default": "\\" },
"nocase": { "type": "boolean", "default": true }
}
},
"isInListPredicate": {
"type": "object",
"required": ["in"],
"properties": {
"in": {
"type": "object",
"required": ["value","list"],
"properties": {
"value": { "$ref": "#/$defs/valueExpression" },
"list": {
"type": "array",
"items": {
"$ref": "#/$defs/valueExpression"
}
},
"nocase": {
"type": "boolean",
"default": true
}
}
}
}
},
"valueExpression": {
"oneOf": [
{"$ref": "#/$defs/scalarExpression"},
{"$ref": "#/$defs/spatialLiteral"},
{"$ref": "#/$defs/typedTemporalLiteral"}
]
},
"scalarOperands": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"$ref": "#/$defs/scalarExpression"
}
},
"scalarExpression": {
"oneOf": [
{"$ref": "#/$defs/scalarLiteral"},
{"$ref": "#/$defs/propertyRef"},
{"$ref": "#/$defs/functionRef"},
{"$ref": "#/$defs/arithmeticExpression"}
]
},
"isNullPredicate": {
"type": "object",
"required": [ "isNull" ],
"properties": {
"isNull": {
"$ref": "#/$defs/scalarExpression"
}
}
},
"$comment": "=======================================================",
"$comment": "= SPATIAL PREDICATES =",
"$comment": "=======================================================",
"spatialPredicate" : {
"oneOf": [
{"$ref": "#/$defs/intersectsExpression"},
{"$ref": "#/$defs/equalsExpression"},
{"$ref": "#/$defs/disjointExpression"},
{"$ref": "#/$defs/touchesExpression"},
{"$ref": "#/$defs/withinExpression"},
{"$ref": "#/$defs/overlapsExpression"},
{"$ref": "#/$defs/crossesExpression"},
{"$ref": "#/$defs/containsExpression"}
]
},
"intersectsExpression": {
"type": "object",
"required": ["intersects"],
"properties": {
"intersects": { "$ref": "#/$defs/spatialOperands" }
}
},
"equalsExpression": {
"type": "object",
"required": ["equals"],
"properties": {
"equals": { "$ref": "#/$defs/spatialOperands" }
}
},
"disjointExpression": {
"type": "object",
"required": ["disjoint"],
"properties": {
"disjoint": { "$ref": "#/$defs/spatialOperands" }
}
},
"touchesExpression": {
"type": "object",
"required": ["touches"],
"properties": {
"touches": { "$ref": "#/$defs/spatialOperands" }
}
},
"withinExpression": {
"type": "object",
"required": ["within"],
"properties": {
"within": { "$ref": "#/$defs/spatialOperands" }
}
},
"overlapsExpression": {
"type": "object",
"required": ["overlaps"],
"properties": {
"overlaps": { "$ref": "#/$defs/spatialOperands" }
}
},
"crossesExpression": {
"type": "object",
"required": ["crosses"],
"properties": {
"crosses": { "$ref": "#/$defs/spatialOperands" }
}
},
"containsExpression": {
"type": "object",
"required": ["contains"],
"properties": {
"contains": { "$ref": "#/$defs/spatialOperands" }
}
},
"spatialOperands": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"$ref": "#/$defs/geomExpression"
}
},
"geomExpression": {
"oneOf": [
{"$ref": "#/$defs/spatialLiteral"},
{"$ref": "#/$defs/propertyRef"},
{"$ref": "#/$defs/functionRef"}
]
},
"$comment": "=======================================================",
"$comment": "= TEMPORAL EXPRESSIONS =",
"$comment": "=======================================================",
"temporalPredicate" : {
"oneOf": [
{"$ref": "#/$defs/beforeExpression"},
{"$ref": "#/$defs/afterExpression"},
{"$ref": "#/$defs/meetsExpression"},
{"$ref": "#/$defs/metbyExpression"},
{"$ref": "#/$defs/toverlapsExpression"},
{"$ref": "#/$defs/overlappedbyExpression"},
{"$ref": "#/$defs/beginsExpression"},
{"$ref": "#/$defs/begunbyExpression"},
{"$ref": "#/$defs/duringExpression"},
{"$ref": "#/$defs/tcontainsExpression"},
{"$ref": "#/$defs/endsExpression"},
{"$ref": "#/$defs/endedbyExpression"},
{"$ref": "#/$defs/tequalsExpression"},
{"$ref": "#/$defs/anyinteractsExpression"}
]
},
"beforeExpression": {
"type": "object",
"required": ["before"],
"properties": {
"before": { "$ref": "#/$defs/temporalOperands" }
}
},
"afterExpression": {
"type": "object",
"required": ["after"],
"properties": {
"after": { "$ref": "#/$defs/temporalOperands" }
}
},
"meetsExpression": {
"type": "object",
"required": ["meets"],
"properties": {
"meets": { "$ref": "#/$defs/temporalOperands" }
}
},
"metbyExpression": {
"type": "object",
"required": ["metby"],
"properties": {
"metby": { "$ref": "#/$defs/temporalOperands" }
}
},
"toverlapsExpression": {
"type": "object",
"required": ["toverlaps"],
"properties": {
"toverlaps": { "$ref": "#/$defs/temporalOperands" }
}
},
"overlappedbyExpression": {
"type": "object",
"required": ["overlappedby"],
"properties": {
"overlappedby": { "$ref": "#/$defs/temporalOperands" }
}
},
"beginsExpression": {
"type": "object",
"required": ["begins"],
"properties": {
"begins": { "$ref": "#/$defs/temporalOperands" }
}
},
"begunbyExpression": {
"type": "object",
"required": ["begunby"],
"properties": {
"begunby": { "$ref": "#/$defs/temporalOperands" }
}
},
"duringExpression": {
"type": "object",
"required": ["during"],
"properties": {
"during": { "$ref": "#/$defs/temporalOperands" }
}
},
"tcontainsExpression": {
"type": "object",
"required": ["tcontains"],
"properties": {
"tcontains": { "$ref": "#/$defs/temporalOperands" }
}
},
"endsExpression": {
"type": "object",
"required": ["ends"],
"properties": {
"ends": { "$ref": "#/$defs/temporalOperands" }
}
},
"endedbyExpression": {
"type": "object",
"required": ["endedby"],
"properties": {
"endedby": { "$ref": "#/$defs/temporalOperands" }
}
},
"tequalsExpression": {
"type": "object",
"required": ["tequals"],
"properties": {
"tequals": { "$ref": "#/$defs/temporalOperands" }
}
},
"anyinteractsExpression": {
"type": "object",
"required": ["anyinteracts"],
"properties": {
"anyinteracts": { "$ref": "#/$defs/temporalOperands" }
}
},
"temporalOperands": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"$ref": "#/$defs/temporalExpression"
}
},
"temporalExpression": {
"oneOf": [
{"$ref": "#/$defs/temporalLiteral"},
{"$ref": "#/$defs/propertyRef"},
{"$ref": "#/$defs/functionRef"}
]
},
"$comment": "=======================================================",
"$comment": "= ARRAY PREDICATE =",
"$comment": "=======================================================",
"arrayPredicate" : {
"oneOf": [
{"$ref": "#/$defs/aequalsExpression"},
{"$ref": "#/$defs/acontainsExpression"},
{"$ref": "#/$defs/acontainedByExpression"},
{"$ref": "#/$defs/aoverlapsExpression"}
]
},
"aequalsExpression": {
"type": "object",
"required": ["aequals"],
"properties": {
"aequals": { "$ref": "#/$defs/arrayExpression" }
}
},
"acontainsExpression": {
"type": "object",
"required": ["acontains"],
"properties": {
"acontains": { "$ref": "#/$defs/arrayExpression" }
}
},
"acontainedByExpression": {
"type": "object",
"required": ["acontainedBy"],
"properties": {
"acontainedBy": { "$ref": "#/$defs/arrayExpression" }
}
},
"aoverlapsExpression": {
"type": "object",
"required": ["aoverlaps"],
"properties": {
"aoverlaps": { "$ref": "#/$defs/arrayExpression" }
}
},
"arrayExpression": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"oneOf": [
{ "$ref": "#/$defs/propertyRef" },
{ "$ref": "#/$defs/functionRef" },
{ "$ref": "#/$defs/arrayLiteral" }
]
}
},
"arrayLiteral": {
"type": "array",
"items": {
"oneOf": [
{"$ref": "#/$defs/scalarLiteral"},
{"$ref": "#/$defs/spatialLiteral"},
{"$ref": "#/$defs/typedTemporalLiteral"},
{ "$ref": "#/$defs/propertyRef" },
{ "$ref": "#/$defs/functionRef" },
{"$ref": "#/$defs/arithmeticExpression"},
{ "$ref": "#/$defs/arrayLiteral" }
]
}
},
"$comment": "=======================================================",
"$comment": "= ARITHMETIC EXPRESSIONS =",
"$comment": "=======================================================",
"arithmeticExpression": {
"oneOf": [
{"$ref": "#/$defs/addExpression" },
{"$ref": "#/$defs/subExpression" },
{"$ref": "#/$defs/mulExpression" },
{"$ref": "#/$defs/divExpression" }
]
},
"addExpression": {
"type": "object",
"required": ["+"],
"properties": {
"+": { "$ref": "#/$defs/arithmeticOperands" }
}
},
"subExpression": {
"type": "object",
"required": ["-"],
"properties": {
"-": { "$ref": "#/$defs/arithmeticOperands" }
}
},
"mulExpression": {
"type": "object",
"required": ["*"],
"properties": {
"*": { "$ref": "#/$defs/arithmeticOperands" }
}
},
"divExpression": {
"type": "object",
"required": ["*"],
"properties": {
"/": { "$ref": "#/$defs/arithmeticOperands" }
}
},
"arithmeticOperands": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"oneOf": [
{"$ref": "#/$defs/arithmeticExpression"},
{"$ref": "#/$defs/propertyRef"},
{"$ref": "#/$defs/functionRef"},
{"type": "number" }
]
}
},
"$comment": "=======================================================",
"$comment": "= PROPERTY REFERENCE =",
"$comment": "=======================================================",
"propertyRef": {
"type": "object",
"required": ["property"],
"properties": {
"propertyName": { "type": "string" }
}
},
"$comment": "=======================================================",
"$comment": "= FUNCTIONS =",
"$comment": "=======================================================",
"functionRef": {
"type": "object",
"required": ["function"],
"properties": {
"function": { "$ref": "#/$defs/function" }
}
},
"function": {
"type": "object",
"required": [ "name" ],
"properties": {
"name": { "type": "string" },
"arguments": {
"type": "array",
"items": {
"oneOf": [
{ "$ref": "#/$defs/scalarLiteral" },
{ "$ref": "#/$defs/spatialLiteral" },
{ "$ref": "#/$defs/typedTemporalLiteral" },
{ "$ref": "#/$defs/propertyRef" },
{ "$ref": "#/$defs/functionRef" },
{ "$ref": "#/$defs/arithmeticExpression" },
{ "$ref": "#/$defs/arrayLiteral" }
]
}
}
}
},
"$comment": "=======================================================",
"$comment": "= LITERALS =",
"$comment": "=======================================================",
"scalarLiteral": {
"oneOf": [
{ "type": "string" },
{ "type": "number" },
{ "type": "boolean"}
]
},
"spatialLiteral": {
"oneOf": [
{ "$ref": "#/$defs/geometryLiteral" },
{ "$ref": "#/$defs/envelopeLiteral" }
]
},
"geometryLiteral": {
"oneOf": [
{ "$ref": "#/$defs/point" },
{ "$ref": "#/$defs/linestring" },
{ "$ref": "#/$defs/polygon" },
{ "$ref": "#/$defs/multipoint" },
{ "$ref": "#/$defs/multilinestring" },
{ "$ref": "#/$defs/multipolygon" }
]
},
"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"
}
}
}
},
"envelopeLiteral": {
"type": "object",
"required": [ "bbox" ],
"properties": {
"bbox": { "$ref": "#/$defs/bbox" }
}
},
"bbox": {
"type": "array",
"oneOf": [
{ "minItems": 4, "maxItems": 4},
{ "minItems": 6, "maxItems": 6}
],
"items": {
"type": "number"
}
},
"temporalLiteral": {
"oneOf": [
{ "$ref": "#/$defs/timeString" },
{ "$ref": "#/$defs/periodString" }
]
},
"timeString": {
"oneOf": [
{ "type": "string", "format": "date" },
{ "type": "string", "format": "date-time" }
]
},
"periodString": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"oneOf": [
{ "$ref": "#/$defs/timeString" },
{ "type": "string", "enum": [".."] }
]
}
},
"typedTemporalLiteral": {
"oneOf": [
{ "$ref": "#/$defs/typedTimeString" },
{ "$ref": "#/$defs/typedPeriodString" }
]
},
"typedTimeString": {
"type": "object",
"required": ["datetime"],
"properties": {
"datetime": {
"$ref": "#/$defs/timeString"
}
}
},
"typedPeriodString": {
"type": "object",
"required": ["datetime"],
"properties": {
"datetime": {
"$ref": "#/$defs/periodString"
}
}
}
}
}
C.2. OpenAPI 3.0 schema for CQL
The following document specifies the schema for CQL as an OpenAPI 3.0 schema in YAML:
---
openapi: 3.0.3
info:
title: Schema of Common Query Language (CQL)
description: 'For use in OpenAPI 3.0 documents'
version: '1.0.0-draft.1'
paths: {}
components:
schemas:
booleanValueExpression:
type: object
oneOf:
- "$ref": "#/components/schemas/andExpression"
- "$ref": "#/components/schemas/orExpression"
- "$ref": "#/components/schemas/notExpression"
- "$ref": "#/components/schemas/comparisonPredicate"
- "$ref": "#/components/schemas/spatialPredicate"
- "$ref": "#/components/schemas/temporalPredicate"
- "$ref": "#/components/schemas/arrayPredicate"
andExpression:
type: object
required:
- and
properties:
and:
type: array
minItems: 2
items:
"$ref": "#/components/schemas/booleanValueExpression"
orExpression:
type: object
required:
- or
properties:
or:
type: array
minItems: 2
items:
"$ref": "#/components/schemas/booleanValueExpression"
notExpression:
type: object
required:
- not
properties:
not:
type: array
minItems: 1
maxItems: 1
items:
"$ref": "#/components/schemas/booleanValueExpression"
comparisonPredicate:
oneOf:
- "$ref": "#/components/schemas/binaryComparisonPredicate"
- "$ref": "#/components/schemas/isLikePredicate"
- "$ref": "#/components/schemas/isBetweenPredicate"
- "$ref": "#/components/schemas/isInListPredicate"
- "$ref": "#/components/schemas/isNullPredicate"
binaryComparisonPredicate:
oneOf:
- "$ref": "#/components/schemas/eqExpression"
- "$ref": "#/components/schemas/ltExpression"
- "$ref": "#/components/schemas/gtExpression"
- "$ref": "#/components/schemas/lteExpression"
- "$ref": "#/components/schemas/gteExpression"
eqExpression:
type: object
required:
- eq
properties:
eq:
"$ref": "#/components/schemas/scalarOperands"
ltExpression:
type: object
required:
- lt
properties:
lt:
"$ref": "#/components/schemas/scalarOperands"
gtExpression:
type: object
required:
- gt
properties:
gt:
"$ref": "#/components/schemas/scalarOperands"
lteExpression:
type: object
required:
- lte
properties:
lte:
"$ref": "#/components/schemas/scalarOperands"
gteExpression:
type: object
required:
- gte
properties:
gte:
"$ref": "#/components/schemas/scalarOperands"
isBetweenPredicate:
type: object
required:
- between
properties:
between:
type: object
required:
- value
- lower
- upper
properties:
value:
"$ref": "#/components/schemas/valueExpression"
lower:
"$ref": "#/components/schemas/scalarExpression"
upper:
"$ref": "#/components/schemas/scalarExpression"
isLikePredicate:
type: object
required:
- like
properties:
like:
"$ref": "#/components/schemas/scalarOperands"
wildcard:
type: string
default: "%"
singleChar:
type: string
default: "."
escapeChar:
type: string
default: "\\"
nocase:
type: boolean
default: true
isInListPredicate:
type: object
required:
- in
properties:
in:
type: object
required:
- value
- list
properties:
value:
"$ref": "#/components/schemas/valueExpression"
list:
type: array
items:
"$ref": "#/components/schemas/valueExpression"
nocase:
type: boolean
default: true
valueExpression:
oneOf:
- "$ref": "#/components/schemas/scalarExpression"
- "$ref": "#/components/schemas/spatialLiteral"
- "$ref": "#/components/schemas/typedTemporalLiteral"
scalarOperands:
type: array
minItems: 2
maxItems: 2
items:
"$ref": "#/components/schemas/scalarExpression"
scalarExpression:
oneOf:
- "$ref": "#/components/schemas/scalarLiteral"
- "$ref": "#/components/schemas/propertyRef"
- "$ref": "#/components/schemas/functionRef"
- "$ref": "#/components/schemas/arithmeticExpression"
isNullPredicate:
type: object
required:
- isNull
properties:
isNull:
"$ref": "#/components/schemas/scalarExpression"
spatialPredicate:
oneOf:
- "$ref": "#/components/schemas/intersectsExpression"
- "$ref": "#/components/schemas/equalsExpression"
- "$ref": "#/components/schemas/disjointExpression"
- "$ref": "#/components/schemas/touchesExpression"
- "$ref": "#/components/schemas/withinExpression"
- "$ref": "#/components/schemas/overlapsExpression"
- "$ref": "#/components/schemas/crossesExpression"
- "$ref": "#/components/schemas/containsExpression"
intersectsExpression:
type: object
required:
- intersects
properties:
intersects:
"$ref": "#/components/schemas/spatialOperands"
equalsExpression:
type: object
required:
- equals
properties:
equals:
"$ref": "#/components/schemas/spatialOperands"
disjointExpression:
type: object
required:
- disjoint
properties:
disjoint:
"$ref": "#/components/schemas/spatialOperands"
touchesExpression:
type: object
required:
- touches
properties:
touches:
"$ref": "#/components/schemas/spatialOperands"
withinExpression:
type: object
required:
- within
properties:
within:
"$ref": "#/components/schemas/spatialOperands"
overlapsExpression:
type: object
required:
- overlaps
properties:
overlaps:
"$ref": "#/components/schemas/spatialOperands"
crossesExpression:
type: object
required:
- crosses
properties:
crosses:
"$ref": "#/components/schemas/spatialOperands"
containsExpression:
type: object
required:
- contains
properties:
contains:
"$ref": "#/components/schemas/spatialOperands"
spatialOperands:
type: array
minItems: 2
maxItems: 2
items:
"$ref": "#/components/schemas/geomExpression"
geomExpression:
oneOf:
- "$ref": "#/components/schemas/spatialLiteral"
- "$ref": "#/components/schemas/propertyRef"
- "$ref": "#/components/schemas/functionRef"
temporalPredicate:
oneOf:
- "$ref": "#/components/schemas/beforeExpression"
- "$ref": "#/components/schemas/afterExpression"
- "$ref": "#/components/schemas/meetsExpression"
- "$ref": "#/components/schemas/metbyExpression"
- "$ref": "#/components/schemas/toverlapsExpression"
- "$ref": "#/components/schemas/overlappedbyExpression"
- "$ref": "#/components/schemas/beginsExpression"
- "$ref": "#/components/schemas/begunbyExpression"
- "$ref": "#/components/schemas/duringExpression"
- "$ref": "#/components/schemas/tcontainsExpression"
- "$ref": "#/components/schemas/endsExpression"
- "$ref": "#/components/schemas/endedbyExpression"
- "$ref": "#/components/schemas/tequalsExpression"
- "$ref": "#/components/schemas/anyinteractsExpression"
beforeExpression:
type: object
required:
- before
properties:
before:
"$ref": "#/components/schemas/temporalOperands"
afterExpression:
type: object
required:
- after
properties:
after:
"$ref": "#/components/schemas/temporalOperands"
meetsExpression:
type: object
required:
- meets
properties:
meets:
"$ref": "#/components/schemas/temporalOperands"
metbyExpression:
type: object
required:
- metby
properties:
metby:
"$ref": "#/components/schemas/temporalOperands"
toverlapsExpression:
type: object
required:
- toverlaps
properties:
toverlaps:
"$ref": "#/components/schemas/temporalOperands"
overlappedbyExpression:
type: object
required:
- overlappedby
properties:
overlappedby:
"$ref": "#/components/schemas/temporalOperands"
beginsExpression:
type: object
required:
- begins
properties:
begins:
"$ref": "#/components/schemas/temporalOperands"
begunbyExpression:
type: object
required:
- begunby
properties:
begunby:
"$ref": "#/components/schemas/temporalOperands"
duringExpression:
type: object
required:
- during
properties:
during:
"$ref": "#/components/schemas/temporalOperands"
tcontainsExpression:
type: object
required:
- tcontains
properties:
tcontains:
"$ref": "#/components/schemas/temporalOperands"
endsExpression:
type: object
required:
- ends
properties:
ends:
"$ref": "#/components/schemas/temporalOperands"
endedbyExpression:
type: object
required:
- endedby
properties:
endedby:
"$ref": "#/components/schemas/temporalOperands"
tequalsExpression:
type: object
required:
- tequals
properties:
tequals:
"$ref": "#/components/schemas/temporalOperands"
anyinteractsExpression:
type: object
required:
- anyinteracts
properties:
anyinteracts:
"$ref": "#/components/schemas/temporalOperands"
temporalOperands:
type: array
minItems: 2
maxItems: 2
items:
"$ref": "#/components/schemas/temporalExpression"
temporalExpression:
oneOf:
- "$ref": "#/components/schemas/temporalLiteral"
- "$ref": "#/components/schemas/propertyRef"
- "$ref": "#/components/schemas/functionRef"
arrayPredicate:
oneOf:
- "$ref": "#/components/schemas/aequalsExpression"
- "$ref": "#/components/schemas/acontainsExpression"
- "$ref": "#/components/schemas/acontainedByExpression"
- "$ref": "#/components/schemas/aoverlapsExpression"
aequalsExpression:
type: object
required:
- aequals
properties:
aequals:
"$ref": "#/components/schemas/arrayExpression"
acontainsExpression:
type: object
required:
- acontains
properties:
acontains:
"$ref": "#/components/schemas/arrayExpression"
acontainedByExpression:
type: object
required:
- acontainedBy
properties:
acontainedBy:
"$ref": "#/components/schemas/arrayExpression"
aoverlapsExpression:
type: object
required:
- aoverlaps
properties:
aoverlaps:
"$ref": "#/components/schemas/arrayExpression"
arrayExpression:
type: array
minItems: 2
maxItems: 2
items:
oneOf:
- "$ref": "#/components/schemas/propertyRef"
- "$ref": "#/components/schemas/functionRef"
- "$ref": "#/components/schemas/arrayLiteral"
arrayLiteral:
type: array
items:
oneOf:
- "$ref": "#/components/schemas/scalarLiteral"
- "$ref": "#/components/schemas/spatialLiteral"
- "$ref": "#/components/schemas/typedTemporalLiteral"
- "$ref": "#/components/schemas/propertyRef"
- "$ref": "#/components/schemas/functionRef"
- "$ref": "#/components/schemas/arithmeticExpression"
- "$ref": "#/components/schemas/arrayLiteral"
arithmeticExpression:
oneOf:
- "$ref": "#/components/schemas/addExpression"
- "$ref": "#/components/schemas/subExpression"
- "$ref": "#/components/schemas/mulExpression"
- "$ref": "#/components/schemas/divExpression"
addExpression:
type: object
required:
- "+"
properties:
"+":
"$ref": "#/components/schemas/arithmeticOperands"
subExpression:
type: object
required:
- "-"
properties:
"-":
"$ref": "#/components/schemas/arithmeticOperands"
mulExpression:
type: object
required:
- "*"
properties:
"*":
"$ref": "#/components/schemas/arithmeticOperands"
divExpression:
type: object
required:
- "/"
properties:
"/":
"$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:
propertyName:
type: string
functionRef:
type: object
required:
- function
properties:
function:
"$ref": "#/components/schemas/function"
function:
type: object
required:
- name
properties:
name:
type: string
arguments:
type: array
items:
oneOf:
- "$ref": "#/components/schemas/scalarLiteral"
- "$ref": "#/components/schemas/spatialLiteral"
- "$ref": "#/components/schemas/typedTemporalLiteral"
- "$ref": "#/components/schemas/propertyRef"
- "$ref": "#/components/schemas/functionRef"
- "$ref": "#/components/schemas/arithmeticExpression"
- "$ref": "#/components/schemas/arrayLiteral"
scalarLiteral:
oneOf:
- type: string
- type: number
- type: boolean
spatialLiteral:
oneOf:
- "$ref": "#/components/schemas/geometryLiteral"
- "$ref": "#/components/schemas/envelopeLiteral"
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"
geojson-bbox:
type: array
minItems: 4
maxItems: 4
items:
type: number
point:
title: GeoJSON Point
type: object
required:
- type
- coordinates
properties:
type:
type: string
enum:
- Point
coordinates:
type: array
minItems: 2
items:
type: number
bbox:
"$ref": "#/components/schemas/geojson-bbox"
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:
"$ref": "#/components/schemas/geojson-bbox"
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:
"$ref": "#/components/schemas/geojson-bbox"
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:
"$ref": "#/components/schemas/geojson-bbox"
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:
"$ref": "#/components/schemas/geojson-bbox"
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:
"$ref": "#/components/schemas/geojson-bbox"
envelopeLiteral:
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
temporalLiteral:
oneOf:
- "$ref": "#/components/schemas/timeString"
- "$ref": "#/components/schemas/periodString"
timeString:
oneOf:
- type: string
format: date
- type: string
format: date-time
periodString:
type: array
minItems: 2
maxItems: 2
items:
oneOf:
- type: string
format: date
- type: string
format: date-time
- type: string
enum:
- ..
typedTemporalLiteral:
oneOf:
- "$ref": "#/components/schemas/typedTimeString"
- "$ref": "#/components/schemas/typedPeriodString"
typedTimeString:
type: object
required:
- datetime
properties:
datetime:
"$ref": "#/components/schemas/timeString"
typedPeriodString:
type: object
required:
- datetime
properties:
datetime:
"$ref": "#/components/schemas/periodString"
Annex D: Revision History
Date | Release | Editor | Primary clauses modified | Description |
---|---|---|---|---|
2020-04-06 |
1.0.0-SNAPSHOT |
P. Vretanos |
all |
initial version |
2020-12-22 |
1.0.0-draft.1 |
P. Vretanos, C. Portele |
all |
version for OAB review |
2021-01-18 |
1.0.0-draft.2 |
P. Vretanos, C. Portele, C. Reed |
all |
include changes from OAB review |
2021-01-27 |
1.0.0-draft.2 |
C. Portele |
5.2, 10.2, 10.3 |
include changes from OGC-NA review, version for public review |
Annex E: Bibliography
-
Internet Engineering Task Force (IETF). RFC 5234: Augmented BNF for Syntax Specifications: ABNF [online]. Edited by D. Crocker, P. Overell. 2008 [viewed 2020-11-22]. Available at https://tools.ietf.org/rfc/rfc5234.txt
-
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://tools.ietf.org/id/draft-handrews-json-schema-02.txt
-
Internet Engineering Task Force (IETF). draft-handrews-json-schema-validation-02: JSON Schema Validation: A Vocabulary for Structural Validation of JSON [online]. Edited by A. Wright, H. Andrews, B. Hutton. 2019 [viewed 2020-11-22]. Available at https://tools.ietf.org/id/draft-handrews-json-schema-validation-02.txt
-
OpenAPI Initiative (OAI). OpenAPI Specification 3.0 [online]. 2020 [viewed 2020-03-16]. The latest patch version at the time of publication of this standard was 3.0.3, available at http://spec.openapis.org/oas/v3.0.3