From 05b4d553f48021af9bdcb35d83a0b0889b9dcc26 Mon Sep 17 00:00:00 2001 From: Clemens Portele Date: Wed, 23 Dec 2020 10:10:39 +0100 Subject: [PATCH] prepare 1.0.0-draft.1 of part 3 --- extensions/cql/standard/19-079.adoc | 2 +- extensions/cql/standard/19-079.html | 7066 +++++++++++++++++++++++++++ 2 files changed, 7067 insertions(+), 1 deletion(-) create mode 100644 extensions/cql/standard/19-079.html diff --git a/extensions/cql/standard/19-079.adoc b/extensions/cql/standard/19-079.adoc index 319a5303..4869cb73 100644 --- a/extensions/cql/standard/19-079.adoc +++ b/extensions/cql/standard/19-079.adoc @@ -31,7 +31,7 @@ |Publication Date:   |External identifier of this OGC(R) document: http://www.opengis.net/doc/IS/ogcapi-features-3/1.0 |Internal reference number of this OGC(R) document:    19-079 -|Version: link:http://docs.opengeospatial.org/DRAFTS/19-079.html[1.0.0-SNAPSHOT (Editor's draft)] +|Version: link:https://htmlpreview.github.io/?https://github.com/opengeospatial/ogcapi-features/blob/part3-1.0.0-draft.1/extensions/cql/standard/19-079.html[1.0.0-draft.1] |Latest Published Draft: n/a |Category: OGC(R) Implementation Specification |Editors: Panagiotis (Peter) A. Vretanos, Clemens Portele diff --git a/extensions/cql/standard/19-079.html b/extensions/cql/standard/19-079.html new file mode 100644 index 00000000..b60fc7c6 --- /dev/null +++ b/extensions/cql/standard/19-079.html @@ -0,0 +1,7066 @@ + + + + + + + +OGC API - Features - Part 3: Filtering and the Common Query Language (CQL) + + + + + +
+
+
+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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.1

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.

+
+
+
+
Table of Contents
+ +
+
+
+

i. Abstract

+
+
+

OGC API standards define modular API building blocks to spatially enable Web API +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 +of them is a separate standard.

+
+
+

A fundamental operation performed on a collection of resources is that of +filtering in order to obtain a subset of the data which contains resource +instances that satisfy some filtering criteria. This part, part 3, 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 can be used to specify +how resource instances in a source collection can be filtered to identify a +result set. Typically, CQL is used in query operations to identify the +subset of resources that should be included in a response document. +However, CQL can also be used in other operations (e.g. 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 or false. 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, 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.

+
+
+ + + + + +
+
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.

+
+
+

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.

    +
  • +
  • +

    interactive instruments GmbH

    +
  • +
+
+
+

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

+
+
+
+

1. Scope

+
+
+

This document specifies an extension to the OGC API - Features - +Part 1: Core standard that defines the behaviour 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 are:

+
+
+
    +
  • +

    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 this the Filter conformance class 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 have to 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 specification (i.e., bbox, datetime +and optionally collection-specific properties).

+
+
+

The specific set of operators defined in this conformance class are:

+
+
+
    +
  • +

    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

      +
    • +
    +
    +
  • +
+
+
+

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 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.

+
+
+
+
+

3. Roadmap

+
+
+

The content of the 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.

+
+
+
+
+

4. 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

    +
  • +
+
+
+
+
+

5. Terms, Definitions and Symbols

+
+
+

5.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.

+
+
+

5.1.1. filter

+
+

predicate encoded for transmission between systems

+
+
+
+

5.1.2. predicate

+
+

set of computational operations applied to a data instance which evaluate to true or false [Filter Encoding 2.0.2]

+
+
+
+
+

5.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

    +
  • +
+
+
+
+
+
+

6. Conventions and background

+
+
+

6.1. General remarks

+
+

See OGC API - Features - Part 1: Core, Clauses 5 and 6.

+
+
+
+ +
+

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.

    +
  • +
+
+
+
+

6.3. 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).

+
+
+
+

6.4. 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).

+
+
+
+

6.5. 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.

+
+
+
+
+
+

7. Requirements Class "Filter"

+
+
+

7.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.

+
+
+

This 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.

+
+
+

This requirements class also defines resources for discovering the list of +resource properties (and their types) that may be used to construct filter +expressions.

+
+
+
+

7.2. Queryables

+
+

This extension does not assume that the content schema of a +resource being queried is available for inspection and thus 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, e.g., 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 /queryables and the media type application/schema+json.

+

B

+

The queryables accessed at this path SHALL be valid for all collections identified in the Collections resource (path /collections).

+

C

+

The Queryables resource SHALL be referenced from the Landing Page resource +with a link with the link relation type http://www.opengis.net/def/rel/ogc/1.0/queryables.

+
+ ++++ + + + + + + + + + + + + + + + + + + +

Requirement 2

+

/req/filter/get-queryables-op-local

+

A

+

For every collection identified in the Collections resource (path + /collections), the server SHALL support the HTTP GET operation at the path + /collections/{collectionId}/queryables and the media type application/schema+json.

+

B

+

The parameter collectionId is each id property in the collections response (JSONPath: $.collections[*].id).

+

C

+

The Queryable resource SHALL be referenced from the Collection resource +with a link with the link relation type http://www.opengis.net/def/rel/ogc/1.0/queryables.

+
+ ++++ + + + + + + + + + + + + + + +

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 200.

+

B

+

For responses that use application/schema+json as the Content-Type of +the response, the response SHALL have the following characteristics:

+
+
+
    +
  • +

    The property $schema is http://json-schema.org/draft-07/schema# or +https://json-schema.org/draft/2019-09/schema.

    +
  • +
  • +

    The property $id is the URI of the resource without query parameters.

    +
  • +
  • +

    The type is object and each property is a queryable.

    +
  • +
+
+
+

To support clients, it is recommended to provide additional detail +about the meaning of the property and the possible values:

+
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Recommendation 1

+

/rec/filter/queryables-schema

+

A

+

Each property SHOULD have a human readable title (title) and where +necessary a description (description).

+

B

+

Each property SHOULD have a single type (type).

+

C

+

For string properties minLength, maxLength, enum and/or pattern +SHOULD be provided, where applicable.

+

D

+

For numeric properties multipleOf, minimum, exclusiveMinimum, +maximum, exclusiveMaximum SHOULD be provided, where applicable.

+

E

+

For integer properties that represent enumerated values, enum SHOULD +be provided.

+

F

+

For temporal properties, the property SHOULD be a string literal with +the appropriate format date-time, date, time, or duration.

+

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, https://geojson.org/schema/Point.json for a point geometry.

+

I

+

For array properties, the property SHOULD consist of items that are strings +or numbers.

+
+
+
Example 1. Queryables example
+
+
+
+
{
+  "$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"
+    }
+  }
+}
+
+
+
+
+
+
+

7.3. Parameter filter

+
+

This extension defines a general parameter, filter, whose value is a filter +expression to be applied when retrieving resources in order 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. /collections/{collectionId}/items) SHALL support a parameter filter with the following characteristics (using an OpenAPI Specification 3.0 fragment):

+
+
+
+
name: filter
+in: query
+required: false
+schema:
+  type: string
+style: form
+explode: false
+
+
+
+
+

7.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 +(e.g. at /search or /tiles) 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. This, of course, 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 400.

+
+
+

The following example illustrates a notional query on a hypothetical Query resource +that uses a CQL filter and references multiple collections:

+
+
+
Multi-collection filter example
+
+
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. +
+
+
+
+

7.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. /collections/{collectionId}/items) SHALL support a parameter filter-lang with the following characteristics (using an OpenAPI Specification 3.0 fragment):

+
+
+
+
name: filter-lang
+in: query
+required: false
+schema:
+  type: string
+  enum:
+     - 'cql-text'
+     - 'cql-json'
+  default: 'cql-text'
+style: form
+
+

B

+

The enum array in the schema of filter-lang SHALL list the filter encodings that the server supports for the resource.

+

C

+

The default value in the schema of filter-lang SHALL identify the filter encoding that the server will assume, if a filter is provided, but no filter-lang.

+
+
+

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.

+
+
+
+

7.6. Parameter filter-crs

+ ++++ + + + + + + + + + + +

Requirement 7

+

/req/filter/filter-crs-wgs84

+

A

+

If a HTTP GET operation on the path that fetches resource instances (e.g. /collections/{collectionId}/items) includes a filter parameter, but no filter-crs parameter, the server SHALL process all geometries in the filter expression using CRS84 (for coordinates without height) or CRS84h (for coordinates with height) as the coordinate reference system (CRS).

+
+ ++++ + + + + + + + + + + + + + + + + + + + + + + +

Requirement 8

+

/req/filter/filter-crs-param

+

Condition

A

+

The HTTP GET operation on the path that fetches resource instances (e.g. /collections/{collectionId}/items) SHALL support a parameter filter-crs with the following characteristics (using an OpenAPI Specification 3.0 fragment):

+
+
+
+
name: filter-crs
+in: query
+required: false
+schema:
+  type: string
+  format: uri-reference
+style: form
+explode: false
+
+

B

+

If a HTTP GET operation on the path that fetches resource instances (e.g. /collections/{collectionId}/items) includes the filter and the filter-crs parameter, the server SHALL process all geometries in the filter expression using the CRS identified by the URI in filter-crs.

+

C

+

The server SHALL return an error, if it does not support the CRS identified in filter-crs for the resource.

+
+
+
+

7.7. Interaction with other predicates

+ ++++ + + + + + + + + + + +

Requirement 9

+

/req/filter/mixing-expression

+

A

+

Other filter predicates supported by the server (e.g. bbox, datetime, etc.) SHALL be logically connected with the AND operator when mixed in a request with the filter parameter.

+
+
+
+

7.8. Filter expression languages

+
+

This extension 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.

+
+
+
+

7.9. Response

+ ++++ + + + + + + + + + + + + + + + + + + +

Requirement 10

+

/req/filter/response

+

A

+

The filter expression SHALL be evaluated for each item of the resource that is queried.

+

B

+

If the filter expression evaluates to TRUE then the item SHALL be included in the result set.

+

C

+

If the filter expression evaluates to FALSE then the item SHALL be excluded from the result set.

+
+
+
+
+
+

8. Requirements Class "Features Filter"

+
+
+

8.1. Overview

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + +

Requirements Class

http://www.opengis.net/spec/ogcapi-features-3/1.0/req/features-filter

Target type

Web API

Dependency

Requirements Class "Filter"

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 filtering parameters defined in this standard.

+
+
+
+

8.2. Features

+
+

8.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 /collections/{collectionId}/items path SHALL support the filter parameter as defined in the Parameter filter clause.

+
+ ++++ + + + + + + + + + + +

Requirement 12

+

/req/features-filter/filter-lang-param

+

A

+

The HTTP GET operation on the /collections/{collectionId}/items path SHALL support the filter-lang parameter as defined in the Parameter filter-lang clause.

+
+ ++++ + + + + + + + + + + +

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

A

+

The HTTP GET operation on the /collections/{collectionId}/items path SHALL support the filter-crs parameter as defined in the Parameter filter-crs clause.

+
+
+
+

8.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 TRUE then the feature SHALL be included in the result set.

+

D

+

If the filter expression OR any other specified filtering parameter (i.e. zero or more of bbox, datetime and property filters) evaluates to FALSE then the feature SHALL be excluded from the result set.

+
+
+
+
+
+
+

9. Requirements Class "Simple CQL"

+
+
+

9.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.

+
+
+
+

9.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 (e.g. presentation in the result set, being passed on +to the next predicate in the filter for further evaluation, etc.).

+
+
+

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 booleanValueExpression in CQL BNF with the following exceptions:

+
+
+
    +
  • +

    the rules arrayPredicate, function and arithmeticExpression do not have to be supported;

    +
  • +
  • +

    in rule spatialOperator only "INTERSECTS" has to be supported;

    +
  • +
  • +

    in rule temporalOperator only "ANYINTERACTS" has to be supported.

    +
  • +
+
+
+

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:

+
+
+ +
+
+

Examples of Simple CQL filter expressions are included in the subsequent sub-clauses.

+
+
+
+

9.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).

    +
  • +
+
+
+
Example 2. Literal examples
+
+
+
    +
  • +

    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. +
+
+
+
+

9.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 propertyName) SHALL be a queryable of the items in the collection.

+

B

+

The property name reference SHALL evaluate to a literal value or NULL.

+

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.

+
+
+
Example 3. Property reference in a scalar expression
+
+
+

In this example, the property windSpeed is used in a function that returns a number.

+
+
+
+
avg(windSpeed)
+
+
+
+
+
{ "function": { "name": "avg", "arguments": [ { "property": "windSpeed" } ] } }
+
+
+
+
+
+
+

9.5. Comparison predicates

+ ++++ + + + + + + + + + + + + + + +

Requirement 17

+

/req/simple-cql/binary-comparison-predicate

+

A

+

A binary comparison predicate as specified by rule binaryComparisonPredicate evaluates two scalar expressions to determine if the expressions satisfy the specified comparison operator. If the requirements of the operator are satisfied, then the predicate SHALL evaluate to the Boolean value TRUE; otherwise the predicate SHALL evaluate to the Boolean value FALSE.

+

B

+

Both scalar expressions (rules scalarExpression) in rule binaryComparisonPredicate SHALL evaluate to the same type of literal.

+
+
+
Example 4. Binary comparison predicates
+
+
+
+
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 isLikePredicate) tests whether a string value matches the specified pattern. If the value matches the pattern (rule patternExpression), then the predicate SHALL evaluate to the Boolean value TRUE; otherwise the predicate SHALL evaluate to the Boolean value FALSE.

+

B

+

The scalar expression (rule scalarExpression) in rule isLikePredicate SHALL evaluate to a characterLiteral.

+

C

+

The character specified using the WILDCARD modifier SHALL match zero of more characters in the test value.

+

D

+

The wildchar character SHALL not match the NULL value.

+

E

+

If the WILDCHAR modifier is not specified, the default wildcard character SHALL be "%".

+

F

+

The character specified using the SINGLECHAR modifier SHALL match exactly one characters in the test value.

+

G

+

If the SINGLECHAR modifier is not specified, the default singlechar character SHALL be "_".

+

H

+

The character specified using the ESCAPECHAR modifier SHALL be used to escape the WILDCHAR and/or SINGLECAHR characters in the pattern string.

+

I

+

If the ESCAPECHAR modifier is not specified, the default escapechar character SHALL be "\".

+

J

+

If NOCASE is TRUE, the comparison SHALL be case insensitive, if it is FALSE it SHALL be case sensitive. The default is TRUE.

+
+
+
Example 5. Example of a LIKE predicate
+
+
+
+
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 isBetweenPredicate) tests whether a numeric value +lies within the specified range. The between operator is inclusive. +If the value lies within the specified range, then the predicate +SHALL evaluate to the Boolean value TRUE; otherwise the predicate SHALL +evaluate to the Boolean value FALSE.

+

B

+

Any function (rule function) or property (rule propertyName) in rule isBetweenPredicate SHALL evaluate to a numericLiteral.

+
+
+
Example 6. Examples of a BETWEEN predicate
+
+
+
+
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 isInListPredicate) tests, for equality, the value of a scalar expression against a list of values of the same type. If the value on the left side of the predicate is equal to one or more of the values in the list on the right side of the predicate, the predicate SHALL evaluate to the Boolean value TRUE; otherwise the predicate SHALL evaluate to the Boolean value FALSE.

+

B

+

The items in the list of an in-list predicate (rule inListOperand, i.e., the items on the right hand side of the predicate) SHALL be of the same literal type as the value being tested by the predicate (rule inListOperand, i.e., the left hand side of the predicate), if evaluated.

+
+
+
Example 7. Examples of a IN predicate
+
+
+
+
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 isNullPredicate) tests whether the value of a scalar expression is null. If the value of the scalar expression is null, the predicate SHALL evaluate to the Boolean value TRUE; otherwise the null predicate SHALL evaluate to the Boolean value FALSE.

+
+
+
Example 8. Examples of a NULL predicate
+
+
+
+
geometry IS NOT NULL
+
+
+
+
+
{ "not": { "isNull" : { "property": "geometry" } } }
+
+
+
+
+
+
+

9.6. Spatial predicates

+ ++++ + + + + + + + + + + + + + + +

Requirement 22

+

/req/simple-cql/spatial-predicate

+

A

+

A spatial predicate evaluates two geometry-valued expressions to determine, if the expressions satisfy the requirements of the specified spatial operator. If the requirements of the operator are satisfied, then the predicate SHALL evaluate to the Boolean value TRUE; otherwise the predicate SHALL evaluate to the Boolean value FALSE.

+

B

+

The INTERSECTS operator SHALL be evaluated as defined in clause 6.1.15 of OpenGIS® Implementation Standard for Geographic information - Simple feature access - Part 1: Common architecture (except that in CQL the predicates evaluate to a Boolean, not an Integer).

+
+
+ + + + + +
+
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 specification, the filter-crs query parameter +is used to pass the CRS information to the server.

+
+
+
Example 9. Example spatial predicate
+
+
+
+
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]
+         ]
+      ]
+   }
+] }
+
+
+
+
+
+
Example 10. Example for the filter-crs query parameter
+
+
+
+
...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)))...
+
+
+
+
+
+
+

9.7. Temporal predicates

+ ++++ + + + + + + + + + + + + + + +

Requirement 23

+

/req/simple-cql/temporal-predicate

+

A

+

A temporal predicate evaluates two time-valued expressions to determine if the expressions satisfy the requirements of the specified temporal operator. If the requirements of the operator are satisfied, then the predicate SHALL evaluate to the Boolean value TRUE; otherwise the predicate SHALL evaluate to the Boolean value FALSE.

+

B

+

The ANYINTERACTS operator SHALL evaluate as (using the temporal operators from Requirements Class "Enhanced Temporal Operators"):

+
+
+
+
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.

+
+
+
Example 11. Examples temporal predicate
+
+
+
+
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.8. CQL Encodings

+
+

This standard defines a text encoding and a +JSON encoding of CQL that covers Simple CQL +and all enhanced capabilities specified in the next clause.

+
+
+
+
+
+

10. Common Query Language enhancements

+
+
+

10.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, the clause specifies requirements for the rules in CQL BNF not +supported by Simple CQL.

+
+
+
+

10.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

Requirements Class "Simple CQL"

+
+

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 spatialOperator in CQL BNF.

+

B

+

The spatial operators in addition to INTERSECTS SHALL be evaluated as defined in clause 6.1.15 of OpenGIS® Implementation Standard for Geographic information - Simple feature access - Part 1: Common architecture (except that in CQL the predicates evaluate to a Boolean, not an Integer).

+
+
+ + + + + +
+
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. +
+
+
+

The following table lists the mathematical definitions of each spatial operators +as described in OpenGIS® Implementation Standard for Geographic information - Simple feature access - Part 1: Common architecture.

+
+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1. Mathematical definitions of spatial operators
Spatial operatorDefinition

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.

+
+
+
+Touches +
+
Figure 1. Examples of the TOUCHES relationship
+
+
+
+Within +
+
Figure 2. Examples of the WITHIN relationship Polygon/Polygon(a), Polygon/LineString(b), LineString/LineString(c), and Polygon/Point(d)
+
+
+ + + + + +
+
Note
+
+If geometry a CONTAINS geometry b, then geometry b is WITHIN geometry a. +
+
+
+
+Overlaps +
+
Figure 3. Examples of the OVERLAPS relationship Polygon/LineString(a) and LineString/LineString(b)
+
+
+
+Crosses +
+
Figure 4. Examples of the CROSSES relationship Polygon/LineString(a) and LineString/LineString(b)
+
+
+
Example 12. Example of a spatial relationship between two literal geometries
+
+
+
+
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]
+         ]
+      }
+   ]
+}
+
+
+
+
+
+
Example 13. Example of a spatial relationship between a property and a literal geometry
+
+
+
+
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]
+         ]
+      }
+   ]
+}
+
+
+
+
+
+
Example 14. Example of a spatial relationship between a property and a function that return a geometry value.
+
+
+

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"]}}
+   ]
+}
+
+
+
+
+
+
+

10.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

Requirements Class "Simple CQL"

+
+

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 temporalOperator +in CQL BNF.

+

B

+

The spatial operators in addition to ANYINTERACTS SHALL be evaluated as defined in the +Time Ontology in OWL with the following mapping between CQL temporal operator names +and the property names defined in the Time Ontology in OWL:

+
+
+ +
+
+

CQL supports date and timestamps as time instants, but even the smallest "instant" has a +duration and can be evaluated as an interval, too. 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.

+
+
+
+TemporalOps +
+
Figure 5. The elementary relations between time intervals
+
+
+
Example 15. Examples of temporal relationships using temporal literals.
+
+
+
+
    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"]]
+}
+
+
+
+
+
+
Example 16. Examples of temporal relationships using a property and a temporal literal.
+
+
+
+
    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"]]
+}
+
+
+
+
+
+
+

10.4. Requirements Class "Functions"

+ ++++ + + + + + + + + + + + + + + + + +

Requirements Class

http://www.opengis.net/spec/ogcapi-features-3/1.0/req/functions

Target type

Web API

Dependency

Requirements Class "Simple CQL"

+
+

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 function in CQL BNF +with the exception of the rule arithmeticExpression in argument.

+

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 /functions path.

+
+ ++++ + + + + + + + + + + + + + + +

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 200.

+

B

+

The content of that response SHALL be based upon the following OpenAPI 3.0 schema +and list all functions that the server supports:

+
+
+
+
type: object
+required:
+- functions
+properties:
+  functions:
+    type: array
+    items:
+      type: object
+      required:
+      - name
+      - returns
+      properties:
+        name:
+          type: string
+        description:
+          type: string
+        metadataUrl:
+          type: string
+          format: uri-reference
+        arguments:
+          type: array
+          items:
+            type: object
+            required:
+            - type
+            properties:
+              title:
+                type: string
+              description:
+                type: string
+              type:
+                type: array
+                items:
+                  type: string
+                  enum:
+                  - string
+                  - number
+                  - integer
+                  - datetime
+                  - geometry
+                  - boolean
+        returns:
+          type: array
+          items:
+            type: string
+            enum:
+            - string
+            - number
+            - integer
+            - datetime
+            - geometry
+            - boolean
+
+
+
+
Example 17. Get functions JSON response example
+
+
+
+
{
+   "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"]
+      }
+   ]
+}
+
+
+
+
+
+
+

10.5. Requirements Class "Arithmetic Expressions"

+ ++++ + + + + + + + + + + + + + + + + +

Requirements Class

http://www.opengis.net/spec/ogcapi-features-3/1.0/req/arithmetic

Target type

Web API

Dependency

Requirements Class "Simple CQL"

+
+

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 +arithmeticExpression in CQL BNF with the exception of the rule function in arithmeticOperand.

+
+
+ + + + + +
+
Note
+
+Support for the BNF rule function is added by the requirements class Functions. +
+
+
+
Example 18. Predicate with an arithmetic expression finding all vehicles that are too tall to pass under a bridge.
+
+
+
+
vehicle_height > (bridge_height-1)
+
+
+
+
+
{
+   "gt": [{"property":"vehicle_height"},{"-":[{"property":"bridge_height"},1]}]
+}
+
+
+
+
+
+
+

10.6. Requirements class "Arrays"

+ ++++ + + + + + + + + + + + + + + + + +

Requirements Class

http://www.opengis.net/spec/ogcapi-features-3/1.0/req/arrays

Target type

Web API

Dependency

Requirements Class "Simple CQL"

+
+

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 arrayPredicate in CQL BNF +with the exception of the following rules:

+
+
+
    +
  • +

    function in arrayExpression, arrayElement

    +
  • +
  • +

    arithmeticExpression and function in arrayElement.

    +
  • +
+

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:

+
+
+
    +
  • +

    AEQUALS evaluates to the Boolean value TRUE, if both sets are identical; otherwise the predicate +SHALL evaluate to the Boolean value FALSE.

    +
  • +
  • +

    ACONTAINS evaluates to the Boolean value TRUE, if the first set is a superset of the second set; +otherwise the predicate SHALL evaluate to the Boolean value FALSE.

    +
  • +
  • +

    CONTAINED BY evaluates to the Boolean value TRUE, if the first set is a subset of the second set; +otherwise the predicate SHALL evaluate to the Boolean value FALSE.

    +
  • +
  • +

    AOVERLAPS evaluates to the Boolean value TRUE, if both sets share at least one common element; +otherwise the predicate SHALL evaluate to the Boolean value FALSE.

    +
  • +
+
+
+ + + + + +
+
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. +
+
+
+
Example 19. Evalute if the value of an array property contains the specified subset of values.
+
+
+
+
layer:ids ACONTAINS ["layers-ca","layers-us"]
+
+
+
+
+
{
+   "acontains": [{"property": "layer:ids"},["layers-ca","layers-us"]]
+}
+
+
+
+
+
+
+
+
+

11. Requirements classes for encodings

+
+
+

11.1. Overview

+
+

This clause specifies requirements for a text encoding and a JSON encoding of CQL.

+
+
+
+

11.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

Requirements Class "Simple CQL"

Conditional Dependency

Requirements Class "Enhanced Spatial Operators"

Conditional Dependency

Requirements Class "Enhanced Temporal Operators"

Conditional Dependency

Requirements Class "Functions"

Conditional Dependency

Requirements Class "Arithmetic Expressions"

Conditional Dependency

Requirements Class "Arrays"

Conditional Dependency

Requirements Class "Filter"

+
+

This requirements class defines a well known text encoding of CQL. Such an +encoding would be suitable for use with the a 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 cql-text as the value of the filter-lang parameter.

+
+ ++++ + + + + + + + + + + +

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.

+
+
+
+

11.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

Requirements Class "Simple CQL"

Conditional Dependency

Requirements Class "Enhanced Spatial Operators"

Conditional Dependency

Requirements Class "Enhanced Temporal Operators"

Conditional Dependency

Requirements Class "Functions"

Conditional Dependency

Requirements Class "Arithmetic Expressions"

Conditional Dependency

Requirements Class "Arrays"

Conditional Dependency

Requirements Class "Filter"

+
+

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 SWG will review both encodings and decide which one to adopt, feedback from implementations 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 cql-json as the value of the filter-lang parameter.

+
+ ++++ + + + + + + + + + + +

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:

+
+
+
    +
  • +

    "#/$defs/functionRef"

    +
  • +
  • +

    "#/$defs/arithmeticExpression"

    +
  • +
  • +

    "#/$defs/arrayPredicate"

    +
  • +
  • +

    "#/$defs/equalsExpression"

    +
  • +
  • +

    "#/$defs/disjointExpression"

    +
  • +
  • +

    "#/$defs/touchesExpression"

    +
  • +
  • +

    "#/$defs/withinExpression"

    +
  • +
  • +

    "#/$defs/overlapsExpression"

    +
  • +
  • +

    "#/$defs/crossesExpression"

    +
  • +
  • +

    "#/$defs/containsExpression"

    +
  • +
  • +

    "#/$defs/beforeExpression"

    +
  • +
  • +

    "#/$defs/afterExpression"

    +
  • +
  • +

    "#/$defs/meetsExpression"

    +
  • +
  • +

    "#/$defs/metbyExpression"

    +
  • +
  • +

    "#/$defs/toverlapsExpression"

    +
  • +
  • +

    "#/$defs/overlappedbyExpression"

    +
  • +
  • +

    "#/$defs/beginsExpression"

    +
  • +
  • +

    "#/$defs/begunbyExpression"

    +
  • +
  • +

    "#/$defs/duringExpression"

    +
  • +
  • +

    "#/$defs/tcontainsExpression"

    +
  • +
  • +

    "#/$defs/endsExpression"

    +
  • +
  • +

    "#/$defs/endedbyExpression"

    +
  • +
  • +

    "#/$defs/tequalsExpression"

    +
  • +
+
+ ++++ + + + + + + + + + + + + + + +

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:

+
+
+
    +
  • +

    "#/$defs/equalsExpression"

    +
  • +
  • +

    "#/$defs/disjointExpression"

    +
  • +
  • +

    "#/$defs/touchesExpression"

    +
  • +
  • +

    "#/$defs/withinExpression"

    +
  • +
  • +

    "#/$defs/overlapsExpression"

    +
  • +
  • +

    "#/$defs/crossesExpression"

    +
  • +
  • +

    "#/$defs/containsExpression"

    +
  • +
+
+ ++++ + + + + + + + + + + + + + + +

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:

+
+
+
    +
  • +

    "#/$defs/beforeExpression"

    +
  • +
  • +

    "#/$defs/afterExpression"

    +
  • +
  • +

    "#/$defs/meetsExpression"

    +
  • +
  • +

    "#/$defs/metbyExpression"

    +
  • +
  • +

    "#/$defs/toverlapsExpression"

    +
  • +
  • +

    "#/$defs/overlappedbyExpression"

    +
  • +
  • +

    "#/$defs/beginsExpression"

    +
  • +
  • +

    "#/$defs/begunbyExpression"

    +
  • +
  • +

    "#/$defs/duringExpression"

    +
  • +
  • +

    "#/$defs/tcontainsExpression"

    +
  • +
  • +

    "#/$defs/endsExpression"

    +
  • +
  • +

    "#/$defs/endedbyExpression"

    +
  • +
  • +

    "#/$defs/tequalsExpression"

    +
  • +
+
+ ++++ + + + + + + + + + + + + + + +

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:

+
+
+
    +
  • +

    "#/$defs/functionRef"

    +
  • +
+
+
+

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:

+
+
+
    +
  • +

    "#/$defs/arithmeticExpression"

    +
  • +
+
+ ++++ + + + + + + + + + + + + + + +

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:

+
+
+
    +
  • +

    "#/$defs/arrayPredicate"

    +
  • +
+
+
+
+

11.4. XML encoding

+
+

This specification does not specifically define an XML-encoding for CQL. +However, it is recognized that XML is still in common use and so +implementors 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.

+
+
+
+
+
+

12. Media Types

+
+ +
+ + + + + +
+
Note
+
+So far, 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 to add a comment in this GitHub issue. +
+
+
+
+
+

13. Security Considerations

+
+ +
+
+
+
+

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

+
+ +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
DateReleaseEditorPrimary clauses modifiedDescription

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

+
+
+
+
+

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

    +
  • +
+
+
+
+
+ + + + \ No newline at end of file