From 74f1488138ba7c2b103536d8f502cc1b40426eff Mon Sep 17 00:00:00 2001 From: ghobona Date: Mon, 5 Aug 2024 09:44:44 +0100 Subject: [PATCH 1/4] adds cql2 and ogc api features part 3 spec element mappings --- specification-elements/code/19-079r2.py | 63 + specification-elements/code/21-065r2.py | 63 + specification-elements/mappings/19-079r2.csv | 82 + specification-elements/mappings/21-065r2.csv | 214 + .../specifications/19-079r2.html | 4885 +++++ .../specifications/21-065r2.html | 15393 ++++++++++++++++ 6 files changed, 20700 insertions(+) create mode 100644 specification-elements/code/19-079r2.py create mode 100644 specification-elements/code/21-065r2.py create mode 100644 specification-elements/mappings/19-079r2.csv create mode 100644 specification-elements/mappings/21-065r2.csv create mode 100644 specification-elements/specifications/19-079r2.html create mode 100644 specification-elements/specifications/21-065r2.html diff --git a/specification-elements/code/19-079r2.py b/specification-elements/code/19-079r2.py new file mode 100644 index 00000000..5a46c639 --- /dev/null +++ b/specification-elements/code/19-079r2.py @@ -0,0 +1,63 @@ +# OGC API - Features - Part 3 + +def cleanString(intext): + intext = intext.replace("\"","") + if " + + + + + + +OGC API - Features - Part 3: Filtering + + + + + + +
+
+
+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Open Geospatial Consortium

Submission Date: 2024-03-26

Approval Date:  2024-05-23

Publication Date:  2024-07-26

External identifier of this OGC® document: http://www.opengis.net/doc/IS/ogcapi-features-3/1.0

Internal reference number of this OGC® document:    19-079r2

Version: 1.0

Latest Published Draft: n/a

Category: OGC® Implementation Specification

Editors: Panagiotis (Peter) A. Vretanos, Clemens Portele

+ +++ + + + + + +

OGC API - Features - Part 3: Filtering

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

Copyright notice

Copyright © 2024 Open Geospatial Consortium

To obtain additional rights of use, visit http://www.opengeospatial.org/legal/

+ +++ + + + + + +

Warning

+
+

This document is an OGC Member approved international standard. This document is available on a royalty free, non-discriminatory basis. Recipients of this document are invited to submit, with their comments, notification of any relevant patent rights of which they are aware and to provide supporting documentation.

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

Document type:    OGC® Standard

Document subtype:    Interface

Document stage:    Approved

Document language:  English

+
+
+

License Agreement

+
+
+

Permission is hereby granted by the Open Geospatial Consortium, ("Licensor"), free of charge and subject to the terms set forth below, to any person obtaining a copy of this Intellectual Property and any associated documentation, to deal in the Intellectual Property without restriction (except as set forth below), including without limitation the rights to implement, use, copy, modify, merge, publish, distribute, and/or sublicense copies of the Intellectual Property, and to permit persons to whom the Intellectual Property is furnished to do so, provided that all copyright notices on the intellectual property are retained intact and that each person to whom the Intellectual Property is furnished agrees to the terms of this Agreement.

+
+
+

If you modify the Intellectual Property, all copies of the modified Intellectual Property must include, in addition to the above copyright notice, a notice that the Intellectual Property includes modifications that have not been approved or adopted by LICENSOR.

+
+
+

THIS LICENSE IS A COPYRIGHT LICENSE ONLY, AND DOES NOT CONVEY ANY RIGHTS UNDER ANY PATENTS THAT MAY BE IN FORCE ANYWHERE IN THE WORLD.

+
+
+

THE INTELLECTUAL PROPERTY IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE DO NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE INTELLECTUAL PROPERTY WILL MEET YOUR REQUIREMENTS OR THAT THE OPERATION OF THE INTELLECTUAL PROPERTY WILL BE UNINTERRUPTED OR ERROR FREE. ANY USE OF THE INTELLECTUAL PROPERTY SHALL BE MADE ENTIRELY AT THE USER’S OWN RISK. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY CONTRIBUTOR OF INTELLECTUAL PROPERTY RIGHTS TO THE INTELLECTUAL PROPERTY BE LIABLE FOR ANY CLAIM, OR ANY DIRECT, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM ANY ALLEGED INFRINGEMENT OR ANY LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR UNDER ANY OTHER LEGAL THEORY, ARISING OUT OF OR IN CONNECTION WITH THE IMPLEMENTATION, USE, COMMERCIALIZATION OR PERFORMANCE OF THIS INTELLECTUAL PROPERTY.

+
+
+

This license is effective until terminated. You may terminate it at any time by destroying the Intellectual Property together with all copies in any form. The license will also terminate if you fail to comply with any term or condition of this Agreement. Except as provided in the following sentence, no such termination of this license shall require the termination of any third party end-user sublicense to the Intellectual Property which is in force as of the date of notice of such termination. In addition, should the Intellectual Property, or the operation of the Intellectual Property, infringe, or in LICENSOR’s sole opinion be likely to infringe, any patent, copyright, trademark or other right of a third party, you agree that LICENSOR, in its sole discretion, may terminate this license without any compensation or liability to you, your licensees or any other party. You agree upon termination of any kind to destroy or cause to be destroyed the Intellectual Property together with all copies in any form, whether held by you or by any third party.

+
+
+

Except as contained in this notice, the name of LICENSOR or of any other holder of a copyright in all or part of the Intellectual Property shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Intellectual Property without prior written authorization of LICENSOR or such copyright holder. LICENSOR is and shall at all times be the sole entity that may authorize you or any third party to use certification marks, trademarks or other special designations to indicate compliance with any LICENSOR standards or specifications. This Agreement is governed by the laws of the Commonwealth of Massachusetts. The application to this Agreement of the United Nations Convention on Contracts for the International Sale of Goods is hereby expressly excluded. In the event any provision of this Agreement shall be deemed unenforceable, void or invalid, such provision shall be modified so as to make it valid and enforceable, and as so modified the entire Agreement shall remain in full force and effect. No decision, action or inaction by LICENSOR shall be construed to be a waiver of any rights or remedies available to it.

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

i. Abstract

+
+
+

OGC API Standards define modular API building blocks to spatially enable Web APIs in a consistent way. The OpenAPI specification is used to define the API building blocks.

+
+
+

OGC API - Features provides API building blocks to create, modify and query +features on the Web. OGC API - Features is comprised of multiple parts. Each +part is a separate standard.

+
+
+

A fundamental operation performed on a collection of features is that of +filtering in order to obtain a subset of the data which contains feature +instances that satisfy some filtering criteria. Part three of the OGC API - Features Standard defines +query parameters (filter, filter-lang, filter-crs) to specify filter +criteria in a request to an API and the Queryables resource that declares the properties +of data in a collection that can be used in filter expressions.

+
+
+

ii. Keywords

+
+
+

The following are keywords to be used by search engines and document catalogues.

+
+
+

OGC, filter, expression, query, SQL, CQL2, 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.

    +
  • +
  • +

    Ecere Corporation

    +
  • +
  • +

    GeoSolutions di Giannecchini Simone & C. s.a.s.

    +
  • +
  • +

    interactive instruments GmbH

    +
  • +
  • +

    US Army Geospatial Center (AGC)

    +
  • +
+
+
+

v. Submitters

+
+
+

All questions regarding this submission should be directed to the editors or the submitters:

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

Name

Affiliation

Panagiotis (Peter) A. Vretanos (editor)

CubeWerx Inc.

Clemens Portele (editor)

interactive instruments GmbH

Andrea Aime

GeoSolutions di Giannecchini Simone & C. s.a.s.

Jeff Harrison

US Army Geospatial Center (AGC)

Jérôme Jacovella-St-Louis

Ecere Corporation

+
+
+
+

1. Scope

+
+
+

This document specifies an extension to the OGC API - Features - +Part 1: Core standard that defines the behavior of a server that supports +enhanced filtering capabilities expressed using the Common Query Language (CQL2).

+
+
+

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;

    +
  • +
  • +

    Support for CQL2 Text and CQL2 JSON as languages for filter expressions;

    +
  • +
  • +

    How the set of properties that can be used to construct filter expressions ("queryables") are published by a Web API.

    +
  • +
+
+
+
+
+

2. Conformance

+
+
+

This standard defines the following requirements classes, +grouped by their standardization target:

+
+
+ +
+
+

The Queryables requirements class defines the Queryables resource (at path /collections/{collectionId}/queryables) and its representation as a JSON Schema. Queryables can be used to determine the list of property names and their schemas that may be used to construct filter expressions.

+
+
+

The Queryables as Query Parameters requirements class adds the requirement to provide query parameters for queryables according to the recommendation in the section Parameters for filtering on feature properties in OGC API - Features - Part 1: Core.

+
+
+

The Filter requirements 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 requirements +class is:

+
+
+
    +
  • +

    filter - The filter expression.

    +
  • +
  • +

    filter-lang - The language used in the filter expression.

    +
  • +
  • +

    filter-crs - The coordinate reference system used in the filter expression, if Part 2 is supported.

    +
  • +
+
+
+

The Features Filter requirements class defines the +binding between the Filter requirements class and the +OGC API - Features - Part 1: Core standard.

+
+
+

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.

+
+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1. Conformance class URIs
Conformance classURI

Queryables

http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables

Queryables as Query Parameters

http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables-query-parameters

Filter

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

Features Filter

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

+
+

APIs that implement the Common Query Language (CQL2) Standard should advertize all supported CQL2 conformance classes in the Conformance Declaration, too.

+
+
+

2.1. Roadmap

+
+

The content of this sub-clause is informative.

+
+
+

Because the filter parameters are not exclusively useful for features, it is anticipated that the +Queryables and Filter requirements classes will eventually become parts of the OGC API - Common suite of standards thus +leaving the Queryables as Query Parameters and Features Filter requirements classes as part +3 of the OGC API - Features Standard.

+
+
+
+
+
+

3. References

+
+
+

The following normative documents contain provisions that, through reference in this text, constitute provisions of this document. For dated references, subsequent amendments to, or revisions of, any of these publications do not apply. For undated references, the latest edition of the normative document referred to applies.

+
+
+
    +
  • +

    Open Geospatial Consortium (OGC). OGC 17-069r4: OGC API - Features - Part 1: Core corrigendum [online]. Edited by C. Portele, P. Vretanos, C. Heazel. 2022 [viewed 2023-02-19]. Available at https://docs.ogc.org/is/17-069r4/17-069r4.html

    +
  • +
  • +

    Open Geospatial Consortium (OGC). OGC 18-058r1: OGC API - Features - Part 2: Coordinate Reference Systems by Reference corrigendum [online]. Edited by C. Portele, P. Vretanos. 2022 [viewed 2023-02-19]. Available at https://docs.ogc.org/is/18-058r1/18-058r1.html

    +
  • +
  • +

    Open Geospatial Consortium (OGC). OGC 21-065r1: Common Query Language (CQL2) [online]. Edited by P. Vretanos, C. Portele. to be published. Available at https://docs.ogc.org/is/21-065r1/21-065r1.html

    +
  • +
  • +

    Internet Engineering Task Force (IETF). draft-bhutton-json-schema-01: JSON Schema: A Media Type for Describing JSON Documents [online]. Edited by A. Wright, H. Andrews, B. Hutton, G. Dennis. 2022 [viewed 2024-02-28]. Available at https://json-schema.org/draft/2020-12/json-schema-core

    +
  • +
+
+
+
+
+

4. Terms, Definitions, Symbols and Abbreviated Terms

+
+
+

4.1. Terms and Definitions

+
+

This document used the terms defined in OGC Policy Directive 49, which is based on the ISO/IEC Directives, Part 2, Rules for the structure and drafting of International Standards. In particular, the word “shall” (not “must”) is the verb form used to indicate a requirement to be strictly followed to conform to this standard and OGC documents do not use the equivalent phrases in the ISO/IEC Directives, Part 2.

+
+
+

This document also uses terms defined in the OGC Standard for Modular specifications (OGC 08-131r3), also known as the 'ModSpec'. The definitions of terms such as standard, specification, requirement, and conformance test are provided in the ModSpec.

+
+
+

For the purposes of this document, the following additional terms and definitions apply.

+
+
+

4.1.1. collection

+
+

a body of resources that belong or are used together; an aggregate, set, or group of related resources (OGC 20-024, OGC API - Common - Part 2: Collections).

+
+
+
+

4.1.2. endpoint

+
+

a web address (URI) at which access can be gained to a service or resource

+
+
+
+

4.1.3. filter expression

+
+

predicate encoded for transmission between systems

+
+
+
+

4.1.4. predicate

+
+

set of computational operations applied to a data instance which evaluate to true or false (OGC Filter Encoding 2.0 Encoding Standard - With Corrigendum)

+
+
+
+

4.1.5. publisher

+
+

entity responsible for making a resource available (Dublin Core Metadata Initiative - DCMI Metadata Terms)

+
+
+ + + + + +
+
Note
+
+As content of OGC API Standards, a resource is typically published at an endpoint. +
+
+
+
+

4.1.6. queryable

+
+

a token that represents a property of a resource that can be used in a filter expression

+
+
+
+

4.1.7. resource

+
+

entity that might be identified (Dublin Core Metadata Initiative - DCMI Metadata Terms)

+
+
+ + + + + +
+
Note
+
+The term "resource", when used in the context of an OGC API Standard, should be understood to mean a web resource unless otherwise indicated. +
+
+
+
+

4.1.8. web resource

+
+

a resource that is identified by a HTTP URI.

+
+
+
+
+

4.2. Abbreviated terms

+
+
+
ABNF
+
+

Augmented Backus-Naur Form

+
+
API
+
+

Application Programming Interface

+
+
BNF
+
+

Backus-Naur Form

+
+
CQL2
+
+

Common Query Language

+
+
CRS
+
+

Coordinate Reference System

+
+
HTTP
+
+

Hypertext Transfer Protocol

+
+
HTTPS
+
+

Hypertext Transfer Protocol Secure

+
+
IANA
+
+

Internet Assigned Numbers Authority

+
+
JSON
+
+

JavaScript Object Notation

+
+
OGC
+
+

Open Geospatial Consortium

+
+
URI
+
+

Uniform Resource Identifier

+
+
WKT
+
+

Well-Known Text

+
+
YAML
+
+

YAML Ain’t Markup Language

+
+
+
+
+
+
+
+

5. Conventions and background

+
+
+

5.1. General remarks

+
+

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

+
+
+
+

5.2. Identifiers

+
+

The normative provisions in this standard are denoted by the URI http://www.opengis.net/spec/ogcapi-features-3/1.0.

+
+
+

All requirements and conformance tests that appear in this document are denoted by partial URIs which are relative to this base.

+
+
+
+ +
+

The following OGC link relation types are introduced in this document (no applicable link relation type in the IANA link relation type register 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 sub-resources of the link’s context.

    +
  • +
+
+
+

As an alternative, the Compact URI (CURIE) [ogc-rel:queryables] can be used, too, where a CURIE is an allowed value.

+
+
+
+

5.4. HTTP URIs

+
+

If URIs include reserved characters that are delimiters in the URI subcomponent, these have to be percent-encoded. See Clause 2 of RFC 3986 for details. Not all URIs in this document are properly percent-encoded for better readability.

+
+
+
+

5.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 obligatory dependencies. Every server implementing the requirements class has to conform to the referenced specification or requirements class.

+
+
+

In addition, requirements classes can also have conditional dependencies. Servers implementing the requirements class do not have to conform to the referenced specification or requirements class, but if they do, they have to conform to the requirements that identify the conditional dependency as a pre-condition for the normative statement.

+
+
+
+
+
+

6. Requirements Class "Queryables"

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

Requirements Class

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

Target type

Web API

+
+

This requirements class defines the Queryables resource for discovering a list of +resource properties with their types and constraints that may be used to construct filter +expressions on a collection of resources, for example, a set of features.

+
+
+

This Standard does not assume that the content schema of a +resource being queried is available for inspection. Therefore, a means needs +to exist to interrogate an endpoint to determine the names and types of the +properties that may be used to construct a filter expression +("queryables").

+
+
+

In addition, a publisher may want to support queryables that are not +directly represented as resource properties in the content schema of the +resource. Or the publisher may want to restrict filtering on certain +properties. For example, because the backend datastore has not been configured +to allow high-performance queries on those properties.

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

Requirement 2

+

/req/queryables/get-queryables-op

+

A

+

The Queryables resource SHALL support the HTTP GET operation and the media type application/schema+json.

+
+
+

The response is returned as a JSON Schema document that describes a single JSON object where each property is a queryable.

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

Requirement 3

+

/req/queryables/get-queryables-response

+

A

+

A successful execution of the operation SHALL be reported as a response +with an HTTP status code of 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 https://json-schema.org/draft/2020-12/schema.

    +
  • +
  • +

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

    +
  • +
  • +

    The type is object and each property is a queryable.

    +
  • +
+

C

+

Each property SHALL include a type member, except for spatial properties.

+

D

+

Each spatial property SHALL not include a type or $ref member.

+

E

+

Each spatial property SHALL include a format member with a string value "geometry", followed by a hyphen, followed by the name of the geometry type in lower case. I.e., the values for the Simple Feature geometry types are: "geometry-point", "geometry-multipoint", "geometry-linestring", "geometry-multilinestring", "geometry-polygon", "geometry-multipolygon", and "geometry-geometrycollection". In addition, the following special values are supported: "geometry-any" as the wildcard for any geometry type, "geometry-point-or-multipoint" for a Point or MultiPoint, "geometry-linestring-or-multilinestring" for a LineString or MultiLineString, and "geometry-polygon-or-multipolygon" for a Polygon or MultiPolygon.

+

F

+

Each temporal property SHALL be a string literal with the appropriate format (e.g., date-time or date for instances, depending on the temporal granularity).

+

G

+

The additionalProperties member with a value of true or false is used +to state the behavior with respect to properties that are not explicitly declared +in the queryables schema.

+
+
+

If additionalProperties is missing or has the default value true, +any property name is valid in a filter expression and the property reference SHALL +evaluate to null, if the property does not exist for a resource.

+
+
+

If additionalProperties is set to false, property references that are not +explicitly declared in the queryables schema SHALL result in a 400 response.

+
+
+ + + + + +
+
Note
+
+The queryables schema does not specify a schema of any object that can be retrieved from the API. JSON Schema is used for the queryables to have a consistent approach for describing schema information. The queryables schema describes a "virtual" resource view for the purpose of filtering. JSON Schema will also be used in Part 5: Schemas of OGC API Features to describe schemas for feature content. +
+
+
+

To support clients, providing additional detail about the meaning of the +queryable properties and their value range is recommended:

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

Recommendation 1

+

/rec/queryables/queryables-schema

+

A

+

Each property SHOULD have a human readable title (title) and, where necessary for the understanding of the property, a description (description).

+

B

+

The type SHOULD be one of the following values: string (string or temporal properties), number/integer (numeric properties), boolean (boolean properties), object (object properties) or array (array properties).

+

C

+

Properties that represent a URI SHOULD be represented as a string with format uri or uri-reference.

+

D

+

Properties that represent a URI template SHOULD be represented as a string with format uri-template.

+

E

+

Properties that represent a UUID SHOULD be represented as a string with format uuid.

+

F

+

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

+

G

+

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

+

H

+

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

+

I

+

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

+

J

+

The JSON Schema keywords SHOULD be constrained to the those mentioned in this recommendation and requirement /req/queryables/get-queryables-response.

+
+
+
Example 1. Queryables example
+
+
+
+
{
+  "$schema" : "https://json-schema.org/draft/2020-12/schema",
+  "$id" : "https://demo.ldproxy.net/zoomstack/collections/roads_national/queryables",
+  "type" : "object",
+  "title" : "National Roads",
+  "description" : "Lines representing the road network. A road is defined as a metalled way for vehicles.",
+  "properties" : {
+    "geom" : {
+      "title": "Centerline",
+      "description": "The geometry of the road.",
+      "x-ogc-role" : "primary-geometry",
+      "format" : "geometry-linestring"
+    },
+    "name" : {
+      "title" : "Road Name",
+      "description": "The common, human readable, name of the road.",
+      "type" : "string"
+    },
+    "number" : {
+      "title" : "Road Identifier",
+      "description": "The official number of the road.",
+      "type" : "string"
+    },
+    "type" : {
+      "title" : "Type",
+      "description": "The road type, one of 'Primary' or 'Motorway'.",
+      "enum" : [ "Primary", "Motorway" ],
+      "type" : "string"
+    },
+    "level" : {
+      "title" : "Level",
+      "enum" : [ 0, 1, 2 ],
+      "type" : "integer"
+    }
+  },
+  "additionalProperties" : false
+}
+
+
+
+
+
+
Example 2. Filtering on complex data structures
+
+
+

Queryables also support simplified filtering on complex data structures. This example illustrates one potential approach to define a queryable on specific SpatioTemporal Asset Catalog (STAC) assets. The following is a STAC snippet:

+
+
+
+
"features": [
+  {
+    "type": "Feature",
+    "assets": {
+      "B5": {
+        "eo:bands": [
+          {
+            "common_name": "nir",
+            "name": "B5"
+          }
+        ],
+        "href": "https://landsat-pds.s3.us-west-2.amazonaws.com/c1/L8/060/247/LC08_L1TP_060247_20180905_20180912_01_T1/LC08_L1TP_060247_20180905_20180912_01_T1_B5.TIF",
+        "type": "image/tiff; application=geotiff; profile=cloud-optimized"
+      }
+    }
+  }
+]
+
+
+
+

A common type of filter is to fetch only resources that have in their assets object a value that has an eo:bands value that contains a common_name value of "nir".

+
+
+

This could be implemented using a queryable common_band_names defined as an array of strings:

+
+
+
+
{
+  "$schema": "https://json-schema.org/draft/2020-12/schema",
+  "$id": "https://example.net/stac/collections/landsat/queryables",
+  "type": "object",
+  "title": "A STAC item",
+  "properties": {
+    "common_band_names": {
+      "title": "Common band names",
+      "description": "an array of common band names included in the assets",
+      "type" : "array",
+      "items": {
+        "type": "string"
+      }
+    }
+  }
+}
+
+
+
+

Internally this could be mapped to the following JSON Path for a STAC item (item):

+
+
+

item['assets'][*]['eo:bands'][\*]['common_name']

+
+
+

Note that the JSON Path is just included here to clarify the mapping. An implementation would use a mapping that fits its backend datastore, but these details are hidden from the user.

+
+
+

A client can now use, e.g., the CQL2 array predicates to filter with the queryable. Examples using the CQL2 text encoding:

+
+
+
    +
  • +

    A_CONTAINS(common_band_names, ["nir"]) - includes at least a 'nir' band

    +
  • +
  • +

    A_EQUALS(common_band_names, ["nir","blue"]) - 'nir' and 'blue' exist for the feature, but no other band

    +
  • +
+
+
+
+
+
+
+

7. Requirements Class "Queryables as Query Parameters"

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

Requirements Class

http://www.opengis.net/spec/ogcapi-features-3/1.0/req/queryables-query-parameters

Target type

Web API

Dependency

OGC API - Features - Part 1: Core, Requirements Class "Core"

Dependency

Requirements Class "Queryables"

+
+

This requirements class specifies a requirement to provide query parameters for queryables according to the recommendation in the section Parameters for filtering on feature properties in OGC API - Features - Part 1: Core.

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

Requirement 4

+

/req/queryables-query-parameters/parameters

+

A

+

For every feature collection, the server SHALL support the Queryables resource at the path + /collections/{collectionId}/queryables.

+

B

+

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

+

C

+

For every queryable of a feature collection that has a simple value (string, number, integer or boolean), +the collection SHALL support a query parameter at path /collections/{collectionId}/items +with the same schema as the schema of the queryable.

+

D

+

If the query parameter is provided in a request, the response SHALL only include +resources that match the provided value for the queryable.

+
+
+
Example 3. Queryables as Query Parameters example
+
+
+

The OpenAPI 3.0 definitions of the query parameters for the Queryables in Queryables example would be:

+
+
+
+
type_roads_national:
+  name: type
+  in: query
+  description: Filter the collection by property 'type' (Road Type).
+  required: false
+  style: form
+  explode: false
+  schema:
+    title: Road Type
+    description: The road type, one of 'Primary' or 'Motorway'.
+    type: string
+    enum:
+    - Primary
+    - Motorway
+name_roads_national:
+  name: name
+  in: query
+  description: Filter the collection by property 'name' (Road Name).
+  required: false
+  style: form
+  explode: false
+  schema:
+    title: Road Name
+    description: The common, human readable, name of the road.
+    type: string
+number_roads_national:
+  name: number
+  in: query
+  description: Filter the collection by property 'number' (Road Identifier).
+  required: false
+  style: form
+  explode: false
+  schema:
+    title: Road Identifier
+    description: The official number of the road.
+    type: integer
+    minimum: 1
+    maximum: 9999
+
+
+
+
+
+
+
+

8. Requirements Class "Filter"

+
+
+

8.1. Overview

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

Requirements Class

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

Target type

Web API

Dependency

Requirements Class "Queryables"

+
+

OGC API - Features - Part 1: Core defines two filtering parameters on the resource at path /collections/{collectionId}/items: bbox and datetime. OGC API - Features - Part 1: Core also adds support for simple equality predicates logically joined using the AND operator. These capabilities offer simple resource filtering for HTTP requests.

+
+
+

The Filter requirements class defines additional query parameters that allow more +complex filtering expressions to be specified when querying server resources.

+
+
+

Specifically, this clause defines the parameters, filter, filter-lang and +filter-crs.

+
+
+
+

8.2. Parameter filter

+
+

The Filter requirements class defines a general parameter, filter, whose +value is a filter expression to be applied when retrieving resources. This +is necessary to determine which resources should be included in a result set.

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

Requirement 5

+

/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 based on the following OpenAPI 3.0 fragment:

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

Recommendation 2

+

/rec/filter/queryables-schema

+

A

+

The filter parameter MAY specify a default value.

+
+
+
+

8.3. 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 based on the following OpenAPI 3.0 fragment:

+
+
+
+
name: filter-lang
+in: query
+required: false
+schema:
+  type: string
+  enum:
+     - 'cql2-text'
+     - 'cql2-json'
+  default: 'cql2-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 cql2-text is used to indicate that the value of the +filter parameter is the text encoding of CQL2.

+
+
+

The enumerated value cql2-json is used to indicate that the value of the +filter parameter is the JSON encoding of CQL2.

+
+
+

Servers that support other filtering languages can extend this list of values +as necessary although the meanings of any additional values are not described +in this Standard.

+
+
+
+

8.4. Parameter filter-crs

+
+

For reasons discussed in the W3C/OGC Spatial Data on the Web Best Practices document, spatial coordinates by default are in the coordinate reference system WGS 84 longitude and latitude for 2D coordinates and WGS 84 longitude, latitude and ellipsoidal height in meters for 3D coordinates. For servers that support geometries in other coordinate reference systems, the filter-crs parameter defined in this clause allows clients to assert which CRS is being used to encode geometric values in a filter expression. Otherwise, the filter-crs parameter has no use.

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

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 ellipsoidal height) as the coordinate reference system (CRS).

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

Requirement 8

+

/req/filter/filter-crs-param

+

Condition

+

Server supports additional coordinate reference systems

+

A

+

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

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

B

+

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

+
+
+ + + + + +
+
Note
+
+Discovery of the list of supported coordinate reference systems for use with the filter-crs parameter depends on the filterable resource. +
+
+ ++++ + + + + + + + + + + +

Recommendation 3

+

/rec/filter/filter-crs-list

+

A

+

The server SHOULD list the supported coordinate reference system URIs +as enums in the schema of the filter-crs parameter.

+
+
+
+

8.5. Interaction with other predicates

+
+

Servers can and often will support additional filtering parameters on filterable resources. This clause defines how the filter parameter and other filtering parameters should interact if specified in a single request.

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

Requirement 9

+

/req/filter/mixing-expressions

+

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.

+
+
+
+

8.6. CQL2 functions

+
+

If the server supports CQL2 and the requirements class "Functions", a resource, /functions is published that allows clients to discover the +list of functions that a server offers.

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

Requirement 10

+

/req/filter/get-functions-operation

+

Condition

+

Server implements Common Query Language (CQL2), requirements class "Functions"

+

A

+

A server SHALL support the HTTP GET operation at the /functions path.

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

Requirement 11

+

/req/filter/get-functions-response-json

+

Condition

+

Server implements Common Query Language (CQL2), requirements class "Functions"

+

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 4. Get functions JSON response example
+
+
+
+
{
+   "functions": [
+      {
+         "name": "min",
+         "arguments": [
+            {
+               "type": ["string","number","datetime"]
+            },
+            {
+               "type": ["string","number","datetime"]
+            },
+         ],
+         "returns": ["string","number","datetime"]
+      },
+      {
+         "name": "max",
+         "arguments": [
+            {
+               "type": ["string","number","datetime"]
+            },
+            {
+               "type": ["string","number","datetime"]
+            },
+         ],
+         "returns": ["string","number","datetime"]
+      },
+      {
+         "name": "geometryType",
+         "arguments": [
+            {
+               "type": ["geometry"]
+            }
+         ],
+         "returns": ["string"]
+      }
+   ]
+}
+
+
+
+
+
+
+

8.7. Filter expression languages

+
+

This Standard only specifies filter-lang values for the Common Query Language (CQL2). However, support for +this filter expression language is not mandatory and other languages +can be used as the value of the filter parameter, too.

+
+
+
+

8.8. Response

+
+

A filter expression defines a subset of items from a collection that should be presented in a query response.

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

Requirement 12

+

/req/filter/response

+

A

+

The filter expression SHALL be evaluated for each item of the collection being queried.

+

B

+

If the filter expression evaluates to 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.

+
+
+
+
+
+

9. Requirements Class "Features Filter"

+
+
+

9.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 filter parameters defined in the Filter conformance class as well as the Queryables resource defined in the Queryables conformance class.

+
+
+
+

9.2. Queryables

+
+

9.2.1. Operation

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

Requirement 13

+

/req/features-filter/get-queryables-op

+

A

+

For every feature collection, the server SHALL support the Queryables resource at the path + /collections/{collectionId}/queryables.

+

B

+

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

+
+
+
+
+

9.3. Feature Collection

+
+

9.3.1. Response

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

9.4. Features

+
+

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

+

/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 16

+

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

+

/rec/features-filter/text-encoding

+

A

+

If a filter expression can be represented for its intended use as text, servers SHOULD support the CQL2 text encoding.

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

Recommendation 5

+

/rec/features-filter/JSON-encoding

+

A

+

If a filter expression can be represented for its intended use as JSON, servers SHOULD support the CQL2 JSON encoding.

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

Requirement 17

+

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

+
+
+

Discovery of the list of supported coordinate reference systems for use with the filter-crs parameter is fully described in OGC API - Features - Part 2: Coordinate Reference Systems by Reference. Briefly, the list of supported CRSs can be found in the global list of CRS identifiers (path: /collections/crs) and/or the list of collection-specific CRS identifiers (path: /collections/{collectionsId}/crs).

+
+
+
+

9.4.2. Response

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

Requirement 18

+

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

+

E

+

The server SHALL respond with a 400 error, if a parameter value of filter, filter-lang or filter-crs is invalid.

+
+
+
+
+
+
+

10. Media Types

+
+ +
+
+
+

11. Security Considerations

+
+ +
+
+
+
+

Annex A: Abstract Test Suite (Normative)

+
+
+

This test suite uses the Given-When-Then notation to specify the tests.

+
+
+

In order to execute tests against the Web API under test, the Web API needs to support one of the specified encodings. Since all known implementations at this time support JSON, this test suite uses the JSON encoding and adds a dependency to the Conformance Class "JSON" in OGC API - Common - Part 1: Core for the general "Filter" tests and to the Conformance Class "GeoJSON" in OGC API - Features - Part 1: Core for the feature-specific tests.

+
+
+

The Web API under test can require authorization. Any Executable Test Suite implementing this test suite should implement the following security schemes supported by OpenAPI 3.0: HTTP Authorization schemes "basic" and "bearer", API keys, and OAuth2 flow "authorizationCode".

+
+
+

A.1. Conformance Class "Queryables"

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

Conformance Class

http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables

Target type

+

Web API

+

Requirements class

Dependency

+

OGC API - Common - Part 1: Core, Conformance Class "JSON"

+
+
+ + + + + +
+
Note
+
+The Conformance Class "JSON" in Common Core has a dependency to the Conformance Classes "Core" and "Landing Page"; that is, testing against "JSON" will automatically test against the dependencies. +
+
+
+

The following table lists input given to all tests in this conformance class:

+
+
+
    +
  • +

    The landing page URI of the OGC Web API ({apiURI});

    +
  • +
  • +

    A list of filterable resources in the API ({apiURI}/{pathToResource});

    +
  • +
  • +

    Authentication credentials (optional);

    +
  • +
+
+
+

A.1.1. Conformance Test 1

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

Test id:

+

/conf/queryables/get-conformance

+

Requirements:

+

n/a

+

Test purpose:

+

Check that the API declares support for the conformance class

+

Test method:

+

Given:

+
+
+
    +
  • +

    n/a

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    the request for the Conformance Declaration is executed

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/conformance

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (status code is "200", Content-Type header is "application/json");

    +
  • +
  • +

    assert that $.conformsTo is a string array that includes the value "http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables".

    +
  • +
+
+
+
+

A.1.2. Conformance Test 2

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

Test id:

+

/conf/queryables/get-queryables-uris

+

Requirements:

Test purpose:

+

Check that a link to the Queryables resource exists for every filterable resource

+

Test method:

+

Given:

+
+
+
    +
  • +

    the list of filterable resources ({apiURI}/{pathToResource});

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request is executed for every filterable resource

    +
    +
      +
    • +

      method: HEAD (if HEAD results in a 405 response, use GET instead)

      +
    • +
    • +

      path: {apiURI}/{pathToResource}

      +
    • +
    • +

      header: Accept: application/json

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (status code is "200");

    +
  • +
  • +

    assert that the response includes a Link header with rel set to http://www.opengis.net/def/rel/ogc/1.0/queryables;

    +
  • +
  • +

    store the href value as the Queryables URI for the filterable resource ({queryablesUri}).

    +
  • +
+
+
+
+

A.1.3. Conformance Test 3

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

Test id:

+

/conf/queryables/get-queryables

+

Requirements:

Test purpose:

+

Check that the Queryables resource exists for every filterable resource

+

Test method:

+

Given:

+
+
+
    +
  • +

    test "get-queryables-uris" was successful

    +
  • +
  • +

    the list of Queryables URIs for the filterable resources (list of {queryablesUri})

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    the request for the Queryables page is executed for every filterable resource

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {queryablesUri}

      +
    • +
    • +

      header: Accept: application/schema+json

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (status code is "200", Content-Type header is "application/schema+json");

    +
  • +
  • +

    assert that the value of the $schema member is "https://json-schema.org/draft/2020-12/schema"

    +
  • +
  • +

    assert that the value of the $id member is "{queryablesUri}".

    +
  • +
  • +

    assert that the value of the type member is "object".

    +
  • +
  • +

    assert that $.properties is a non-empty object;

    +
  • +
  • +

    assert that each member in $.properties has an object as its value and the object either includes type member or a format member whose value starts with geometry-;

    +
  • +
  • +

    assert that the response is a valid JSON Schema;

    +
  • +
  • +

    store the key of an arbitrary property with a type member as the sample queryable of the filterable resource;

    +
  • +
  • +

    store the key of an arbitrary property of the object as the spatial queryable of the filterable resource, if the value of member is an object that includes no type member and a format member with a value geometry-{type} where {type} is one of "point", "multipoint", "linestring", "multilinestring", "polygon", "multipolygon", "geometrycollection", "any", "point-or-multipoint", "linestring-or-multilinestring", or "polygon-or-multipolygon";

    +
  • +
  • +

    store the value of the additionalProperties member or true, if it is not provided.

    +
  • +
+
+
+ + + + + +
+
Note
+
+Sub-requirement G of /req/queryables/get-queryables-response can only be checked when executing filter queries in dependent conformance classes. +
+
+
+
+
+

A.2. Conformance Class "Queryables as Query Parameters"

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

Conformance Class

http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables-query-parameters

Target type

+

Web API

+

Requirements class

Dependency

+
+

The following table lists input given to all tests in this conformance class:

+
+
+
    +
  • +

    The landing page URI of the OGC Web API ({apiURI});

    +
  • +
  • +

    Authentication credentials (optional);

    +
  • +
  • +

    A list of filterable resources in the API ({apiURI}/{pathToResource}), where {pathToResource} is /collections/{collectionId}/items;

    +
  • +
  • +

    The media type of the response when accessing these resources ({responseMediaType})

    +
  • +
  • +

    The list of acceptable status codes for a successful filter execution (default: "200");

    +
  • +
  • +

    The list of acceptable status codes for an unsuccessful filter execution (default: "400");

    +
  • +
  • +

    A valid value for each queryable {queryable};

    +
  • +
  • +

    An invalid valid value for each queryable {queryable};

    +
  • +
  • +

    The information stored during the execution of conformance tests of conformance class "Queryables".

    +
  • +
+
+
+

A.2.1. Conformance Test 4

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

Test id:

+

/conf/queryables-query-parameters/get-conformance

+

Requirements:

+

n/a

+

Test purpose:

+

Check that the API declares support for the conformance class

+

Test method:

+

Given:

+
+
+
    +
  • +

    n/a

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    the request for the Conformance Declaration is executed

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/conformance

      +
    • +
    • +

      header: Accept: application/json

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (status code is "200", Content-Type header is "application/json");

    +
  • +
  • +

    assert that $.conformsTo is a string array that includes the value "http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables-query-parameters".

    +
  • +
+
+
+
+

A.2.2. Conformance Test 5

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

Test id:

+

/conf/queryables-query-parameters/query-param

+

Requirements:

Test purpose:

+

Check that query parameters for queryables are supported

+

Test method:

+

Given:

+
+
+
    +
  • +

    test "get-queryables" was successful

    +
  • +
  • +

    the list of collections

    +
  • +
  • +

    the sample queryable of every collection

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for every filterable resource that supports filtering is executed and every queryable (queryable) with a valid value for the queryable ({valid-value})

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/collections/{collectionId}/items

      +
    • +
    • +

      query parameters (before percent encoding): {queryable}={valid-value}

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (the status code is in the list of acceptable status codes for a successful execution, Content-Type header is {responseMediaType});

    +
  • +
  • +

    assert that each returned resource matches the filter.

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for every filterable resource that supports filtering is executed and every queryable (queryable) with an invalid value for the queryable ({invalid-value})

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/collections/{collectionId}/items

      +
    • +
    • +

      query parameters (before percent encoding): {queryable}={invalid-value}

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert unsuccessful execution (the status code is in the list of acceptable status codes for an unsuccessful execution).

    +
  • +
+
+
+
+
+

A.3. Conformance Class "Filter"

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

Conformance Class

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

Target type

+

Web API

+

Requirements class

Dependency

+
+

The following table lists input given to all tests in this conformance class:

+
+
+
    +
  • +

    The landing page URI of the OGC Web API ({apiURI});

    +
  • +
  • +

    Authentication credentials (optional);

    +
  • +
  • +

    The list of filterable resources in the API ({apiURI}/{pathToResource});

    +
  • +
  • +

    The media type of the response when accessing these resources ({responseMediaType})

    +
  • +
  • +

    The list of acceptable status codes for a successful filter execution (default: "200", "204");

    +
  • +
  • +

    The list of acceptable status codes for an unsuccessful filter execution (default: "400");

    +
  • +
  • +

    The name of the filter language to test ({filter-lang}; default: "cql2-text");

    +
  • +
  • +

    A flag that indicates whether the filter language is the default filter language;

    +
  • +
  • +

    A valid filter expression in the filter language for a queryable {queryable} ({filter-valid}; default: {queryable} IS NULL);

    +
  • +
  • +

    An invalid filter expression in the filter language ({filter-invalid}; default: THIS IS NOT A FILTER);

    +
  • +
  • +

    A valid bbox filter expression in the filter language for a spatial queryable {spatialQueryable} and two longitude/latitude positions in WGS 84 {x1}/{y1} and {x2}/{y2} ({bbox-filter}; default: S_INTERSECTS({spatialQueryable},BBOX({x1},{y1},{x2},{y2}));

    +
  • +
  • +

    A flag that indicates whether the API supports custom functions in filter expressions;

    +
  • +
  • +

    The information stored during the execution of conformance tests of conformance class "Queryables".

    +
  • +
+
+
+

A.3.1. Conformance Test 6

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

Test id:

+

/conf/filter/get-conformance

+

Requirements:

+

n/a

+

Test purpose:

+

Check that the API declares support for the conformance class

+

Test method:

+

Given:

+
+
+
    +
  • +

    n/a

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    the request for the Conformance Declaration is executed

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/conformance

      +
    • +
    • +

      header: Accept: application/json

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (status code is "200", Content-Type header is "application/json");

    +
  • +
  • +

    assert that $.conformsTo is a string array that includes the value "http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/filter".

    +
  • +
+
+
+
+

A.3.2. Conformance Test 7

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

Test id:

+

/conf/filter/filter-param

+

Requirements:

Test purpose:

+

Check that the query parameter filter is supported

+

Test method:

+

Given:

+
+
+
    +
  • +

    test "get-queryables" was successful

    +
  • +
  • +

    the list of filterable resources

    +
  • +
  • +

    the sample queryable of every filterable resource

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for each resource that supports filtering is executed without a filter parameter

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/{pathToResource}

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (the status code is in the list of acceptable status codes for a successful execution, Content-Type header is {responseMediaType});

    +
  • +
  • +

    store the result as the unfiltered result of the resource.

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for each resource that supports filtering is executed with a valid filter expression

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/{pathToResource}

      +
    • +
    • +

      query parameters (before percent encoding): filter-lang={filter-lang}&filter={filter-valid} where {queryable} in {filter-valid} is replaced by the sample queryable of the filterable resource

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (the status code is in the list of acceptable status codes for a successful execution, Content-Type header is {responseMediaType});

    +
  • +
  • +

    assert that each returned resource matches the filter expression.

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for each resource that supports filtering is executed with an invalid filter expression

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/{pathToResource}

      +
    • +
    • +

      query parameters (before percent encoding): filter-lang={filter-lang}&filter={filter-invalid} where {queryable} in {filter-invalid} is replaced by the sample queryable of the filterable resource

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert unsuccessful execution (the status code is in the list of acceptable status codes for an unsuccessful execution).

    +
  • +
+
+
+
+

A.3.3. Conformance Test 8

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

Test id:

+

/conf/filter/filter-lang-default

+

Requirements:

Test purpose:

+

Check that the query parameter filter-lang default value is supported

+

Test method:

+

Given:

+
+
+
    +
  • +

    test "get-queryables" was successful

    +
  • +
  • +

    the list of filterable resources

    +
  • +
  • +

    the queryables of every filterable resource

    +
  • +
  • +

    the filter language {filter-lang} is the default filter language

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for each resource that supports filtering is executed with a valid filter expression

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/{pathToResource}

      +
    • +
    • +

      query parameters (before percent encoding): filter={filter-valid} where {queryable} in {filter-valid} is replaced by the sample queryable of the collection

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (the status code is in the list of acceptable status codes for a successful execution, Content-Type header is {responseMediaType});

    +
  • +
  • +

    assert that each returned resource matches the filter expression.

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for each resource that supports filtering is executed with an invalid filter expression

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/{pathToResource}

      +
    • +
    • +

      query parameters (before percent encoding): filter={filter-invalid} where {queryable} in {filter-invalid} is replaced by the sample queryable of the collection

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert unsuccessful execution (the status code is in the list of acceptable status codes for an unsuccessful execution).

    +
  • +
+
+
+
+

A.3.4. Conformance Test 9

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

Test id:

+

/conf/filter/expression-construction

+

Requirements:

Test purpose:

+

Check that unknown queryables are rejected, if this is declared in the Queryables resource

+

Test method:

+

Given:

+
+
+
    +
  • +

    test "get-queryables" was successful

    +
  • +
  • +

    the list of filterable resources, reduced to those where additionalProperties is false`

    +
  • +
  • +

    the sample queryable of every filterable resource in the list

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for each resource is executed with a filter expression with an unsupported queryable

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/{pathToResource}

      +
    • +
    • +

      query parameters (before percent encoding): filter-lang={filter-lang}&filter={filter-valid} where {queryable} in {filter-valid} is replaced by "this_is_not_a_queryable"

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert unsuccessful execution (the status code is in the list of acceptable status codes for an unsuccessful execution).

    +
  • +
+
+
+
+

A.3.5. Conformance Test 10

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

Test id:

+

/conf/filter/filter-crs-wgs84

+

Requirements:

Test purpose:

+

Check that spatial predicates assume WGS84 by default

+

Test method:

+

Given:

+
+
+
    +
  • +

    test "get-queryables" was successful

    +
  • +
  • +

    the list of filterable resources with a spatial queryable

    +
  • +
  • +

    the spatial queryable of each filterable resource

    +
  • +
  • +

    the WGS84 bbox of the resources in each filterable resource

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for each filterable resource is executed with a filter expression with a spatial predicate

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/{pathToResource}

      +
    • +
    • +

      query parameters (before percent encoding): filter-lang={filter-lang}&filter={bbox-filter} where {spatialQueryable} in {bbox-filter} is replaced by the spatial queryable, {x1} is replaced by the west-bound longitude of the WGS84 bbox of the resource, {y1} by the south-bound latitude, {x2} by the east-bound longitude, and {y2} by the north-bound latitude

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (the status code is in the list of acceptable status codes for a successful execution, Content-Type header is {responseMediaType}).

    +
  • +
  • +

    assert that result contains the same features as the unfiltered result of the filterable resource.

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for each filterable resource with a filter expression with a spatial predicate

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/{pathToResource}

      +
    • +
    • +

      query parameters (before percent encoding): filter-lang={filter-lang}&filter={bbox-filter} where {spatialQueryable} in {bbox-filter} is replaced by the spatial queryable, {x1} is replaced by "1000000", {y1} by "1000000", {x2} by "2000000", and {y2} by "2000000"

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert unsuccessful execution (the status code is in the list of acceptable status codes for an unsuccessful execution).

    +
  • +
+
+
+
+

A.3.6. Conformance Test 11

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

Test id:

+

/conf/filter/filter-crs-param

+

Requirements:

Test purpose:

+

Check that spatial predicates assume WGS84 by default

+

Test method:

+

Given:

+
+
+
    +
  • +

    test "get-queryables" was successful

    +
  • +
  • +

    the list of filterable resources, that have a non-empty list of supported CRSs

    +
  • +
  • +

    the spatial queryable of every collection

    +
  • +
  • +

    the WGS84 bbox of every collection

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for each filterable resource and every CRS for that resource with a filter expression with a spatial predicate

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/{pathToResource}

      +
    • +
    • +

      query parameters (before percent encoding): filter-lang={filter-lang}&filter-crs={crsId}&filter={bbox-filter} where {spatialQueryable} in {bbox-filter} is replaced by the spatial queryable, {crsId} by the URI of the CRS, {x1} and {y1} by the coordinates of the west-bound longitude and south-bound latitude of the WGS84 bbox of the collection transformed to the CRS, and {x2} and {y2} by the coordinates of the east-bound longitude and north-bound latitude of the WGS84 bbox of the collection transformed to the CRS

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (the status code is in the list of acceptable status codes for a successful execution, Content-Type header is {responseMediaType});

    +
  • +
  • +

    assert that result contains the same features as the unfiltered result of the collection.

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for each filterable resource with a filter expression with a spatial predicate

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/{pathToResource}

      +
    • +
    • +

      query parameters (before percent encoding): filter-lang={filter-lang}&filter-crs={crsId}&filter={bbox-filter} where {spatialQueryable} in {bbox-filter} is replaced by the spatial queryable, {crsId} by "http://www.opengis.net/def/crs/OGC/0/does_not_exist", {x1} is replaced by the west-bound longitude of the WGS84 bbox of the collection, {y1} by the south-bound latitude, {x2} by the east-bound longitude, and {y2} by the north-bound latitude

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert unsuccessful execution (the status code is in the list of acceptable status codes for an unsuccessful execution).

    +
  • +
+
+
+
+

A.3.7. Conformance Test 12

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

Test id:

+

/conf/filter/get-functions

+

Requirements:

Test purpose:

+

Check that the Functions resource exists and is schema valid

+

Test method:

+

Given:

+
+
+
    +
  • +

    test "get-conformance" was successful

    +
  • +
  • +

    the API supports custom functions in filter expressions

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    the request for the Functions page is executed

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/functions

      +
    • +
    • +

      header: Accept: application/json

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (status code is "200", Content-Type header is "application/json");

    +
  • +
  • +

    assert that the response is valid against the OpenAPI 3.0 schema identified in the requirement.

    +
  • +
+
+
+ + + + + +
+
Note
+
+Requirement /req/filter/mixing-expression can only be checked in dependent conformance classes, when additional filtering parameters are known. +
+
+
+
+
+

A.4. Conformance Class "Features Filter"

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

Conformance Class

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

Target type

+

Web API

+

Requirements class

Dependency

Dependency

+

OGC API - Features - Part 1: Core, Conformance Class "GeoJSON"

+
+
+ + + + + +
+
Note
+
+The Conformance Class "GeoJSON" has a dependency to the Conformance Class "Core"; that is, testing against "GeoJSON" will automatically test against the dependencies. +
+
+
+

The following table lists input given to all tests in this conformance class:

+
+
+
    +
  • +

    The landing page URI of the OGC Web API ({apiURI});

    +
  • +
  • +

    Authentication credentials (optional);

    +
  • +
  • +

    The name of the filter language to test ({filter-lang}; default: "cql2-text");

    +
  • +
  • +

    A flag that indicates whether the filter language is the default filter language;

    +
  • +
  • +

    A valid filter expression in the filter language for a queryable {queryable} ({filter-valid}; default: {queryable} IS NULL);

    +
  • +
  • +

    An invalid filter expression in the filter language ({filter-invalid}; default: THIS IS NOT A FILTER);

    +
  • +
  • +

    A valid bbox filter expression in the filter language for a spatial queryable {spatialQueryable} and two longitude/latitude positions in WGS 84 {x1}/{y1} and {x2}/{y2} ({bbox-filter}; default: S_INTERSECTS({spatialQueryable},ENVELOPE({x1},{y1},{x2},{y2}));

    +
  • +
  • +

    A flag that indicates whether the API supports custom functions in filter expressions.

    +
  • +
+
+
+

A.4.1. Conformance Test 13

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

Test id:

+

/conf/features-filter/get-conformance

+

Requirements:

+

n/a

+

Test purpose:

+

Check that the API declares support for the conformance class

+

Test method:

+

Given:

+
+
+
    +
  • +

    n/a

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    the request for the Conformance Declaration is executed

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/conformance

      +
    • +
    • +

      header: Accept: application/json

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (status code is "200", Content-Type header is "application/json");

    +
  • +
  • +

    assert that $.conformsTo is a string array that includes the value "http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/features-filter".

    +
  • +
+
+
+
+

A.4.2. Conformance Test 14

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

Test id:

+

/conf/features-filter/get-collections

+

Requirements:

+

n/a

+

Test purpose:

+

Retrieve the list of collections provided by the API

+

Test method:

+

Given:

+
+
+
    +
  • +

    test "get-conformance" was successful

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    the request for the Collections page is executed

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/collections

      +
    • +
    • +

      header: Accept: application/json

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (status code is "200", Content-Type header is "application/json");

    +
  • +
  • +

    assert that $.collections is an array;

    +
  • +
  • +

    store the array as the list of collections.

    +
  • +
+
+
+
+

A.4.3. Conformance Test 15

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

Test id:

+

/conf/features-filter/get-collection

+

Requirements:

Test purpose:

+

Check that a link to the Queryables resource exists for every collection

+

Test method:

+

Given:

+
+
+
    +
  • +

    test "get-collections" was successful

    +
  • +
  • +

    the list of collections

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    the request for the Collection page is executed for every collection in the list (collectionId: JSONPath $.collections[*].id)

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {apiURI}/collections/{collectionId}

      +
    • +
    • +

      header: Accept: application/json

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (status code is "200", Content-Type header is "application/json");

    +
  • +
  • +

    assert that a non-negative integer n exists where $.links[{n}].rel is "http://www.opengis.net/def/rel/ogc/1.0/queryables" and where $.links[{n}].href is (after normalization) the URI {apiURI}/collections/{collectionId}/queryables;

    +
  • +
  • +

    store $.extent.spatial.bbox[0] as the WGS84 bbox of the collection

    +
  • +
  • +

    store $.crs[*] as the list of CRS supported for the collection

    +
  • +
+
+
+
+

A.4.4. Conformance Test 16

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

Test id:

+

/conf/features-filter/filter-on-items

+

Requirements:

Test purpose:

+

Check that the API supports filters on the Features resource.

+

Test method:

+

Given:

+
+
+
    +
  • +

    test "get-conformance" was successful

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    the tests for the "Filter" conformance class are executed with the following input parameters:

    +
    +
      +
    • +

      All input parameters given to this conformance class (see above);

      +
    • +
    • +

      The path template to the resource that supports filtering is {apiURI}/collections/{collectionId}/items with a response media type application/geo+json (GeoJSON);

      +
    • +
    • +

      The acceptable status codes for a successful filter execution are: "200";

      +
    • +
    • +

      The list of acceptable status codes for an unsuccessful filter execution are: "400".

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    the Web API under test passes the tests.

    +
  • +
+
+
+
+

A.4.5. Conformance Test 17

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

Test id:

+

/conf/features-filter/mixing-expression

+

Requirements:

Test purpose:

+

Check that a filter and a bbox parameter are evaluated with an AND

+

Test method:

+

Given:

+
+
+
    +
  • +

    test "get-queryables" was successful

    +
  • +
  • +

    the list of collections

    +
  • +
  • +

    the spatial queryable of every collection

    +
  • +
  • +

    the WGS84 bbox of every collection

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for the resource that supports filtering is executed for every collection in the list (collectionId: JSONPath $.collections[*].id) with a filter expression with a spatial predicate, where the collection has a WGS84 bbox and a spatial queryable

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {pathToResource}

      +
    • +
    • +

      query parameters (before percent encoding): filter-lang={filter-lang}&filter={bbox-filter}&bbox={x1},{y1},{x2},{y2} where {spatialQueryable} in {bbox-filter} is replaced by the spatial queryable, {x1} is replaced by the west-bound longitude of the WGS84 bbox of the collection, {y1} by the south-bound latitude, {x2} by the east-bound longitude, and {y2} by the north-bound latitude

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (the status code is in the list of acceptable status codes for a successful execution, Content-Type header is {responseMediaType}).

    +
  • +
  • +

    assert that result contains the same features as the unfiltered result of the collection.

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    a request for the resource that supports filtering is executed for every collection in the list (collectionId: JSONPath $.collections[*].id) with a filter expression with a spatial predicate, where the collection has a WGS84 bbox and a spatial queryable

    +
    +
      +
    • +

      method: GET

      +
    • +
    • +

      path: {pathToResource}

      +
    • +
    • +

      query parameters (before percent encoding): filter-lang={filter-lang}&filter={bbox-filter}&bbox={x3},{y3},{x4},{y4} where {spatialQueryable} in {bbox-filter} is replaced by the spatial queryable, {x1} is replaced by the west-bound longitude of the WGS84 bbox of the collection, {y1} by the south-bound latitude, {x2} by the east-bound longitude, {y2} by the north-bound latitude, and where the bbox {x3},{y3},{x4},{y4} does not intersect the WGS84 bbox of the collection

      +
    • +
    • +

      header: Accept: {responseMediaType}

      +
    • +
    • +

      authentication, if authentication credentials are provided

      +
    • +
    +
    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution (the status code is in the list of acceptable status codes for a successful execution, Content-Type header is {responseMediaType}).

    +
  • +
  • +

    assert that result contains no features.

    +
  • +
+
+
+
+
+
+
+
+

Annex B: 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

+

2021-01-18

1.0.0-SNAPSHOT

P. Vretanos, C. Portele, C. Reed

all

+

include changes from OAB review

+

2021-01-27

1.0.0-draft.2

C. Portele

5.2, 10.2, 10.3

+

include changes from OGC-NA review, version for public review

+

2021-09-27

1.0.0-SNAPSHOT

C. Portele

all

+

move CQL2 to its own standard

+

2024-03-07

1.0.0-rc.1

C. Portele, P. Vretanos

all

+

release candidate, submission for the OGC approval process

+

2024-03-26

1.0.0-rc.2

C. Portele, P. Vretanos

all

+

release candidate

+
+
+
    +
  • +

    #912 Changed requirement for a Link HTTP header to a recommendation.

    +
  • +
+
+
+
+
+
+

Annex C: 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://www.rfc-editor.org/rfc/rfc5234.html

    +
  • +
  • +

    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://datatracker.ietf.org/doc/html/draft-handrews-json-schema-02

    +
  • +
  • +

    Internet Assigned Numbers Authority (IANA). Link Relation Types [online, viewed 2020-03-16], Available at https://www.iana.org/assignments/link-relations/link-relations.xml

    +
  • +
  • +

    Open Geospatial Consortium (OGC). OGC Link Relation Type Register [online, viewed 2021-06-10], Available at http://www.opengis.net/def/rel

    +
  • +
  • +

    Open Geospatial Consortium (OGC). OGC CURIE Register [online, viewed 2023-04-24], Available at http://www.opengis.net/def/curie

    +
  • +
  • +

    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

    +
  • +
  • +

    Internet Engineering Task Force (IETF). RFC 3986: Uniform Resource Identifier (URI): Generic Syntax [online]. Edited by T. Berners-Lee, R. Fielding, L. Masinter. [viewed 2020-03-16]. Available at https://www.rfc-editor.org/rfc/rfc3986.html

    +
  • +
  • +

    ISO 8601-1:2019, Date and time — Representations for information interchange — Part 1: Basic rules

    +
  • +
  • +

    ISO 8601-2:2019, Date and time — Representations for information interchange — Part 2: Extensions

    +
  • +
  • +

    ISO 15836-2:2019, Information and documentation — The Dublin Core metadata element set — Part 2: DCMI Properties and classes

    +
  • +
  • +

    Open Geospatial Consortium (OGC) / World Wide Web Consortium (W3C): Spatial Data on the Web Best Practices [online]. Edited by J. Tandy, L. van den Brink, P. Barnaghi. 2017 [viewed 2020-03-16]. Available at https://www.w3.org/TR/sdw-bp/

    +
  • +
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/specification-elements/specifications/21-065r2.html b/specification-elements/specifications/21-065r2.html new file mode 100644 index 00000000..83ea7341 --- /dev/null +++ b/specification-elements/specifications/21-065r2.html @@ -0,0 +1,15393 @@ + + + + + + + +Common Query Language (CQL2) + + + + +
+ +
+
+
+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Open Geospatial Consortium

Submission Date: 2024-03-26

Approval Date:  2024-05-23

Publication Date:  2024-07-26

External identifier of this OGC® document: http://www.opengis.net/doc/IS/cql2/1.0

Internal reference number of this OGC® document:    21-065r2

Version: 1.0.0

Category: OGC Standard

Editors: Panagiotis (Peter) A. Vretanos, Clemens Portele

+ +++ + + + + + +

Common Query Language (CQL2)

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

Copyright notice

Copyright © 2024 Open Geospatial Consortium

To obtain additional rights of use, visit http://www.ogc.org/legal/

+ +++ + + + + + +

Warning

+
+

This document is an OGC Member approved international standard. This document is available on a royalty free, non-discriminatory basis. Recipients of this document are invited to submit, with their comments, notification of any relevant patent rights of which they are aware and to provide supporting documentation.

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

Document type:    OGC Standard

Document subtype:    Interface

Document stage:    Approved

Document language:  English

+
+
+

License Agreement

+
+
+

Permission is hereby granted by the Open Geospatial Consortium, ("Licensor"), free of charge and subject to the terms set forth below, to any person obtaining a copy of this Intellectual Property and any associated documentation, to deal in the Intellectual Property without restriction (except as set forth below), including without limitation the rights to implement, use, copy, modify, merge, publish, distribute, and/or sublicense copies of the Intellectual Property, and to permit persons to whom the Intellectual Property is furnished to do so, provided that all copyright notices on the intellectual property are retained intact and that each person to whom the Intellectual Property is furnished agrees to the terms of this Agreement.

+
+
+

If you modify the Intellectual Property, all copies of the modified Intellectual Property must include, in addition to the above copyright notice, a notice that the Intellectual Property includes modifications that have not been approved or adopted by LICENSOR.

+
+
+

THIS LICENSE IS A COPYRIGHT LICENSE ONLY, AND DOES NOT CONVEY ANY RIGHTS UNDER ANY PATENTS THAT MAY BE IN FORCE ANYWHERE IN THE WORLD.

+
+
+

THE INTELLECTUAL PROPERTY IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE DO NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE INTELLECTUAL PROPERTY WILL MEET YOUR REQUIREMENTS OR THAT THE OPERATION OF THE INTELLECTUAL PROPERTY WILL BE UNINTERRUPTED OR ERROR FREE. ANY USE OF THE INTELLECTUAL PROPERTY SHALL BE MADE ENTIRELY AT THE USER’S OWN RISK. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY CONTRIBUTOR OF INTELLECTUAL PROPERTY RIGHTS TO THE INTELLECTUAL PROPERTY BE LIABLE FOR ANY CLAIM, OR ANY DIRECT, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM ANY ALLEGED INFRINGEMENT OR ANY LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR UNDER ANY OTHER LEGAL THEORY, ARISING OUT OF OR IN CONNECTION WITH THE IMPLEMENTATION, USE, COMMERCIALIZATION OR PERFORMANCE OF THIS INTELLECTUAL PROPERTY.

+
+
+

This license is effective until terminated. You may terminate it at any time by destroying the Intellectual Property together with all copies in any form. The license will also terminate if you fail to comply with any term or condition of this Agreement. Except as provided in the following sentence, no such termination of this license shall require the termination of any third party end-user sublicense to the Intellectual Property which is in force as of the date of notice of such termination. In addition, should the Intellectual Property, or the operation of the Intellectual Property, infringe, or in LICENSOR’s sole opinion be likely to infringe, any patent, copyright, trademark or other right of a third party, you agree that LICENSOR, in its sole discretion, may terminate this license without any compensation or liability to you, your licensees or any other party. You agree upon termination of any kind to destroy or cause to be destroyed the Intellectual Property together with all copies in any form, whether held by you or by any third party.

+
+
+

Except as contained in this notice, the name of LICENSOR or of any other holder of a copyright in all or part of the Intellectual Property shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Intellectual Property without prior written authorization of LICENSOR or such copyright holder. LICENSOR is and shall at all times be the sole entity that may authorize you or any third party to use certification marks, trademarks or other special designations to indicate compliance with any LICENSOR standards or specifications. This Agreement is governed by the laws of the Commonwealth of Massachusetts. The application to this Agreement of the United Nations Convention on Contracts for the International Sale of Goods is hereby expressly excluded. In the event any provision of this Agreement shall be deemed unenforceable, void or invalid, such provision shall be modified so as to make it valid and enforceable, and as so modified the entire Agreement shall remain in full force and effect. No decision, action or inaction by LICENSOR shall be construed to be a waiver of any rights or remedies available to it.

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

i. Abstract

+
+
+

A fundamental operation performed on a collection of features is that of +filtering in order to obtain a subset of the data which contains feature +instances that satisfy some filtering criteria. This document specifies

+
+
+
    +
  • +

    A filter grammar called Common Query Language (CQL2);

    +
  • +
  • +

    Two encodings for CQL2 - a text and a JSON encoding.

    +
  • +
+
+
+

The Common Query Language (CQL2) defined in this document is a generic filter +grammar that can be used to specify how resource instances in a source +collection of any item type, including features, can be filtered to identify +a results set. Typically, CQL2 is used in query operations to identify the +subset of resources, such as features, that should be included in a response +document. However, CQL2 can also be used in other operations, such as updates, +to identify the subset of resources that should be affected by an operation.

+
+
+

Each resource instance in the source collection is evaluated against a filtering +expression. The filter expression always evaluates to true, false or null. If the +expression evaluates to true, the resource instance satisfies the expression and +is marked as being in the result set. If the overall filter expression evaluates +to false or null, the data instance is not in the result set. Thus, the net effect of +evaluating a filter expression is a set of resources that satisfy the predicates +in the expression.

+
+
+

The Common Query Language and its text encoding are not new, but this is the first time +that the language is formally specified. The Common Query Language with the acronym CQL +was originally created as a text encoding for use with implementations of the OGC Catalogue Service +Implementation Specification. The language is based on the capabilities in +the OGC Filter Encoding Standard, which was originally part of +the Web Feature Service (WFS) Standard.

+
+
+

The Common Query Language as specified in this document is a revision of this earlier +version. While the language design including the classification of operators are +consistent with the earlier specification, there have been a number of changes and +existing implementations of CQL will need to be updated to process filter expressions +specified by this document. This document therefore uses the acronym CQL2 to refer to +the current version of the Common Query Language.

+
+
+ + + + + +
+
Note
+
+The use of CQL2 also distinguishes the Common Query Language from other existing uses +of CQL for query languages, for example, for the Cassandra Query Language. +
+
+
+

ii. Keywords

+
+
+

The following are keywords to be used by search engines and document catalogues.

+
+
+

OGC, common query language, filter, expression, query, SQL, CQL2, where clause, +selection clause

+
+
+

iii. Preface

+
+
+

Attention is drawn to the possibility that some of the elements of this document may be the subject of patent rights. The Open Geospatial Consortium Inc. shall not be held responsible for identifying any or all such patent rights.

+
+
+

Recipients of this document are requested to submit, with their comments, notification of any relevant patent claims or other intellectual property rights of which they may be aware that might be infringed by any implementation of the standard set forth in this document, and to provide supporting documentation.

+
+
+

iv. Submitting organizations

+
+
+

The following organizations submitted this document to the Open Geospatial Consortium (OGC):

+
+
+
    +
  • +

    CubeWerx Inc.

    +
  • +
  • +

    Ecere Corporation

    +
  • +
  • +

    GeoSolutions di Giannecchini Simone & C. s.a.s.

    +
  • +
  • +

    interactive instruments GmbH

    +
  • +
  • +

    US Army Geospatial Center (AGC)

    +
  • +
+
+
+

v. Submitters

+
+
+

All questions regarding this submission should be directed to the editors or the submitters:

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

Name

Affiliation

Panagiotis (Peter) A. Vretanos (editor)

CubeWerx Inc.

Clemens Portele (editor)

interactive instruments GmbH

Andrea Aime

GeoSolutions di Giannecchini Simone & C. s.a.s.

Jeff Harrison

US Army Geospatial Center (AGC)

Jérôme Jacovella-St-Louis

Ecere Corporation

+
+
+
+

1. Scope

+
+
+

This document specifies the Common Query Language (CQL2) to express filter expressions on spatial and temporal data.

+
+
+

This document defines

+
+
+
    +
  • +

    A text encoding for a CQL2 filter;

    +
  • +
  • +

    A JSON encoding for a CQL2 filter.

    +
  • +
+
+
+ + + + + +
+
Note
+
+The CQL2 grammar contains all the necessary language elements of a general purpose expression language, including support for spatio-temporal values. +The focus of this version of the language are boolean-valued filter expressions. It is planned to potentially remove this restriction, while maintaining backward compatibility, allowing expressions that result in values of other data types, including geometries. Such expressions could be used, for example, in a styling language to specify parameter values, or to define derived properties. In this case, a particular use of CQL2 could specify the boolean-valued restriction separately, for example when used as a filter predicate expression, or as a styling rule selector. The usability of such an expression language, especially in the context of geometry types, would also greatly benefit from standardizing additional functions and/or operators e.g., to compute the geometry resulting from buffering or intersecting operations. Example files and associated schemas have been published on the OGC Schemas repository. +
+
+
+
+
+

2. Conformance

+
+
+

This standard defines the following requirements classes, +grouped by their standardization target:

+
+ +
+ + + + + +
+
Note
+
+"Server" is used in this Standard to identify any executable software that is +able to evaluate filter expressions on data. +
+
+
+

The Basic CQL2 requirements class defines the minimal subset +of the Common Query Language (CQL2) that all implementations must support. +Basic CQL2 is intended to be a useful, but limited set of +predicates that support fine-grained read-access to collections of resources.

+
+
+

The specific set of operators defined in this requirements class is:

+
+
+
    +
  • +

    Logical operators:

    +
    +
      +
    • +

      and

      +
    • +
    • +

      or

      +
    • +
    • +

      not

      +
    • +
    +
    +
  • +
  • +

    Comparison operators:

    +
    +
      +
    • +

      equal to

      +
    • +
    • +

      not equal to

      +
    • +
    • +

      less than

      +
    • +
    • +

      less than or equal to

      +
    • +
    • +

      greater than

      +
    • +
    • +

      greater than or equal to

      +
    • +
    • +

      is null

      +
    • +
    +
    +
  • +
+
+
+

Basic CQL2 only requires support for property-literal comparisons. That means that servers only have to support property references as expressions on the left-hand side of an operator, and only literal values as expressions on the right-hand side.

+
+
+

An encoding of CQL2 may be used as the value of the filter parameters defined +in the "Filter" requirements class specified in OGC API - Features - Part 3: Filtering.

+
+
+

The Advanced Comparison Operators requirements class specifies additional comparison operators:

+
+
+
    +
  • +

    like

    +
  • +
  • +

    between

    +
  • +
  • +

    in

    +
  • +
+
+
+

The Case-insensitive Comparison requirements class adds a standardized string function to support case-insensitive string comparisons:

+
+
+
    +
  • +

    casei

    +
  • +
+
+
+

The Accent-insensitive Comparison requirements class adds a standardized string function to support accent-insensitive string comparisons:

+
+
+
    +
  • +

    accenti

    +
  • +
+
+
+

The Basic Spatial Functions requirements class specifies minimal requirements for servers that support standardized spatial comparison functions. Only the following spatial comparison function must be supported, and only for points and bounding boxes:

+
+
+
    +
  • +

    s_intersects

    +
  • +
+
+
+

The Basic Spatial Functions with additional Spatial Literals requirements class is similar to the Basic Spatial Functions requirements class except it removes the restrictions on the spatial literals that may be used in the expression.

+
+
+

The Spatial Functions requirements class specifies requirements for servers that support a richer set of spatial comparison functions. The list of additional spatial comparison functions that must be supported is:

+
+
+
    +
  • +

    s_contains

    +
  • +
  • +

    s_crosses

    +
  • +
  • +

    s_disjoint

    +
  • +
  • +

    s_equals

    +
  • +
  • +

    s_overlaps

    +
  • +
  • +

    s_touches

    +
  • +
  • +

    s_within

    +
  • +
+
+
+

All spatial data types from the Simple Feature Access Standard must be supported.

+
+
+

The Temporal Functions requirements +class specifies requirements for servers that support standardized temporal comparison function. +The list of temporal comparison function that must be supported is:

+
+
+
    +
  • +

    t_after

    +
  • +
  • +

    t_before

    +
  • +
  • +

    t_contains

    +
  • +
  • +

    t_disjoint

    +
  • +
  • +

    t_during

    +
  • +
  • +

    t_equals

    +
  • +
  • +

    t_finishedby

    +
  • +
  • +

    t_finishes

    +
  • +
  • +

    t_intersects

    +
  • +
  • +

    t_meets

    +
  • +
  • +

    t_metby

    +
  • +
  • +

    t_overlappedby

    +
  • +
  • +

    t_overlaps

    +
  • +
  • +

    t_startedby

    +
  • +
  • +

    t_starts

    +
  • +
+
+
+

The Array Functions requirements class specifies +requirements for standardized array comparison functions for sets of values. +The array comparison functions that must be supported are:

+
+
+
    +
  • +

    a_containedby

    +
  • +
  • +

    a_contains

    +
  • +
  • +

    a_equals

    +
  • +
  • +

    a_overlaps

    +
  • +
+
+
+

The Property-Property Comparisons requirements class drops the permission to restrict expressions on the left-hand side to properties and to restrict expressions on the right-hand side to literal values. This supports property-property, but also literal-literal or literal-property comparisons.

+
+
+

The Functions requirements class specifies requirements for +supporting function calls (e.g. min, max, etc.) in a CQL2 expression. Function +calls are the primary means of extending the language. Implementations +should provide a capability to discover the available functions.

+
+
+

The Arithmetic Expressions requirements class specifies +requirements for supporting the standard set of arithmetic operators +(+, -, *, /, %, div, and ^) in a CQL2 expression.

+
+
+

The CQL2 Text encoding requirements class defines +a text encoding for CQL2. Such an encoding is suitable for use with HTTP query +parameters such as the filter parameter defined by the "Filter" requirements class specified +in OGC API - Features - Part 3: Filtering.

+
+
+

The CQL2 JSON encoding requirements class defines +a JSON encoding for CQL2. Such as encoding is suitable for use as the +body of an HTTP POST request.

+
+
+

Conformance with this standard shall be checked using all the relevant tests +specified in Annex A of this document. The framework, concepts, and +methodology for testing, and the criteria to be achieved to claim conformance +are specified in the OGC Compliance Testing Policies and Procedures and the +OGC Compliance Testing web site.

+
+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1. Conformance class URIs
Conformance classURI

Basic CQL2

http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2

Advanced Comparison Operators

http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators

Case-insensitive Comparison

http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison

Accent-insensitive Comparison

http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison

Basic Spatial Functions

http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions

Basic Spatial Functions with additional Spatial Literals

http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus

Spatial Functions

http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions

Temporal Functions

http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions

Array Functions

http://www.opengis.net/spec/cql2/1.0/conf/array-functions

Property-Property Comparisons

http://www.opengis.net/spec/cql2/1.0/conf/property-property

Functions

http://www.opengis.net/spec/cql2/1.0/conf/functions

Arithmetic Expressions

http://www.opengis.net/spec/cql2/1.0/conf/arithmetic

CQL2 Text encoding

http://www.opengis.net/spec/cql2/1.0/conf/cql2-text

CQL2 JSON encoding

http://www.opengis.net/spec/cql2/1.0/conf/cql2-json

+
+
+
+

3. References

+
+
+

The following normative documents contain provisions that, through reference in this text, constitute provisions of this document. For dated references, subsequent amendments to, or revisions of, any of these publications do not apply. For undated references, the latest edition of the normative document referred to applies.

+
+
+ +
+
+
+
+

4. Terms, Definitions, Symbols and Abbreviated Terms

+
+
+

4.1. Terms and Definitions

+
+

This document used the terms defined in OGC Policy Directive 49, which is based on the ISO/IEC Directives, Part 2, Rules for the structure and drafting of International Standards. In particular, the word “shall” (not “must”) is the verb form used to indicate a requirement to be strictly followed to conform to this standard and OGC documents do not use the equivalent phrases in the ISO/IEC Directives, Part 2.

+
+
+

This document also uses terms defined in the OGC Standard for Modular specifications (OGC 08-131r3), also known as the 'ModSpec'. The definitions of terms such as standard, specification, requirement, and conformance test are provided in the ModSpec.

+
+
+

For the purposes of this document, the following additional terms and definitions apply.

+
+
+

4.1.1. boundary

+
+

set that represents the limit of an entity (ISO 19107:2019, definition 3.6)

+
+
+ + + + + +
+
Note
+
+Boundary is most commonly used in the context of geometry, where the set is a collection of points or a collection of objects that represent those points. In other arenas, the term is used metaphorically to describe the transition between an entity and the rest of its domain of discourse. +
+
+
+
+

4.1.2. collection

+
+

a body of resources that belong or are used together; an aggregate, set, or group of related resources (OGC 20-024, OGC API - Common - Part 2: Collections).

+
+
+
+

4.1.3. custom function

+
+

function that is not specified in the CQL2 standard

+
+
+ + + + + +
+
Note
+
+Custom functions require support for the Functions requirements class. +
+
+
+
+

4.1.4. exterior

+
+

difference between the universe and the closure (ISO 19107:2019,definition 3.37)

+
+
+ + + + + +
+
Note
+
+The concept of exterior is applicable to both topological and geometric complexes. +
+
+
+
+

4.1.5. filter expression

+
+

predicate encoded for transmission between systems

+
+
+
+

4.1.6. function

+
+

rule that associates each element from a domain (source, or domain of the function) to a unique element in another domain (target, co-domain, or range) (ISO 19107:2003, definition 4.41)

+
+
+
+

4.1.7. interior

+
+

set of all direct positions that are on a geometric object but which are not on its boundary

+
+
+ + + + + +
+
Note
+
+The interior of a topological object is the continuous image of the interior of any of its geometric realizations. This is not included as a definition because it follows from a theorem of topology. Another way of saying this is that any point on a geometric object is in its interior if it can be placed inside a homeomorphic image of an open set in the Euclidean space of the object’s topological dimension. +
+
+
+
+

4.1.8. standardized function

+
+

function specified in the CQL2 standard

+
+
+
+

4.1.9. predicate

+
+

set of computational operations applied to a data instance which evaluate to true or false (OGC Filter Encoding 2.0 Encoding Standard - With Corrigendum)

+
+
+
+

4.1.10. queryable

+
+

a token that represents a property of a resource that can be used in a filter expression

+
+
+
+

4.1.11. resource

+
+

entity that might be identified (Dublin Core Metadata Initiative - DCMI Metadata Terms)

+
+
+
+

4.1.12. unicode case folding; case folding

+
+

process of making two texts which differ only in case identical for comparison purposes (W3C Character Model for the World Wide Web: String Matching)

+
+
+ + + + + +
+
Note
+
+Case folding is meant for the purpose of case-insensitive string matching. +
+
+
+
+

4.1.13. unicode normalization; normalization

+
+

process of removing alternate representations of equivalent sequences from textual data, to convert the data into a form that can be binary-compared for equivalence (Glossary of Unicode Terms)

+
+
+
+
+

4.2. Symbols

+
+
    +
  • +

    intersection, operation on two or more sets

    +
  • +
  • +

    and, logical intersection

    +
  • +
  • +

    empty set, the set having no members

    +
  • +
  • +

    not equal

    +
  • +
  • +

    if and only if, logical equivalence between statements

    +
  • +
  • +

    is a subset of

    +
  • +
  • +

    dim(x) returns the maximum dimension (-1, 0, 1, or 2) of the geometric object x

    +
  • +
  • +

    I(x) represents the interior of the geometric object x

    +
  • +
  • +

    B(x) represents the boundary of the geometric object x

    +
  • +
  • +

    E(x) represents the exterior of the geometric object x

    +
  • +
+
+
+
+

4.3. Abbreviated terms

+
+
+
ABNF
+
+

Augmented Backus-Naur Form

+
+
API
+
+

Application Programming Interface

+
+
BNF
+
+

Backus-Naur Form

+
+
CQL2
+
+

Common Query Language

+
+
CRS
+
+

Coordinate Reference System

+
+
DE-9IM
+
+

Dimensionally Extended Nine-Intersection Model

+
+
HTTP
+
+

Hypertext Transfer Protocol

+
+
HTTPS
+
+

Hypertext Transfer Protocol Secure

+
+
IANA
+
+

Internet Assigned Numbers Authority

+
+
JSON
+
+

JavaScript Object Notation

+
+
OGC
+
+

Open Geospatial Consortium

+
+
URI
+
+

Uniform Resource Identifier

+
+
WKT
+
+

Well-Known Text

+
+
YAML
+
+

YAML Ain’t Markup Language

+
+
+
+
+
+
+
+

5. Conventions and background

+
+
+

5.1. Identifiers

+
+

The normative provisions in this standard are denoted by the URI http://www.opengis.net/spec/cql2/1.0.

+
+
+

All requirements and conformance tests that appear in this document are denoted by partial URIs which are relative to this base.

+
+
+
+

5.2. Use of BNF

+
+

BNF as specified in Augmented BNF for Syntax Specifications is used to formally specify the grammar of the Common Query Language (CQL2) and its text encoding (CQL2-Text).

+
+
+
+

5.3. Use of JSON Schema

+
+

JSON Schema draft 2019-09 (JSON Schema, JSON Schema Validation) is used to formally specify the schema of the JSON encoding of CQL2 (CQL2-JSON).

+
+
+
+

5.4. Dependencies to other requirements classes

+
+

The requirements classes in this document distinguish two types of dependencies to other specifications or requirements classes:

+
+
+

First, there are the obligatory dependencies. Every server implementing the requirements class has to conform to the referenced specification or requirements class.

+
+
+

In addition, requirements classes can also have conditional dependencies. Servers implementing the requirements class do not have to conform to the referenced specification or requirements class, but if they do, they have to conform to the requirements that identify the conditional dependency as a pre-condition for the normative statement.

+
+
+
+
+
+

6. Requirements Class "Basic CQL2"

+
+
+

6.1. Overview

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/basic-cql2

Target type

Servers that evaluate filter expressions

Dependency

OGC Simple feature access - Part 1: Common architecture, Architecture

Dependency

W3C/OGC Time Ontology in OWL

Dependency

RFC 3339 (Date and Time on the Internet: Timestamps)

Dependency

JSON Schema: A Media Type for Describing JSON Documents

Dependency

Unicode

+
+

This clause defines the core of a query language called Common Query Language +(CQL2) that may be used to construct filter expressions. This core is called Basic CQL2.

+
+
+

Subsequent clauses define additional filtering capabilities as well as several +encodings of CQL2.

+
+
+
+

6.2. CQL2 filter expression

+
+

A CQL2 filter expression is an expression that defines a logically connected set of predicates that are evaluated for each item of a collection. Each predicate is an operator with operands where the number of operands depends on the operator. An operand is either a literal, a property, a standardized or custom function or an arithmetic expression.

+
+
+

A predicate is an expression that evaluates to the Boolean values of TRUE or FALSE or that evaluates to the value NULL when dealing with unknown values. +Logically connected predicates are evaluated according to the following truth table:

+
+ + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2. Truth table of evaluating CQL2 predicates
Predicate1Predicate2Predicate1 AND Predicate2Predicate1 OR Predicate2

TRUE

TRUE

TRUE

TRUE

TRUE

FALSE

FALSE

TRUE

FALSE

TRUE

FALSE

TRUE

FALSE

FALSE

FALSE

FALSE

TRUE

NULL

NULL

TRUE

FALSE

NULL

FALSE

NULL

NULL

TRUE

NULL

TRUE

NULL

FALSE

FALSE

NULL

NULL

NULL

NULL

NULL

+
+

A collection item that satisfies ALL the requirements of a CQL2 filter expression according to the above true table evaluates to a Boolean value of TRUE; otherwise the CQL2 filter expression evaluates to FALSE or NULL.

+
+
+

If a CQL2 filter expression evaluates to TRUE for an item, the item is included in the result set and is thus available for further processing such as presentation in a response document.

+
+
+

If a CQL2 filter expression overall evaluates to FALSE or NULL for an item, the item is not included in the result set and is thus not available for further processing.

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

Requirement 1

+

/req/basic-cql2/cql2-filter

+

A

+

A server SHALL support a CQL2 filter expression composed of a logically connected series of one or more predicates as described by the BNF rule booleanExpression in CQL2 BNF with the exception that the rules isLikePredicate, isBetweenPredicate, isInListPredicate, spatialPredicate, temporalPredicate, arrayPredicate, function and arithmeticExpression as well as the functions CASEI and ACCENTI in the rules characterExpression and patternExpression do not have to be supported.

+
+
+

Literal values do not have to be supported on the left-hand side of predicates and property references do not have to be supported on the right-hand side of +predicates.

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

Permission 1

+

/per/basic-cql2/cql2-filter

+

A

+

In the rule binaryComparisonPredicate the server MAY only support propertyName in the first scalarExpression rule as well as characterLiteral, numericLiteral, booleanLiteral, and instantInstance in the second scalarExpression rule.

+

B

+

In the rule isNullPredicate the server MAY only support propertyName in the scalarExpression rule.

+
+
+

A Basic CQL2 filter expression can be constructed by logically connecting comparison predicates.

+
+
+

Support for the parts of CQL2 that are not part of Basic CQL2 is added in additional +requirements classes in Common Query Language enhancements:

+
+
+ +
+
+

Examples of Basic CQL2 filter expressions are included in the subsequent sub-clauses.

+
+
+
+

6.3. Data types and literal values

+
+

This section documents the data types supported by Basic CQL2 and has examples +of literal values for each data type.

+
+
+

A literal value is any part of an CQL2 filter expression that is used +exactly as it is specified in the expression.

+
+
+

Other requirements classes add more data types. These are defined in the chapter +specifying the requirements class.

+
+
+

6.3.1. Scalar data types

+
+

The scalar data types are:

+
+
+
    +
  • +

    "string": character strings (rule characterLiteral);

    +
  • +
  • +

    "number": numbers including integers and floating point values (rule numericLiteral);

    +
  • +
  • +

    "boolean": booleans (rule booleanLiteral);

    +
  • +
  • +

    "timestamp": an instant with a granularity of a second or smaller (rule timestampInstant)

    +
  • +
  • +

    "date": an instant with a granularity of a day (rule dateInstant)

    +
  • +
+
+
+

For character string, numeric and boolean literals, the standard representations are used.

+
+
+

Conceptually, an instant is a "temporal entity with zero extent or duration" [Time Ontology in OWL]. In practice, the temporal position of an instant is described using data types where each value has some duration or granularity that is sufficient for the intended use of the data.

+
+
+

CQL2 supports two commonly used granularities: a second or smaller (data type "timestamp") and days (data type "date"). Literal timestamps are always in the time zone UTC ("Z"), dates are local dates without an associated time zone.

+
+
+

If time zone information is important for the intended use, then the "date" data type should not be used and the temporal information should be provided as an interval with start and end timestamps.

+
+
+ + + + + +
+
Note
+
+While instants (timestamps and dates) are scalar data types that can be used with the basic comparison operators, intervals are more complex data types. Support for intervals is added in the requirements class Temporal Functions where intervals can be provided as arguments in temporal comparison functions. +
+
+
+

For timestamp and date values representations based on RFC 3339 are used:

+
+
+ +
+
+
Example 1. Scalar literal examples
+
+
+
    +
  • +

    character string

    +
  • +
+
+
+
+
'This is a literal string.'
+
+
+
+
    +
  • +

    character string with an escaped embedded quote

    +
  • +
+
+
+
+
'Via dell''Avvento'
+
+
+
+
    +
  • +

    number

    +
  • +
+
+
+
+
-100
+3.14159
+
+
+
+
    +
  • +

    boolean

    +
  • +
+
+
+
+
true
+false
+
+
+
+
    +
  • +

    timestamp (Text)

    +
  • +
+
+
+
+
TIMESTAMP('1969-07-20T20:17:40Z')
+
+
+
+
    +
  • +

    timestamp (JSON)

    +
  • +
+
+
+
+
{ "timestamp": "1969-07-20T20:17:40Z" }
+
+
+
+
    +
  • +

    date (Text)

    +
  • +
+
+
+
+
DATE('1969-07-20')
+
+
+
+
    +
  • +

    date (JSON)

    +
  • +
+
+
+
+
{ "date": "1969-07-20" }
+
+
+
+
+
+
+

6.3.2. Escaping in string literals

+
+

In general, escaping special character sequences in a string literal will be handled according to the rules of the specific encoding being used. For example, for the JSON encoding of CQL2, an embedded newline in a string literal would be encoded as \n. If, however, an XML encoding of CQL2 existed the embedded newline character would be encoded as &#xA. Furthermore, additional processing of a string literal may be necessary before it can be passed down to an underlying platform (e.g. RDBMS) for further handling.

+
+
+

For the text encoding of CQL2 see Requirements Class "CQL2 Text" and requirement /req/cql2-text/escaping for additional requirements concerning escaping in string literals.

+
+
+
+

6.3.3. Type casts

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

Permission 2

+

/per/basic-cql2/type-casts

+

A

+

If an operator or function has operands that have incompatible data types, the server MAY either return an error or it MAY cast the operands to compatible data types.

+
+
+

This Standard does not prescribe how types are cast. The evaluation of filter expressions that involve type casts will, therefore, be system dependent.

+
+
+

For example, a system that evaluates an expression '5' > 4 can, for example,

+
+
+
    +
  • +

    throw an error (incompatible types in a comparison operator);

    +
  • +
  • +

    cast the number to a string ('5' > '4');

    +
  • +
  • +

    cast the string to a number (5 > 4).

    +
  • +
+
+
+
+
+

6.4. Identifiers

+
+

An identifier is a token that represents a resource or a named part of a resource within a CQL2 expression that is not a CQL2 keyword or command. Identifiers are composed of a sequence of UTF-8 characters. Valid starting characters for identifiers can include the colon (i.e. ":"), the underscore (i.e. "_") and letters of the alphabet (e.g. "A-Z, a-z"). Additional continuing characters in an identifier can include the period (i.e ".") and numeric digits (i.e. "0-9"). The identifier production in the CQL2 BNF enumerates the specific characters that can be used to start an identifier as well as additional identifier continuing characters.

+
+
+
+

6.5. Property references

+
+

Properties in an object being evaluated in the CQL2 filter expression can be +referenced by their name (rule propertyName).

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

Requirement 2

+

/req/basic-cql2/property

+

A

+

The property name (rule propertyName) SHALL be a queryable of the data.

+

B

+

The property name reference SHALL evaluate to its corresponding value, or NULL if unset.

+
+
+

For example, a property name used in a scalar expression (rule scalarExpression) +has to be a queryable of type string, number, integer, boolean, date, or timestamp.

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

In this example, the property windSpeed is used in a function that receives an array of numbers and returns a number.

+
+
+
+
avg(windSpeed)
+
+
+
+
+
{ "op": "avg", "args": [ { "property": "windSpeed" } ] }
+
+
+
+
+
+
+

6.6. Standard comparison predicates

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

Requirement 3

+

/req/basic-cql2/binary-comparison-predicate

+

A

+

A binary comparison predicate as specified by rule 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.

+

B

+

If the requirements of the operator are not satisfied, then the predicate SHALL evaluate to FALSE.

+

C

+

If either scalar expression (rule scalarExpression) of the predicate is NULL then the predicate SHALL evaluate to the value NULL;

+

D

+

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

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

Recommendation 1

+

/rec/core/string-normalization

+

A

+

For any string comparisons, the server SHOULD implement unicode normalization described in the implementation guidelines of the Unicode 15.0.0 standard (see clause 5.6 Normalization).

+

B

+

The recommended normalization form is canonical decomposition (NFD).

+
+
+

Instants (timestamps and dates) are scalar data types. All implementations have to support the comparison of two timestamps or two dates. How this is implemented is a decision of the server and will depend on the internal representation. For example, the server could compare the RFC 3339 string representations of the two timestamps.

+
+
+
Example 3. Binary comparison predicates
+
+
+
+
city='Toronto'
+
+
+
+
+
{
+  "op": "=",
+  "args": [
+    { "property": "city" },
+    "Toronto"
+  ]
+}
+
+
+
+
+
avg(windSpeed) < 4
+
+
+
+
+
{
+  "op": "<",
+  "args": [
+    {
+      "op": "avg",
+      "args": [ { "property": "windSpeed" } ]
+    },
+    4
+  ]
+}
+
+
+
+
+
balance-150.0 > 0
+
+
+
+
+
{
+  "op": ">",
+  "args": [
+    {
+      "op": "-",
+      "args": [
+        { "property": "balance" },
+        150.0
+      ]
+    },
+    0
+  ]
+}
+
+
+
+
+
updated >= date('1970-01-01')
+
+
+
+
+
{
+  "op": ">=",
+  "args": [
+    { "property": "updated" },
+    { "date": "1970-01-01" }
+  ]
+}
+
+
+
+
+ ++++ + + + + + + + + + + +

Requirement 4

+

/req/basic-cql2/null-predicate

+

A

+

The null predicate (rule isNullPredicate) tests whether the value of a scalar expression is null. The predicate SHALL be evaluated according to the following truth table:

+
+ + ++++ + + + + + + + + + + + + + + + + + + + + +
Table 3. True table for the NOT operator
PredicateNOT(Predicate)

TRUE

FALSE

FALSE

TRUE

NULL

NULL

+
+
Example 4. Examples of a NULL predicate
+
+
+
+
geometry IS NOT NULL
+
+
+
+
+
{
+  "op": "not",
+  "args": [
+    {
+      "op": "isNull",
+      "args": [ { "property": "geometry" } ]
+    }
+  ]
+}
+
+
+
+
+
+
+

6.7. CQL2 Encodings

+
+

This document defines a text +encoding and a JSON encoding of CQL2 that covers Basic CQL2 +and all enhanced capabilities specified in the next clause.

+
+
+
+
+
+

7. Common Query Language enhancements

+
+
+

7.1. Overview

+
+

This clause specifies requirements for enhancements to Basic CQL2. +Specifically, this clause defines requirements for:

+
+
+
    +
  • +

    Advanced comparison operators;

    +
  • +
  • +

    Case-insensitive comparison;

    +
  • +
  • +

    Accent-insensitive comparison;

    +
  • +
  • +

    Spatial functions;

    +
  • +
  • +

    Temporal functions;

    +
  • +
  • +

    Array functions;

    +
  • +
  • +

    Property-property and literal-literal comparisons;

    +
  • +
  • +

    Support for functions in CQL2;

    +
  • +
  • +

    Support for arithmetic expression in CQL2;

    +
  • +
+
+
+

In each case, this clause specifies requirements for the rules in CQL2 BNF +not supported by Basic CQL2.

+
+
+
+

7.2. Requirements Class "Advanced Comparison Operators"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic CQL2"

+
+

This requirements class adds support for the operators LIKE, BETWEEN and IN.

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

Requirement 5

+

/req/advanced-comparison-operators/like-predicate

+

A

+

The like predicate (rule 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.

+

B

+

If the value does not match the pattern (patternExpression), then the predicate SHALL evaluate to the Boolean value FALSE.

+

C

+

If the character expression (rule characterExpression) and/or the pattern expression (rule patternExpression) in the predicate is NULL, then the predicate SHALL evaluate to the value NULL.

+

D

+

The character expression (rule characterExpression) in rule isLikePredicate SHALL evaluate to a characterLiteral.

+

E

+

The wildcard character SHALL be the percent character (ASCII x25, %).

+

F

+

The wildcard SHALL match zero of more characters in the test value.

+

G

+

The wildcard character SHALL not match the NULL value.

+

H

+

The single character wildcard SHALL be the underbar character (ASCII x5F, _).

+

I

+

The single character wildcard SHALL match one character in the test value.

+

J

+

The single character wildcard SHALL not match the NULL value.

+

K

+

The escape character SHALL be the back slash (ASCII x5C, \).

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

Permission 3

+

/per/advanced-comparison-operators/like-predicate

+

A

+

The server MAY not support characterLiteral as the character expression (rule characterExpression) in rule isLikePredicate.

+
+
+
Example 5. Example of a LIKE predicate
+
+
+
+
name LIKE 'Smith%'
+
+
+
+
+
{
+  "op": "like",
+  "args": [
+    { "property": "name" },
+    "Smith%"
+  ]
+}
+
+
+
+
+ ++++ + + + + + + + + + + + + + + + + + + + + + + +

Requirement 6

+

/req/advanced-comparison-operators/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.

+

B

+

If the value lies outside the specified range, then the predicate SHALL evaluate to the Boolean value FALSE.

+

C

+

If any numeric expression (rule numericExpression) in the predicate is NULL then the predicate SHALL evaluate to the value NULL.

+

D

+

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

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

Permission 4

+

/per/advanced-comparison-operators/between-predicate

+

A

+

The server MAY not support a numericLiteral as the first operand (rule numericExpression) in rule isBetweenPredicate.

+

B

+

The server MAY not support a propertyName as the second and third operand (rule numericExpression) in rule isBetweenPredicate.

+
+
+
Example 6. Examples of a BETWEEN predicate
+
+
+
+
depth BETWEEN 100.0 and 150.0
+
+
+
+
+
{
+  "op": "between",
+  "args": [
+    { "property": "depth" },
+    100.0,
+    150.0
+  ]
+}
+
+
+
+
+ ++++ + + + + + + + + + + + + + + +

Requirement 7

+

/req/advanced-comparison-operators/in-predicate

+

A

+

The in-list predicate (rule 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 inList, 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 scalarExpression, i.e., the left-hand side of the predicate), if evaluated.

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

Permission 5

+

/per/advanced-comparison-operators/in-predicate

+

A

+

The server MAY not support characterLiteral, numericLiteral, booleanLiteral or instantInstance as the value to be tested (rule scalarExpression, i.e., the left-hand side of the predicate).

+

B

+

The server MAY not support propertyName as the items in the list of an in-list predicate (rule inList, i.e., the items on the right-hand side of the predicate).

+
+
+
Example 7. Examples of a IN predicate
+
+
+
+
cityName IN ('Toronto','Frankfurt','Tokyo','New York')
+
+
+
+
+
{
+  "op": "in",
+  "args": [
+    { "property": "cityName" },
+    [ "Toronto", "Frankfurt", "Tokyo", "New York" ]
+  ]
+}
+
+
+
+
+
category NOT IN (1,2,3,4)
+
+
+
+
+
{
+  "op": "not",
+  "args": [
+    {
+      "op": "in",
+      "args": [
+        { "property": "category" },
+        [ 1, 2, 3, 4 ]
+      ]
+    }
+  ]
+}
+
+
+
+
+
+
+

7.3. Requirements Class "Case-insensitive Comparison"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/case-insensitive-comparison

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic CQL2"

+
+

The following requirements class adds support for case-insensitive string comparisons.

+
+
+

This capability is useful to operate across data that has not been normalized or has been normalized to values that are different than they should be. This is implemented via a standardized string function to normalize a string with respect to case (CASEI).

+
+
+

For example, the CASEI function is useful when a property is set to "PLANET", "Planet", or "planet" and one wants to match either without having to enumerate all the variations.

+
+
+

Implementations of the CASEI function can be complex and depend on the locale, but in many cases the underlying datastore will provide a capability that the function can be mapped to.

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

Requirement 8

+

/req/case-insensitive-comparison/casei-function

+

A

+

The server SHALL support a function named CASEI.

+

B

+

The function SHALL accept one argument that can be a character string literal, the name of a property that evaluates to a character string literal or a function that returns a character string literal (see rules characterLiteral, propertyName, function).

+

C

+

The function SHALL return a character string.

+

D

+

If the argument to the function is NULL, the function SHALL return a NULL value.

+

E

+

The function SHALL implement the full case folding algorithm defined in the implementation guidelines of the Unicode 15.0.0 standard (see clause 5.18 Case Mappings, sub-clause Caseless Matching, CaseFolding-15.0.0.txt and SpecialCasing-15.0.0.txt).

+
+
+ + + + + +
+
Note
+
+Implementation Guidance for CASEI()
+The implementation of case folding makes use of the CaseFolding-15.0.0.txt file and replaces code points in the source string by the corresponding sequence on lines with a 'C'(ommon) or 'F'(ull). +
+
+
+
Example 8. Example case-insensitive comparison
+
+
+
+
CASEI(road_class) IN (CASEI('Οδος'),CASEI('Straße'))
+
+
+
+
+
{
+  "op": "in",
+  "args": [
+    {
+      "op": "casei",
+      "args": [ { "property": "road_class" } ]
+    },
+    [
+      { "op": "casei", "args": [ "Οδος" ] },
+      { "op": "casei", "args": [ "Straße" ] }
+    ]
+  ]
+}
+
+
+
+
+
+

The CASEI function returns a string typed representation of the input expression that is guaranteed to be equal to any other case insensitive representation of that string. In order to ensure correct comparisons, the function should be applied to both sides of an expression. So, for example, the only durable case-insensitive equality comparison would be CASEI(some_property) = CASEI('Straße'). An expression such as CASEI(some_property) = 'strasse' might work but is not guaranteed to work across implementations or between versions of the same implementation.

+
+
+
+

7.4. Requirements Class "Accent-insensitive Comparison"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic CQL2"

+
+

This requirements class adds support for accent-insensitive string comparisons to operate across data that has not been normalized or has been normalized to values that are different than they should be.

+
+
+

Similar to the case-insensitive comparison, this capability is supported via a string function ACCENTI.

+
+
+

For example, the ACCENTI function is useful when accents (or, more generally, diacritics not available in ASCII) were dropped when indexing a property. This may be useful, for example, to support users that are not familiar with accents or that do not know how to type them on their keyboard. For example, "papa" would also match "papá". Note that accent-insensitive comparisons can match values with a different meaning. E.g., in Spanish "papa" is potato and "papá" is father. "papá" in an accent-insensitive comparison will match both, but this may also be intentional, because the users knows that some of the data has been processed in ASCII.

+
+
+

Implementations of the ACCENTI function can be complex, but in many cases the underlying datastore will provide a capability that the function can be mapped to.

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

Requirement 9

+

/req/accent-insensitive-comparison/accenti-function

+

A

+

The server SHALL support a function named ACCENTI.

+

B

+

The function SHALL accept one argument that can be a character string literal, the name of a property that evaluates to a character string literal or a function that returns a character string literal (see rules characterLiteral, propertyName, function).

+

C

+

The function SHALL return a character string.

+

D

+

If the argument to the function is NULL, the function SHALL return a NULL value.

+

E

+

The function SHALL implement accent stripping and diacritic folding.

+
+
+
Example 9. Example accent-insensitive comparison
+
+
+
+
ACCENTI(etat_vol) = ACCENTI('débárquér')
+
+
+
+
+
{
+  "op": "=",
+  "args": [
+    {
+      "op": "accenti",
+      "args": [ { "property": "etat_vol" } ]
+    },
+    {
+      "op": "accenti",
+      "args": [ "débárquér" ]
+    }
+  ]
+}
+
+
+
+
+
+

Like CASEI, the ACCENTI function returns a string typed representation of the input expression that is guaranteed to be equal to any other accent insensitive representation of that string. In order to ensure correct comparisons, the function should be applied to both sides of an expression. So, for example, the only durable accent-insensitive equality comparison would be ACCENTI(some_property) = ACCENTI('papá'). An expression such as ACCENTI(some_property) = 'papa' might work but is not guaranteed to work across implementations or between versions of the same implementation.

+
+
+ + + + + +
+
Note
+
+
+

Implementation guidance for ACCENTI()

+
+
+

The implementation of an ACCENTI() function requires the use of fields 3 and 5 from UnicodeData.txt and the application of the Unicode Normalization Algorithm (NFD or NFKD) by:

+
+
+ +
+
+
+
if(codePoint >= 0xAC00 && codePoint < 0xD7B0)
+{
+   unsigned int syllable = codePoint - 0xAC00;
+   unsigned int t = syllable % 28, v, l;
+   syllable /= 28;
+   v = syllable % 21, l = syllable / 21;
+   add(0x1100 + l);
+   add(0x1161 + v);
+   if(t) add(0x11A7 + t);
+}
+
+
+
+
    +
  • +

    Applying the Canonical Ordering algorithm which is stable-sorting (e.g., bubble-sort) the decomposed mapping code points by the value of that combining class for any sub-string where the Combining Class (field 3) (also in DerivedCombiningClass.txt) value is non-zero. This step is necessary if there were combining marks in the source text; the Decomposition Mappings should otherwise already be in the correct order. The canonical ordering will only matter for code points that do not get stripped, so it will not matter for any of the combining characters that are non-spacing marks.

    +
  • +
+
+
+

then:

+
+
+
    +
  • +

    Removing Nonspacing Marks (category Mn) (general category is field 2 of UnicodeData.txt, also available in DerivedGeneralCategory.txt).

    +
  • +
  • +

    An exception should be made for some characters categorized as Mn, as stripping some non-spacing marks — like the Japanese voicing marks (dakuten [ ゛] U+3099 and handakuten [゜] U+309A) — can be a lossy change that would turn はじめ "hajime" (beginning) into はしめ "hashime" (fastener).

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

Recommendation 2

+

/rec/accent-insensitive-comparison/japanese-non-spacing-marks +Implementations of the ACCENTI() function SHOULD not remove the Japanese non-spacing marks dakuten U+3099[ ゛] and handakuten U+309A[゜].

+
+
+
+

7.5. Requirements Class "Basic Spatial Functions"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic CQL2"

Dependency

OGC Simple feature access - Part 1: Common architecture, Architecture

+
+

A spatial predicate evaluates two geometry-valued expressions to determine if the expressions satisfy the requirements of the specified spatial comparison function.

+
+
+

7.5.1. Basic spatial data types and literal values

+
+

The basic spatial data types are (part of rule spatialInstance):

+
+
+
    +
  • +

    "Point": a point;

    +
  • +
  • +

    "BBox": a bounding rectangle or box.

    +
  • +
+
+
+

For the Point data type, the following representations are used for literal values:

+
+
+ +
+
+

For the BBox data type:

+
+
+

In the Text representation, the type is encoded as a BBOX() spatial comparison function with four or six numerical arguments, depending on whether the coordinates include a vertical axis (height or depth):

+
+
+
    +
  • +

    Lower left corner, coordinate axis 1

    +
  • +
  • +

    Lower left corner, coordinate axis 2

    +
  • +
  • +

    Minimum value, coordinate axis 3 (optional)

    +
  • +
  • +

    Upper right corner, coordinate axis 1

    +
  • +
  • +

    Upper right corner, coordinate axis 2

    +
  • +
  • +

    Maximum value, coordinate axis 3 (optional)

    +
  • +
+
+
+

In cases where the bounding box spans the antimeridian of a geographic coordinate reference system, the lower-left value (west-most box edge) is larger than the upper-right value (east-most box edge).

+
+
+

If the vertical axis is included, the third and the sixth number are the bottom and the top of the 3-dimensional bounding box.

+
+
+

In JSON, the BBox type is encoded as a JSON object with a "bbox" member with an array with four or six numbers. This representation is consistent with the GeoJSON representation of a bounding box (see clause 5 of GeoJSON).

+
+
+

Since WKT and GeoJSON do not provide a capability to specify the CRS of a geometry literal, the server has to determine the CRS of the geometry literals in a filter expression through another mechanism. For example, a query parameter filter-crs is used in OGC API - Features - Part 3: Filtering to pass the CRS information to the server.

+
+
+
Example 10. Spatial literal example
+
+
+
    +
  • +

    spatial geometry (Text)

    +
  • +
+
+
+
+
POINT(43.5845 -79.5442)
+
+
+
+
    +
  • +

    spatial geometry (JSON)

    +
  • +
+
+
+
+
{
+   "type": "Point",
+   "coordinates": [43.5845,-79.5442]
+}
+
+
+
+
    +
  • +

    bounding box (Text)

    +
  • +
+
+
+
+
BBOX(160.6,-55.95,-170,-25.89)
+
+
+
+
    +
  • +

    bounding box (JSON)

    +
  • +
+
+
+
+
{
+   "bbox": [160.6, -55.95, -170, -25.89]
+}
+
+
+
+
+
+
+

7.5.2. Spatial Functions

+
+

In this conformance class, the only required spatial comparison function is intersects and the only required spatial literals are point and BBox. Additional spatial literals are specified in the Basic Spatial Functions with additional Spatial Literals requirements class and additional spatial comparison functions are specified in the Spatial Functions requirements class.

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

Requirement 10

+

/req/basic-spatial-operators/spatial-predicate

+

A

+

If the requirements of the standardized spatial comparison function are satisfied, then the predicate SHALL evaluate to the Boolean value TRUE.

+

B

+

If the requirements of the standardized spatial comparison function are not satisfied, then the predicate SHALL evaluate to the Boolean value FALSE.

+

C

+

If either geometry expression (rule geomExpression) of the predicate is NULL then the predicate SHALL evaluate to the value NULL.

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

Requirement 11

+

/req/basic-spatial-functions/spatial-functions

+

A

+

The server SHALL support the standardized S_INTERSECTS spatial comparison function as defined by the BNF rule spatialFunction in CQL2 BNF.

+

B

+

All supported standardized spatial comparison functions SHALL be evaluated as defined in clause 6.1.15 of OpenGIS® Implementation Standard for Geographic information - Simple feature access - Part 1: Common architecture (except that in CQL2 the predicates evaluate to a Boolean, not an Integer).

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

Permission 6

+

/per/basic-spatial-functions/spatial-predicates

+

A

+

The server MAY not support a spatialInstance as the first operand (rule geomExpression) in rule spatialPredicate.

+

B

+

The server MAY not support a propertyName as the second operand (rule geomExpression) in rule spatialPredicate.

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

Permission 7

+

/per/basic-spatial-functions/spatial-data-types

+

A

+

The server MAY only support pointTaggedText and bboxTaggedText in rule spatialInstance.

+
+
+
+

7.5.3. Examples

+
+
Example 11. Example spatial predicate
+
+
+
+
S_INTERSECTS(geometry,POINT(36.319836 32.288087))
+
+
+
+
+
{
+  "op": "s_intersects",
+  "args": [
+    { "property": "geometry" },
+    {
+      "type": "Point",
+      "coordinates": [ 36.319836, 32.288087 ]
+    }
+  ]
+}
+
+
+
+
+
+
Example 12. Example for the filter-crs query parameter
+
+
+
+
...filter-lang=cql2-text&
+   filter-crs=http://www.opengis.net/def/crs/EPSG/0/32635&
+   filter=S_INTERSECTS(geometry,POINT(379213.87 3610774.16))...
+
+
+
+

Note that the values of the filter-crs and filter parameters have not been percent-encoded (see section 2.1 of RFC 3986) in this example for better readability.

+
+
+
+
+
+
+

7.6. Requirements Class "Basic Spatial Functions with additional Spatial Literals"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic Spatial Functions"

Dependency

OGC Simple feature access - Part 1: Common architecture, Architecture

+
+

This requirements class is similar to the Basic Spatial Functions requirements class except it removes the restrictions on the spatial literals that can participate in the expression.

+
+
+

7.6.1. Additional spatial data types and literal values

+
+

In addition to the spatial types listed in the Basic Spatial Functions requirements class (i.e. "Point", "BBox"), this requirements class allows the following Spatial Literals (part of rule spatialInstance):

+
+
+
    +
  • +

    "LineString": a curve with linear interpolation between the vertices;

    +
  • +
  • +

    "Polygon": a planar surface bounded by closed line strings;

    +
  • +
  • +

    "MultiPoint": a collection of points;

    +
  • +
  • +

    "MultiLineString": a collection of line strings;

    +
  • +
  • +

    "MultiPolygon": a collection of polygons;

    +
  • +
  • +

    "GeometryCollection": a collection of one or more of "Point", "Polygon", "MultiPoint", "MultiLineString", or "MultiPolygon" instances;

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

Requirement 12

+

/req/basic-spatial-functions-plus/spatial-data-types

+

A

+

The server SHALL support all spatial literals as defined by the BNF rule spatialInstance in CQL2 BNF.

+
+
+

The following representations are used for literal values:

+
+
+ +
+
+
Example 13. Spatial literal example
+
+
+
    +
  • +

    spatial geometry (Text)

    +
  • +
+
+
+
+
LINESTRING(43.6776 -79.5792, 43.7089 -79.5532, 43.7184 -79.5169, 43.7314 -79.4503, 43.7592 -79.4037, 43.7681 -79.3384, 43.8118 -79.3473, 43.8118 -79.3473, 43.8416 -79.3673)
+
+POLYGON((43.5845 -79.5442, 43.6079 -79.4893, 43.5677 -79.4632, 43.6129 -79.3925, 43.6223 -79.3238, 43.6576 -79.3163, 43.7945 -79.1178, 43.8144 -79.1542, 43.8555 -79.1714, 43.7509 -79.6390, 43.5845 -79.5442))
+
+
+
+
    +
  • +

    spatial geometry (JSON)

    +
  • +
+
+
+
+
{
+  "type": "LineString",
+  "coordinates": [
+    [43.6776,-79.5792],
+    [43.7089,-79.5532],
+    [43.7184,-79.5169],
+    [43.7314,-79.4503],
+    [43.7592,-79.4037],
+    [43.7681,-79.3384],
+    [43.8118,-79.3473],
+    [43.8118,-79.3473],
+    [43.8416,-79.3673]
+  ]
+}
+
+{
+  "type": "Polygon",
+  "coordinates": [
+    [
+     [43.5845,-79.5442],
+      [43.6079,-79.4893],
+      [43.5677,-79.4632],
+      [43.6129,-79.3925],
+      [43.6223,-79.3238],
+      [43.6576,-79.3163],
+      [43.7945,-79.1178],
+      [43.8144,-79.1542],
+      [43.8555,-79.1714],
+      [43.7509,-79.6390],
+      [43.5845,-79.5442]
+    ]
+  ]
+}
+
+
+
+
+
+
Example 14. Example spatial predicate
+
+
+
+
S_INTERSECTS(geometry,POLYGON((43.5845 -79.5442, 43.6079 -79.4893, 43.5677 -79.4632, 43.6129 -79.3925, 43.6223 -79.3238, 43.6576 -79.3163, 43.7945 -79.1178, 43.8144 -79.1542, 43.8555 -79.1714, 43.7509 -79.6390, 43.5845 -79.5442)))
+
+
+
+
+
{
+  "op": "s_intersects",
+  "args": [
+    { "property": "geometry" },
+   {
+     "type": "Polygon",
+     "coordinates": [
+       [
+         [43.5845,-79.5442],
+         [43.6079,-79.4893],
+         [43.5677,-79.4632],
+         [43.6129,-79.3925],
+         [43.6223,-79.3238],
+         [43.6576,-79.3163],
+         [43.7945,-79.1178],
+         [43.8144,-79.1542],
+         [43.8555,-79.1714],
+         [43.7509,-79.6390],
+         [43.5845,-79.5442]
+       ]
+     ]
+   }
+  ]
+}
+
+
+
+
+
+
Example 15. Example for the filter-crs query parameter
+
+
+
+
...filter-lang=cql2-text&
+   filter-crs=http://www.opengis.net/def/crs/EPSG/0/32635&
+   filter=S_INTERSECTS(geometry,POLYGON((43.5845 -79.5442, 43.6079 -79.4893, 43.5677 -79.4632, 43.6129 -79.3925, 43.6223 -79.3238, 43.6576 -79.3163, 43.7945 -79.1178, 43.8144 -79.1542, 43.8555 -79.1714, 43.7509 -79.6390, 43.5845 -79.5442)))...
+
+
+
+

Note that the values of the filter-crs and filter parameters have not been percent-encoded (see section 2.1 of RFC 3986) in this example for better readability.

+
+
+
+
+
+
+

7.7. Requirements Class "Spatial Functions"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/spatial-functions

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic Spatial Functions"

Dependency

Requirements Class "Basic Spatial Functions with additional Spatial Literals"

+
+

This requirements class adds:

+
+
+
    +
  • +

    a set of Dimensionally Extended Nine-intersection Model (DE-9IM) relation operators that may be used to add spatial predicates to a CQL2 filter expression. These operators are implemented in CQL2 as standardized functions.

    +
  • +
+
+
+

7.7.1. Spatial Functions

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

Requirement 13

+

/req/spatial-functions/spatial-functions

+

A

+

The server SHALL support all standardized spatial comparison functions as defined by the BNF rule spatialFunction in CQL2 BNF.

+
+
+

This clause specifies a set of standardized spatial comparison functions that can be used to evaluate whether a specific spatial relationship exists between a pair of geometries.

+
+
+

The definition of these spatial comparison functions is based on a Dimensionally Extended 9-Intersection Model (DE-9IM) and further discussion and explanation about this model can be found at DE-9IM and Dimensionally Extended 9-Intersection Model.

+
+
+

Consider geometries a and b.

+
+
+

The spatial relationships between a and b can be represented by the following intersection matrix (see DE-9IM):

+
+
+
+Within +
+
Figure 1. The DE-9IM intersection matrix.
+
+
+

I() represents the set of all positions in the interior of the geometry, B() represents the set of all positions on the boundary of the geometry and E() represents the set of all exterior positions. dim() represents the dimension of the intersection of the interior (I), boundary (B) and exterior (E) of geometries a and b.

+
+
+

The value of each cell in this intersection matrix is either:

+
+
+
    +
  • +

    0 (i.e. the dimension of the intersection is a point),

    +
  • +
  • +

    1 (i.e. the dimension of the intersection is a line),

    +
  • +
  • +

    2 (i.e. the dimension of the intersection is an area) or,

    +
  • +
  • +

    for the empty set or no intersection.

    +
  • +
+
+
+

These values are sometimes simplified to:

+
+
+
    +
  • +

    T representing {0,1,2} (if the actual value of the dimension does not matter),

    +
  • +
  • +

    F representing the empty set and,

    +
  • +
  • +

    * representing a value that is not relevant to the evaluation of a spatial comparison function.

    +
  • +
+
+
+

An example of such an intersection matrix is:

+
+
+

[T*F**FFF*]

+
+
+

The following table lists the mathematical definitions of each standardized spatial comparison function as described in OpenGIS® Implementation Standard for Geographic information - Simple feature access - Part 1: Common architecture and also using DE-9IM.

+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 4. Mathematical definitions of standardized spatial comparison functions
Spatial comparison functionDefinitionIntersection matrix

S_CONTAINS

S_CONTAINS(a,b) ⬄ b WITHIN a

[T*****FF*]

S_CROSSES

S_CROSSES(a,b) ⬄ [I(a) ∩ I(b) ≠ ∅) ∧ (a ∩ b ≠ a) ∧ (a ∩ b ≠ b)]

[T*T******], [T*****T**], [0********]

S_DISJOINT

S_DISJOINT(a,b) ⬄ a ∩ b = ∅

[FF*FF****]

S_EQUALS

S_EQUALS(a,b) ⬄ a ⊆ b ∧ b ⊆ a

[T*F**FFF*]

S_INTERSECTS

S_INTERSECTS(a,b) ⬄ ! a DISJOINT b

[T********],[*T*******],[***T*****],[****T****]

S_OVERLAPS

S_OVERLAPS(a,b) ⬄ (dim(I(a)) = dim(I(b)) = dim(I(a) ∩ I(b))) ∧ (a ∩ b ≠ a) ∧ (a ∩ b ≠ b)

[T*T***T**],[1*T***T**],

S_TOUCHES

S_TOUCHES(a,b) ⬄ (I(a) ∩ I(b) = ∅) ∧ (a ∩ b) ≠ ∅

[FT*******],[F**F*****],[F***T****]

S_WITHIN

S_WITHIN(a,b) ⬄ (a ∩ b = a) ∧ (I(a) ∩ E(b) = ∅)

[T*F**F***]

+
+

The following diagrams illustrate the meaning of the S_CROSSES, S_OVERLAPS, S_TOUCHES and S_WITHIN spatial comparison functions.

+
+
+
+Crosses +
+
Figure 2. Examples of the S_CROSSES relationship Polygon/LineString(a) and LineString/LineString(b).
+
+
+
+Overlaps +
+
Figure 3. Examples of the S_OVERLAPS relationship Polygon/LineString(a) and LineString/LineString(b).
+
+
+
+Touches +
+
Figure 4. Examples of the S_TOUCHES relationship
+
+
+
+Within +
+
Figure 5. Examples of the S_WITHIN relationship Polygon/Polygon(a), Polygon/LineString(b), LineString/LineString(c), and Polygon/Point(d)
+
+
+ + + + + +
+
Note
+
+If geometry a S_CONTAINS geometry b, then geometry b is S_WITHIN geometry a. +
+
+
+
Example 16. Example of a spatial relationship between a property and a literal geometry.
+
+
+
+
S_CROSSES(road,POLYGON((43.7286 -79.2986, 43.7311 -79.2996, 43.7323 -79.2972,
+                        43.7326 -79.2971, 43.7350 -79.2981, 43.7350 -79.2982,
+                        43.7352 -79.2982, 43.7357 -79.2956, 43.7337 -79.2948,
+                        43.7343 -79.2933, 43.7339 -79.2923, 43.7327 -79.2947,
+                        43.7320 -79.2942, 43.7322 -79.2937, 43.7306 -79.2930,
+                        43.7303 -79.2930, 43.7299 -79.2928, 43.7286 -79.2986)))
+
+
+
+
+
{
+  "op": "s_crosses",
+  "args": [
+    { "property": "road" },
+    {
+      "type": "Polygon",
+      "coordinates": [
+        [
+          [ 43.7286, -79.2986 ], [ 43.7311, -79.2996 ], [ 43.7323, -79.2972 ],
+          [ 43.7326, -79.2971 ], [ 43.7350, -79.2981 ], [ 43.7350, -79.2982 ],
+          [ 43.7352, -79.2982 ], [ 43.7357, -79.2956 ], [ 43.7337, -79.2948 ],
+          [ 43.7343, -79.2933 ], [ 43.7339, -79.2923 ], [ 43.7327, -79.2947 ],
+          [ 43.7320, -79.2942 ], [ 43.7322, -79.2937 ], [ 43.7306, -79.2930 ],
+          [ 43.7303, -79.2930 ], [ 43.7299, -79.2928 ], [ 43.7286, -79.2986 ]
+        ]
+      ]
+    }
+  ]
+}
+
+
+
+
+
+
+
+

7.8. Requirements Class "Temporal Functions"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/temporal-functions

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic CQL2"

Dependency

W3C/OGC Time Ontology in OWL, Topological Temporal Relations

+
+

A temporal predicate evaluates two time-valued expressions to determine, if the expressions satisfy the requirements of the specified standardized temporal comparison function.

+
+
+

The operands in a temporal predicate are temporal geometries. A temporal geometry is either an instant or an interval.

+
+
+

7.8.1. Temporal data types and instances

+
+

An instant is either a date (rule dateInstant) or a timestamp (rule timestampInstant) in accordance with RFC 3339 (RFC 3339 rules full-date or date-time). Note that since time is continuous, every instant has a duration and a start/end. Nevertheless, the geometry can be considered an instant in the temporal resolution that is applicable for the specific property.

+
+
+

An interval is the time between a start instant and an end instant, including both bounding instances (rule intervalInstance). Unbounded interval ends are represented by a double-dot string ("..") based on the convention specified in ISO 8601-2.

+
+
+

CQL2 follows ISO 8601-1/ISO 8601-2 in defining intervals as closed at both start and end. Note that some implementations and other specifications use a different definition and it may be necessary to convert between the interval representations. For example, SQL uses half-closed intervals - closed at the start, open at the end.

+
+
+

Depending on the implementation environment, the underlying datastore may or may not support intervals as data types of properties. If not, intervals are typically represented by two separate properties that are instants, one for the start and one for the end of the interval.

+
+
+

All temporal geometries are in the Gregorian Calendar. This is a deliberate restriction to keep implementations of CQL2 simple, avoiding requirements to transform time instants to other temporal coordinate reference systems, but still cover a large number of use cases. This is consistent with the use of RFC 3339 as a key standard for expressing date and time on the internet, including in the OGC API Standards.

+
+
+

For intervals, the following representations are used:

+
+
+
    +
  • +

    Text: an INTERVAL function with two instants or double-dot strings as parameters;

    +
  • +
  • +

    JSON: an object with an interval member with an array of two instants or double-dot strings as parameters.

    +
  • +
+
+
+

In case two instants are provided, both instants have the same granularity (i.e., they are either timestamps or dates).

+
+
+ + + + + +
+
Note
+
+Instants are also scalar data types; for the representations and examples of instances see Scalar data types. +
+
+
+
Example 17. Interval examples
+
+
+
    +
  • +

    intervals (Text)

    +
  • +
+
+
+
+
INTERVAL('1969-07-16', '1969-07-24')
+INTERVAL('1969-07-16T05:32:00Z', '1969-07-24T16:50:35Z')
+INTERVAL('2019-09-09', '..')
+
+
+
+
    +
  • +

    intervals (JSON)

    +
  • +
+
+
+
+
{ "interval": [ "1969-07-16", "1969-07-24" ] }
+{ "interval": [ "1969-07-16T05:32:00Z", "1969-07-24T16:50:35Z" ] }
+{ "interval": [ "2019-09-09", ".." ] }
+
+
+
+
+
+
+

7.8.2. Temporal Functions

+
+

The standardized temporal comparison functions in CQL2 are based on the temporal operator definitions in the W3C/OGC Time Ontology in OWL.

+
+
+ + + + + +
+
Note
+
+Simple temporal predicates involving time instants can also be evaluated using the standard comparison operators. +
+
+
+

The following table specifies the definition of the standardized temporal comparison functions where both operands may be instants or intervals, including mixed combinations.

+
+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 5. Definitions of standardized temporal comparison functions that support both instants and intervals
Temporal comparison functionDefinition (t1: first operand, t2: second operand)

T_AFTER

See after

T_BEFORE

See before

T_DISJOINT

(t1 T_BEFORE t2) OR (t1 T_AFTER t2)

T_EQUALS

Start and end of t1 and t2 are coincident

T_INTERSECTS

NOT (t1 T_DISJOINT t2)

+
+

Additional temporal comparison functions are available, but only applicable for intervals. Using these functions with instants will result in a client error.

+
+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 6. Definitions of standardized temporal comparison function between intervals
Temporal comparison functionDefinition

T_CONTAINS

See intervalContains

T_DURING

See intervalDuring

T_FINISHEDBY

See intervalFinishedBy

T_FINISHES

See intervalFinishes

T_MEETS

See intervalMeets

T_METBY

See intervalMetBy

T_OVERLAPPEDBY

See intervalOverlappedBy

T_OVERLAPS

See intervalOverlaps

T_STARTEDBY

See intervalStarts

T_STARTS

See intervalStartedBy

+
+

The following diagram illustrates the meaning of most of the standardized temporal comparison functions when applied to intervals.

+
+
+
+TemporalOps +
+
Figure 6. The elementary relations between time intervals
+
+ ++++ + + + + + + + + + + + + + + + + + + +

Requirement 14

+

/req/temporal-operators/temporal-predicates

+

A

+

If the requirements of the standardized temporal comparison function are satisfied, then the predicate SHALL evaluate to the Boolean value TRUE.

+

B

+

If the requirements of the standardized temporal comparison function are not satisfied, then the predicate SHALL evaluate to the Boolean value FALSE.

+

C

+

If the either temporal expression (rule temporalExpression) of the standardized temporal comparison function is NULL, then the predicate SHALL evaluate to the value NULL.

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

Requirement 15

+

/req/temporal-functions/temporal-functions

+

A

+

The server SHALL support all temporal functions as defined by the BNF rule temporalFunction +in CQL2 BNF.

+

B

+

The temporal functions SHALL be evaluated as defined in the tables Table 5 and Table 6.

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

Permission 8

+

/per/temporal-functions/temporal-operands

+

A

+

The server MAY not support a temporalInstance as the first operand (rule temporalExpression) in rule temporalPredicate.

+

B

+

The server MAY not support a propertyName as the second operand (rule temporalExpression) in rule temporalPredicate.

+
+
+
+

7.8.3. Type casts

+
+

As stated in Type casts, the evaluation of filter expressions that involve type casts is system dependent.

+
+
+

For example, a system that evaluates the interval INTERVAL('2022-01-01','2022-04-11T12:41:13Z') can, for example,

+
+
+
    +
  • +

    throw an error (incompatible types in an interval);

    +
  • +
  • +

    cast the value to an interval of dates, e.g., INTERVAL('2022-01-01','2022-04-11');

    +
  • +
  • +

    cast the value to an interval of timestamps, e.g., INTERVAL('2022-01-01Z00:00:00Z','2022-04-11T12:41:13Z').

    +
  • +
+
+
+
+

7.8.4. Examples

+
+
Example 18. Examples of temporal predicate using T_INTERSECTS
+
+
+
+
T_INTERSECTS(event_time, INTERVAL('1969-07-16T05:32:00Z', '1969-07-24T16:50:35Z'))
+
+
+
+
+
{
+  "op": "t_intersects",
+  "args": [
+    { "property": "event_time" },
+    { "interval": [ "1969-07-16T05:32:00Z", "1969-07-24T16:50:35Z" ] }
+  ]
+}
+
+
+
+
+
+
Example 19. Examples of temporal relationships using a property and a temporal literal.
+
+
+
+
T_DURING(INTERVAL(touchdown, liftOff), INTERVAL('1969-07-16T13:32:00Z', '1969-07-24T16:50:35Z'))
+
+
+
+
+
{
+  "op": "t_during",
+  "args": [
+    { "interval": [ { "property": "touchdown" }, { "property": "liftOff" } ] },
+    { "interval": [ "1969-07-16T13:32:00Z", "1969-07-24T16:50:35Z" ] }
+  ]
+}
+
+
+
+
+
+
+
+

7.9. Requirements class "Array Functions"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/array-functions

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic CQL2"

+
+

This clause specifies requirements for supporting array expression in CQL2.

+
+
+

7.9.1. Arrays

+
+

An array is a bracket-delimited, comma-separated list of array elements. An array element is either a scalar value, +a geometry, an interval, or another array.

+
+
+
Example 20. Array examples
+
+
+
    +
  • +

    arrays (Text)

    +
  • +
+
+
+
+
( 'a', 'c' )
+( 'a', true, 1 )
+( DATE('1969-07-16'), DATE('1969-07-20'), DATE('1969-07-24') )
+
+
+
+
    +
  • +

    arrays (JSON)

    +
  • +
+
+
+
+
[ "a", "c" ]
+[ "a", true, 1 ]
+[ { "date" : "1969-07-16" }, { "date" : "1969-07-20" }, { "date" : "1969-07-24" } ]
+
+
+
+
+
+
+

7.9.2. Array Functions

+
+

Array expressions can be tested in a predicate for equality, if one array +is a subset of another, if one array is a superset of another or if two +arrays overlap or share elements using a standardized set of array comparison +functions.

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

Requirement 16

+

/req/array-functions/array-predicates

+

A

+

The server SHALL support arrays as defined by the BNF rule arrayPredicate in CQL2 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 an array of values.

+

C

+

The semantics of the standardized array comparison functions SHALL be evaluated as follows:

+
+
+
    +
  • +

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

    +
  • +
  • +

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

    +
  • +
  • +

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

    +
  • +
  • +

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

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

Permission 9

+

/per/array-functions/array-predicates

+

A

+

The server MAY not support an array as the first operand (rule arrayExpression) in rule arrayPredicate.

+

B

+

The server MAY not support a propertyName as the second operand (rule arrayExpression) in rule arrayPredicate.

+
+
+ + + + + +
+
Note
+
+Support for the BNF rule function is added by +the requirements class Functions. +Support for the BNF rule arithmeticExpression is added by +the requirements class Arithmetic Expressions. +
+
+
+
+

7.9.3. Examples

+
+
Example 21. Evaluate if the value of an array property contains the specified subset of values.
+
+
+
+
A_CONTAINS(layer:ids, ('layers-ca','layers-us'))
+
+
+
+
+
{
+  "op": "a_contains",
+  "args": [
+    { "property": "layer:ids" },
+    [ "layers-ca", "layers-us" ]
+  ]
+}
+
+
+
+
+
+
+
+

7.10. Requirements Class "Property-Property Comparisons"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/property-property

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic CQL2"

Conditional Dependency

Requirements Class "Advanced Comparison Operators"

Conditional Dependency

Requirements Class "Basic Spatial Functions"

Conditional Dependency

Requirements Class "Spatial Functions"

Conditional Dependency

Requirements Class "Temporal Functions"

Conditional Dependency

Requirements Class "Array Functions"

+
+

This requirements class adds support for properties on the right side of predicates and for literal on the left side of predicates.

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

Requirement 17

+

/req/property-property/withdraw-permissions

+

A

+

The following permissions SHALL not apply:

+
+
+
    +
  • +

    /per/basic-cql2/cql2filter

    +
  • +
  • +

    /per/advanced-comparison-operators/like-predicate

    +
  • +
  • +

    /per/advanced-comparison-operators/between-predicate

    +
  • +
  • +

    /per/advanced-comparison-operators/in-predicate

    +
  • +
  • +

    /per/basic-spatial-functions/spatial-predicates

    +
  • +
  • +

    /per/temporal-functions/temporal-predicates

    +
  • +
  • +

    /per/array-functions/array-predicates

    +
  • +
+
+
+
Example 22. Example of a spatial relationship between two literal geometries.
+
+
+
+
S_CROSSES(LINESTRING(43.72992 -79.2998, 43.73005 -79.2991, 43.73006 -79.2984,
+                     43.73140 -79.2956, 43.73259 -79.2950, 43.73266 -79.2945,
+                     43.73320 -79.2936, 43.73378 -79.2936, 43.73486 -79.2917),
+        POLYGON((43.7286 -79.2986, 43.7311 -79.2996, 43.7323 -79.2972, 43.7326 -79.2971,
+                 43.7350 -79.2981, 43.7350 -79.2982, 43.7352 -79.2982, 43.7357 -79.2956,
+                 43.7337 -79.2948, 43.7343 -79.2933, 43.7339 -79.2923, 43.7327 -79.2947,
+                 43.7320 -79.2942, 43.7322 -79.2937, 43.7306 -79.2930, 43.7303 -79.2930,
+                 43.7299 -79.2928, 43.7286 -79.2986)))
+
+
+
+
+
{
+  "op": "s_crosses",
+  "args": [
+    {
+      "type": "LineString",
+      "coordinates": [
+        [ 43.72992, -79.2998 ], [ 43.73005, -79.2991 ], [ 43.73006, -79.2984 ],
+        [ 43.73140, -79.2956 ], [ 43.73259, -79.2950 ], [ 43.73266, -79.2945 ],
+        [ 43.73320, -79.2936 ], [ 43.73378, -79.2936 ], [ 43.73486, -79.2917 ]
+      ]
+    },
+    {
+      "type": "Polygon",
+      "coordinates": [
+        [
+          [ 43.7286, -79.2986 ], [ 43.7311, -79.2996 ], [ 43.7323, -79.2972 ],
+          [ 43.7326, -79.2971 ], [ 43.7350, -79.2981 ], [ 43.7350, -79.2982 ],
+          [ 43.7352, -79.2982 ], [ 43.7357, -79.2956 ], [ 43.7337, -79.2948 ],
+          [ 43.7343, -79.2933 ], [ 43.7339, -79.2923 ], [ 43.7327, -79.2947 ],
+          [ 43.7320, -79.2942 ], [ 43.7322, -79.2937 ], [ 43.7306, -79.2930 ],
+          [ 43.7303, -79.2930 ], [ 43.7299, -79.2928 ], [ 43.7286, -79.2986 ]
+        ]
+      ]
+    }
+  ]
+}
+
+
+
+
+
+
Example 23. Examples of temporal relationships using temporal literals.
+
+
+
+
T_DURING(INTERVAL('1969-07-20T20:17:40Z', '1969-07-21T17:54:00Z'), INTERVAL('1969-07-16T13:32:00Z', '1969-07-24T16:50:35Z'))
+
+
+
+
+
{
+  "op": "t_during",
+  "args": [
+    { "interval": [ "1969-07-20T20:17:40Z", "1969-07-21T17:54:00Z" ] },
+    { "interval": [ "1969-07-16T13:32:00Z", "1969-07-24T16:50:35Z" ] }
+  ]
+}
+
+
+
+
+
+
+

7.11. Requirements Class "Functions"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/functions

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic CQL2"

+
+

This sub-clause specifies requirements for supporting custom functions in CQL2. Functions +allow implementations to extend the language.

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

Requirement 18

+

/req/functions/functions

+

A

+

The server SHALL support custom functions as defined by the BNF rules function in CQL2 BNF +with the exception of the rule arithmeticExpression in argument.

+

B

+

The function SHALL evaluate to its return value that is allowed in the same rule +in which the function is used.

+
+
+ + + + + +
+
Note
+
+Support for the BNF rule arithmeticExpression is added by +the requirements class Arithmetic Expressions. +
+
+
+
Example 24. 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 CQL2 but is an example of a function that an implementation may offer that returns a geometry value.

+
+
+
+
S_WITHIN(road,Buffer(geometry,10,'m'))
+
+
+
+
+
{
+  "op": "s_within",
+  "args": [
+    { "property": "road" },
+    {
+      "op": "Buffer",
+      "args": [
+        { "property": "geometry" },
+        10,
+        "m"
+      ]
+    }
+  ]
+}
+
+
+
+
+
+
+

7.12. Requirements Class "Arithmetic Expressions"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/arithmetic

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic CQL2"

+
+

This clause specifies requirements for supporting arithmetic expressions in CQL2. +An arithmetic expression is an expression composed of an arithmetic operand +(a property name, a number or a function that returns a number), an arithmetic +operator (i.e., one of +, -, *, /, %, div, or ^) and another arithmetic operand.

+
+
+

+, -, *, and / are the four basic arithmetic operations (addition, subtraction, multiplication and division). In addition, the modulo operator (%), integer division (div), and the exponention operator (^) are supported.

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

Requirement 19

+

/req/arithmetic/arithmetic

+

A

+

The server SHALL support arithmetic expressions as defined by the BNF rules +arithmeticExpression in CQL2 BNF with the exception of the rule function in arithmeticOperand.

+

B

+

Is any arithmeticOperand in an arithmetic expression is NULL, then the expression SHALL evaluate to NULL.

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

8. Requirements classes for encodings

+
+
+

8.1. Overview

+
+

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

+
+
+
+

8.2. Requirements Class "CQL2 Text"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/cql2-text

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic CQL2"

Conditional Dependency

Simple feature access - Part 1: Common architecture, Well-known Text Representation for Geometry

Conditional Dependency

Requirements Class "Advanced Comparison Operators"

Conditional Dependency

Requirements Class "Case-insensitive Comparisons"

Conditional Dependency

Requirements Class "Accent-insensitive Comparisons"

Conditional Dependency

Requirements Class "Basic Spatial Functions"

Conditional Dependency

Requirements Class "Basic Spatial Functions with additional Spatial Literals"

Conditional Dependency

Requirements Class "Spatial Functions"

Conditional Dependency

Requirements Class "Temporal Functions"

Conditional Dependency

Requirements Class "Array Functions"

Conditional Dependency

Requirements Class "Property-Property Comparisons"

Conditional Dependency

Requirements Class "Functions"

Conditional Dependency

Requirements Class "Arithmetic Expressions"

+
+

This requirements class defines a Well Known Text (WKT) encoding of CQL2. Such an +encoding would be suitable for use with the GET query parameter such as the +filter query parameter specified by the "Filter" requirements class +in OGC API - Features - Part 3: Filtering.

+
+
+

The "CQL2 Text" encoding is defined by the BNF grammar defined in CQL2 BNF.

+
+
+

Keywords in the BNF grammar are case-insensitive. Augmented BNF for Syntax Specifications states:

+
+
+
+
+

ABNF strings are case insensitive and the character set for these strings is US-ASCII.

+
+
+
+
+

The list of CQL2 keywords includes:

+
+
+
    +
  • +

    "A_EQUALS"

    +
  • +
  • +

    "A_CONTAINS"

    +
  • +
  • +

    "A_CONTAINEDBY"

    +
  • +
  • +

    "A_OVERLAPS"

    +
  • +
  • +

    "ACCENTI"

    +
  • +
  • +

    "AND"

    +
  • +
  • +

    "BBOX"

    +
  • +
  • +

    "BETWEEN"

    +
  • +
  • +

    "CASEI"

    +
  • +
  • +

    "DATE"

    +
  • +
  • +

    "DIV"

    +
  • +
  • +

    "FALSE"

    +
  • +
  • +

    "GEOMETRYCOLLECTION"

    +
  • +
  • +

    "IN"

    +
  • +
  • +

    "IS"

    +
  • +
  • +

    "LIKE"

    +
  • +
  • +

    "LINESTRING"

    +
  • +
  • +

    "MULTILINESTRING"

    +
  • +
  • +

    "MULTIPOINT"

    +
  • +
  • +

    "MULTIPOLYGON"

    +
  • +
  • +

    "NOT"

    +
  • +
  • +

    "NULL"

    +
  • +
  • +

    "OR"

    +
  • +
  • +

    "POINT"

    +
  • +
  • +

    "POLYGON"

    +
  • +
  • +

    "S_INTERSECTS"

    +
  • +
  • +

    "S_EQUALS"

    +
  • +
  • +

    "S_DISJOINT"

    +
  • +
  • +

    "S_TOUCHES"

    +
  • +
  • +

    "S_WITHIN"

    +
  • +
  • +

    "S_OVERLAPS"

    +
  • +
  • +

    "S_CROSSES"

    +
  • +
  • +

    "S_CONTAINS"

    +
  • +
  • +

    "T_AFTER"

    +
  • +
  • +

    "T_BEFORE"

    +
  • +
  • +

    "T_CONTAINS"

    +
  • +
  • +

    "T_DISJOINT"

    +
  • +
  • +

    "T_DURING"

    +
  • +
  • +

    "T_EQUALS"

    +
  • +
  • +

    "T_FINISHEDBY"

    +
  • +
  • +

    "T_FINISHES"

    +
  • +
  • +

    "T_INTERSECTS"

    +
  • +
  • +

    "T_MEETS"

    +
  • +
  • +

    "T_METBY"

    +
  • +
  • +

    "T_OVERLAPPEDBY"

    +
  • +
  • +

    "T_OVERLAPS"

    +
  • +
  • +

    "T_STARTEDBY"

    +
  • +
  • +

    "T_STARTS"

    +
  • +
  • +

    "TIMESTAMP"

    +
  • +
  • +

    "TRUE"

    +
  • +
+
+
+

If a queryable uses a property name that is one of the keywords, the property name can be used in double quotes to avoid conflicts with the keyword.

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

Requirement 20

+

/req/cql2-text/basic-cql2

+

A

+

The server SHALL be able to parse and evaluate all filter expressions encoded as a text string that validate against the BNF rules identified in the Basic CQL2 requirements class.

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

Requirement 21

+

/req/cql2-text/escaping

+

A

+

The escape character in a character literal SHALL be the backslash (\\).

+

B

+

Embedded single quotations (') in a character literal SHALL be escaped using a double single quotation ('') OR the backslash (\\) character.

+

C

+

The server SHALL be able to parse the following escaped sequences for encoding control characters in a character literal:

+
+
+
    +
  • +

    '\a' BELL CHR(07)

    +
  • +
  • +

    '\b' BACKSPACE CHR(08)

    +
  • +
  • +

    '\t' HORIZONTAL TAB CHR(09)

    +
  • +
  • +

    '\n' NEWLINE CHR(10)

    +
  • +
  • +

    '\v' VERTICAL TAB CHR(11)

    +
  • +
  • +

    '\f' FORM FEED CHR(12)

    +
  • +
  • +

    '\r' CARRIAGE RETURN CHR(13)

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

Requirement 22

+

/req/cql2-text/advanced-comparison-operators

+

Condition

+

Server implements requirements class Advanced Comparison Operators

+

A

+

The server SHALL be able to parse and evaluate all spatial functions encoded as a text string that validate against the BNF production fragments identified in the Advanced Comparison Operators requirements class.

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

Requirement 23

+

/req/cql2-text/case-insensitive-comparison

+

Condition

+

Server implements requirements class Case-insensitive Comparisons

+

A

+

The server SHALL be able to parse and evaluate all standardized functions encoded as a text string that validate against the BNF production fragments identified in the Case-insensitive Comparisons requirements class.

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

Requirement 24

+

/req/cql2-text/accent-insensitive-comparison

+

Condition

+

Server implements requirements class Accent-insensitive Comparisons

+

A

+

The server SHALL be able to parse and evaluate all standardized functions encoded as a text string that validate against the BNF production fragments identified in the Accent-insensitive Comparisons requirements class.

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

Requirement 25

+

/req/cql2-text/basic-spatial-functions

+

Condition

+

Server implements requirements class Basic Spatial Functions

+

A

+

The server SHALL be able to parse and evaluate all standardized spatial comparison functions encoded as a text string that validate against the BNF production fragments identified in the Basic Spatial Functions requirements class.

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

Requirement 26

+

/req/cql2-text/basic-spatial-functions-plus

+

Condition

+

Server implements requirements class Basic Spatial Functions with additional Spatial Literals

+

A

+

The server SHALL be able to parse all spatial instances encoded as a text string that validate against the BNF production fragments identified in the Basic Spatial Functions with additional Spatial Literals requirements class.

+

B

+

The server SHALL support spatial literals with coordinates in a 2D or 3D CRS, independent of including the Z or not in the value.

+
+
+

OGC WKT uses a "Z" character to distinguish the dimensionality of the coordinate reference system (CRS), e.g. POINT(7 51) for a 2D CRS and POINT Z(7 51 100) for a 3D CRS. In CQL2 Text, processors are required to be more tolerant and to determine the coordinate dimension from the coordinates.

+
+
+

When creating a CQL2 Text expression, it is recommended to encode a geometry literal as required by OGC WKT.

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

Requirement 27

+

/req/cql2-text/spatial-functions

+

Condition

+

Server implements requirements class Spatial Functions

+

A

+

The server SHALL be able to parse and evaluate all standardized spatial comparison functions encoded as a text string that validate against the BNF production fragments identified in the Spatial Functions requirements class.

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

Requirement 28

+

/req/cql2-text/temporal-functions

+

Condition

+

Server implements requirements class Temporal Functions

+

A

+

The server SHALL be able to parse and evaluate all standardized temporal comparison functions encoded as a text string that validate against the BNF production fragments identified in the Temporal Functions requirements class.

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

Requirement 29

+

/req/cql2-text/arrays

+

Condition

+

Server implements requirements class Array Functions

+

A

+

The server SHALL be able to parse and evaluate all array expressions encoded as a text string that validate against the BNF production fragments identified in the Array Expressions requirements class.

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

Requirement 30

+

/req/cql2-text/property-property

+

Condition

+

Server implements requirements class Property-Property Comparisons

+

A

+

The server SHALL be able to parse and evaluate literal values on the left-hand side of comparison, spatial, temporal or array operators and property references on the right-hand side of such operators.

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

Requirement 31

+

/req/cql2-text/functions

+

Condition

+

Server implements requirements class Functions

+

A

+

The server SHALL be able to parse and evaluate all function call expressions encoded as a text string that validate against the BNF production fragments identified in the Functions requirements class.

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

Requirement 32

+

/req/cql2-text/arithmetic

+

Condition

+

Server implements requirements class Arithmetic Expressions

+

A

+

The server SHALL be able to parse and evaluate all arithmetic expressions encoded as a text string that validate against the BNF production fragments identified in the Arithmetic Expressions requirements class.

+
+
+
+

8.3. Requirements Class "CQL2 JSON"

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

Requirements Class

http://www.opengis.net/spec/cql2/1.0/req/cql2-json

Target type

Servers that evaluate filter expressions

Dependency

Requirements Class "Basic CQL2"

Conditional Dependency

GeoJSON, Geometry Objects

Conditional Dependency

Requirements Class "Advanced Comparison Operators"

Conditional Dependency

Requirements Class "Case-insensitive Comparisons"

Conditional Dependency

Requirements Class "Accent-insensitive Comparisons"

Conditional Dependency

Requirements Class "Basic Spatial Functions"

Conditional Dependency

Requirements Class "Basic Spatial Functions with additional Spatial Literals"

Conditional Dependency

Requirements Class "Spatial Functions"

Conditional Dependency

Requirements Class "Temporal Functions"

Conditional Dependency

Requirements Class "Array Functions"

Conditional Dependency

Requirements Class "Property-Property Comparisons"

Conditional Dependency

Requirements Class "Functions"

Conditional Dependency

Requirements Class "Arithmetic Expressions"

+
+

This requirements class defines a JSON encoding of CQL2. Such an encoding +would be suitable as the body of an HTTP POST request.

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

Requirement 33

+

/req/cql2-json/basic-cql2

+

A

+

The server SHALL be able to parse and evaluate all filter expressions encoded as JSON that validate against the JSON Schema in JSON Schema for CQL2 and that do not use the following schema components:

+
+
+
    +
  • +

    "#/$defs/isLikePredicate"

    +
  • +
  • +

    "#/$defs/isBetweenPredicate"

    +
  • +
  • +

    "#/$defs/isInListPredicate"

    +
  • +
  • +

    "#/$defs/casei"

    +
  • +
  • +

    "#/$defs/accenti"

    +
  • +
  • +

    "#/$defs/spatialPredicate"

    +
  • +
  • +

    "#/$defs/temporalPredicate"

    +
  • +
  • +

    "#/$defs/arrayPredicate"

    +
  • +
  • +

    "#/$defs/functionRef"

    +
  • +
  • +

    "#/$defs/arithmeticExpression"

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

Permission 10

+

/per/cql2-json/basic-cql2

+

A

+

The server MAY not support

+
+
+
    +
  • +

    the schema component "#/$defs/propertyRef" in an operand of a comparison operator, standardized spatial, temporal or array comparison functions starting with the second operand,

    +
  • +
  • +

    the schema components "#/$defs/characterExpression", "#/$defs/numericExpression", "#/$defs/spatialInstance", "#/$defs/instantInstance", "#/$defs/intervalInstance", "#/$defs/array", "#/$defs/functionRef", or a boolean literal in the first operand of a comparison operator, standardized spatial, temporal or array comparison function.

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

Requirement 34

+

/req/cql2-text/advanced-comparison-operators

+

Condition

+

Server implements requirements class Advanced Comparison Operators

+

A

+

In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema components:

+
+
+
    +
  • +

    "#/$defs/isLikePredicate"

    +
  • +
  • +

    "#/$defs/isBetweenPredicate"

    +
  • +
  • +

    "#/$defs/isInListPredicate"

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

Requirement 35

+

/req/cql2-text/case-insensitive-comparison

+

Condition

+

Server implements requirements class Case-insensitive Comparisons

+

A

+

In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:

+
+
+
    +
  • +

    "#/$defs/casei"

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

Requirement 36

+

/req/cql2-text/accent-insensitive-comparison

+

Condition

+

Server implements requirements class Accent-insensitive Comparisons

+

A

+

In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:

+
+
+
    +
  • +

    "#/$defs/accenti"

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

Requirement 37

+

/req/cql2-json/basic-spatial-functions

+

Condition

+

Server implements requirements class Basic Spatial Functions

+

A

+

The server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema components:

+
+
+
    +
  • +

    "#/$defs/spatialPredicate" where property "op" has the value "s_intersects"

    +
  • +
  • +

    "#/$defs/spatialInstance" where the value is either "#/$defs/point" or "#/$defs/bboxLiteral"

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

Requirement 38

+

/req/cql2-json/basic-spatial-functions-plus

+

Condition

+

Server implements requirements class Basic Spatial Functions with additional Spatial Literals

+

A

+

The server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema components:

+
+
+
    +
  • +

    "#/$defs/spatialPredicate" where property "op" has the value "s_intersects"

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

Requirement 39

+

/req/cql2-json/spatial-functions

+

Condition

+

Server implements requirements class Spatial Functions

+

A

+

The server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema components:

+
+
+
    +
  • +

    "#/$defs/spatialPredicate"

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

Requirement 40

+

/req/cql2-json/temporal-functions

+

Condition

+

Server implements requirements class Temporal Functions

+

A

+

In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema components:

+
+
+
    +
  • +

    "#/$defs/temporalPredicate"

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

Requirement 41

+

/req/cql2-json/arrays

+

Condition

+

Server implements requirements class Array Functions

+

A

+

In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:

+
+
+
    +
  • +

    "#/$defs/arrayPredicate"

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

Requirement 42

+

/req/cql2-json/property-property

+

Condition

+

Server implements requirements class Property-Property Comparisons

+

A

+

In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use

+
+
+
    +
  • +

    the schema component "#/$defs/propertyRef" in an operand of a comparison operator, standardized spatial, temporal or array comparison function starting with the second operand,

    +
  • +
  • +

    the schema components "#/$defs/characterExpression", "#/$defs/numericExpression", "#/$defs/spatialInstance", "#/$defs/instantInstance", "#/$defs/intervalInstance", "#/$defs/array", "#/$defs/functionRef", or a boolean literal in the first operand of a comparison operator, standardized spatial, temporal or array comparison function.

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

Requirement 43

+

/req/cql2-json/functions

+

Condition

+

Server implements requirements class Functions

+

A

+

In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:

+
+
+
    +
  • +

    "#/$defs/functionRef"

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

Requirement 44

+

/req/cql2-json/arithmetic

+

Condition

+

Server implements requirements class Arithmetic Expressions

+

A

+

In addition to the Basic CQL2 requirement, the server SHALL be able to parse and evaluate filter expressions encoded as JSON that use the following schema component:

+
+
+
    +
  • +

    "#/$defs/arithmeticExpression"

    +
  • +
+
+
+
+

8.4. XML encoding

+
+

This document does not specifically define an XML-encoding for CQL2. However, it is recognized that XML is still in common use and so implementers are directed to review the OGC Filter Encoding 2.0 standard which defines an XML-encoding for filter expressions that closely matches most of the functionality of CQL2.

+
+
+
+
+
+

9. Media Types

+
+
+

No media type has been registered for the CQL2 encodings. The reason is the assumption that filter expressions as such will rarely be used as +standalone documents, but usually be part of another document, e.g. a HTTP request or response, and be embedded in it.

+
+
+
+
+
+

Annex A: Abstract Test Suite (Normative)

+
+
+

This test suite uses the Given-When-Then notation to specify the tests.

+
+
+

Each implementation under test supports the evaluation of filter expressions on one or more data sources. A data source may be, for example, a feature collection in an OGC Web API that implements the OGC API - Features Standard. The implementation must declare the queryable properties (queryables) for each data source.

+
+
+

The requirements specified in this Standard can only be tested, if the test can assess whether the result of an evaluation matches the filter expression. However, in general, the queryables may not be part of the response; that is, it is not possible to perform such an assessment in general without knowledge about the data and the relationship between the queryables and the data. In addition, to assess the implementation of some requirements (e.g., case folding) the test needs to know the data.

+
+
+

With just the knowledge about the queryables and their data types, the tests can typically assess that valid filter expressions for a set of queryables are evaluated without an error. These tests are basic tests specified in this test suite and can be executed against any data.

+
+
+

In addition, to properly test an implementation, conditional tests are provided, if the implementation operates on a test dataset and where the queryables are properties of the features.

+
+
+

The test dataset contains feature types with point, line string and polygon geometries. It is available as a GeoPackage file with the associated queryables specified in JSON Schema for each feature collection in the OGC API Features GitHub repository. The test dataset has been derived from three layers of the Natural Earth vector dataset at scale 1:110 million (ne_110m_admin_0_countries, ne_110m_populated_places_simple, ne_110m_rivers_lake_centerlines). Some columns have been removed and a few columns have been added with random data in order to also test filter expressions on date, timestamp and boolean properties.

+
+
+

The tests assume that

+
+
+
    +
  • +

    all feature properties are also queryables;

    +
  • +
  • +

    the queryable for the feature geometry is geom.

    +
  • +
+
+
+

All eleven conformance classes for the standardization target type "servers that evaluate filter expressions" have the following parameter:

+
+
+
    +
  • +

    Filter Language: The CQL2 encoding to be used in the test, either "CQL2 Text" or "CQL2 JSON".

    +
  • +
+
+
+

General rules for the encoding of all filter expressions in tests:

+
+
+
    +
  • +

    The conformance tests in this annex are specified using the CQL2 BNF grammar. Depending on the Filter Language parameter, the filter expressions have to be instantiated in an executable test as CQL2 Text or CQL2 JSON;

    +
  • +
  • +

    If a property name in a filter expression is a reserved CQL2 keyword, the property name has to be placed in double quotes.

    +
  • +
+
+
+

Executable test suites for the eleven conformance classes will also need to decide on the following questions and support at least one option per question:

+
+
+
    +
  • +

    How to execute the evaluation of a filter expression for a data source? At a minimum, Web API endpoints specified in OGC API - Features - Part 3: Filtering, requirements class "Filter", should be supported;

    +
  • +
  • +

    What are the queryables for a data source? At a minimum, queryables specified using JSON Schema, see OGC API - Features - Part 3: Filtering, requirements class "Filter", should be supported;

    +
  • +
  • +

    What is the format of the response that matches the filter expression? At a minimum, GeoJSON feature collections should be supported.

    +
  • +
+
+
+

To qualify as an OGC Reference Implementation for CQL2, an implementation under test has to

+
+
+
    +
  • +

    support the tests with the test dataset;

    +
  • +
  • +

    support both CQL2 Text and CQL2 JSON;

    +
  • +
  • +

    support at least the conformance classes "Case-insensitive comparison", "Spatial functions" and "Temporal functions" (including all dependencies).

    +
  • +
+
+
+

A.1. Conformance Class "CQL2 Text"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/cql2-text

Target type

+

Servers that evaluate filter expressions

+

Requirements class

Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

+
+

A.1.1. Conformance Test 1

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

Test id:

+

/conf/cql2-text/validate

+

Requirements:

+

all requirements

+

Test purpose:

+

Validate that CQL2 Text is supported by the server

+

Test method:

+

Given:

+
+
+
    +
  • +

    n/a

    +
  • +
+
+
+

When:

+
+
+

Execute conformance tests for all supported conformance classes with the parameter "Filter Language". Use the value "CQL2 Text".

+
+
+

Then:

+
+
+
    +
  • +

    assert that all conformance tests are successful.

    +
  • +
+
+
+
+

A.1.2. Conformance Test 2

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

Test id:

+

/conf/cql2-text/escaping

+

Requirements:

Test purpose:

+

Test escaping in string literals.

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources containing string literals with embedded single quotation (') and/or BELL, and/or BACKSPACE, and/or HORIZONTAL TAB, and/or NEWLINE, and/or VERTICAL TAB, and/or FORM FEED, and/or CARRIAGE RETURN characters.

    +
  • +
+
+
+

When:

+
+
+

Decode each string literal.

+
+
+

Then:

+
+
+
    +
  • +

    assert that the escaped embedded characters have been correctly recovered.

    +
  • +
+
+
+
+
+

A.2. Conformance Class "CQL2 JSON"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/cql2-json

Target type

+

Servers that evaluate filter expressions

+

Requirements class

Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

+
+

A.2.1. Conformance Test 3

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

Test id:

+

/conf/cql2-json/validate

+

Requirements:

+

all requirements

+

Test purpose:

+

Validate that CQL2 JSON is supported by the server

+

Test method:

+

Given:

+
+
+
    +
  • +

    A filter expression

    +
  • +
+
+
+

When:

+
+
+

Execute conformance tests for all supported conformance classes with the parameter "Filter Language". Use the value "CQL2 JSON". Note that the filter expressions in the test cases have to be converted to a CQL2 JSON representation.

+
+
+

Then:

+
+
+
    +
  • +

    assert the validation is successful.

    +
  • +
+
+
+
+
+

A.3. Conformance Class "Basic-CQL2"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2

Target type

+

Servers that evaluate filter expressions

+

Parameter

+

Filter Language: "CQL2 Text" or "CQL2 JSON"

+

Requirements class

+
+

A.3.1. Conformance Test 4

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

Test id:

+

/conf/basic-cql2/basic-test

+

Requirements:

+

n/a

+

Test purpose:

+

Implementation under test provides sufficient information to construct filter expressions and supports comparison predicates

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

n/a

+
+
+

Then:

+
+
+
    +
  • +

    assert that there is at least one queryable for each data source;

    +
  • +
  • +

    assert that the data type (String, Number, Integer, Boolean, Timestamp, Date, Interval, Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, Geometry, GeometryCollection, or Array) is specified for each queryable;

    +
  • +
  • +

    assert that at least one queryable for each data source is of data type String, Boolean, Number, Integer, Timestamp or Date.

    +
  • +
+
+
+
+

A.3.2. Conformance Test 5

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

Test id:

+

/conf/basic-cql2/comparison

+

Requirements:

Test purpose:

+

Test comparison predicates

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
  • +

    Test '/conf/basic-cql2/basic-test' passes.

    +
  • +
+
+
+

When:

+
+
+

For each queryable {queryable} of one of the data types String, Boolean, Number, Integer, Timestamp or Date, evaluate the following filter expressions

+
+
+
    +
  • +

    {queryable} = {value}

    +
  • +
  • +

    {queryable} <> {value}

    +
  • +
  • +

    {queryable} > {value}

    +
  • +
  • +

    {queryable} < {value}

    +
  • +
  • +

    {queryable} >= {value}

    +
  • +
  • +

    {queryable} <= {value}

    +
  • +
+
+
+

where {value} depends on the data type:

+
+
+
    +
  • +

    String: 'foo'

    +
  • +
  • +

    Boolean: true

    +
  • +
  • +

    Number: 3.14

    +
  • +
  • +

    Integer: 1

    +
  • +
  • +

    Timestamp: TIMESTAMP('2022-04-14T14:48:46Z')

    +
  • +
  • +

    Date: DATE('2022-04-14')

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets for each queryable for the operators = and <> have no item in common;

    +
  • +
  • +

    assert that the two result sets for each queryable for the operators > and <= have no item in common;

    +
  • +
  • +

    assert that the two result sets for each queryable for the operators < and >= have no item in common;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.3.3. Conformance Test 6

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

Test id:

+

/conf/basic-cql2/is-null

+

Requirements:

Test purpose:

+

Test IS NULL predicate

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
  • +

    Test '/conf/basic-cql2/basic-test' passes.

    +
  • +
+
+
+

When:

+
+
+

For each queryable {queryable}, evaluate the following filter expressions

+
+
+
    +
  • +

    {queryable} IS NULL

    +
  • +
  • +

    {queryable} is not null

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets for each queryable have no item in common;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.3.4. Conformance Test 7

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

Test id:

+

/conf/basic-cql2/boolean

+

Requirements:

Test purpose:

+

Test boolean filter expression

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources.

    +
  • +
  • +

    Test '/conf/basic-cql2/basic-test' passes.

    +
  • +
+
+
+

When:

+
+
+

For each data source, evaluate the following filter expressions

+
+
+
    +
  • +

    true

    +
  • +
  • +

    false

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the result sets for false are empty;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.3.5. Conformance Test 8

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

Test id:

+

/conf/basic-cql2/test-data

+

Requirements:

+

all requirements

+

Test purpose:

+

Test predicates against the test dataset

+

Test method:

+

Given:

+
+
+
    +
  • +

    The implementation under test uses the test dataset.

    +
  • +
+
+
+

When:

+
+
+

Evaluate each predicate in Predicates and expected results.

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the expected result is returned;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 7. Predicates and expected results
Data SourcePredicateExpected number of items

ne_110m_admin_0_countries

NAME='Luxembourg'

1

ne_110m_admin_0_countries

NAME>='Luxembourg'

84

ne_110m_admin_0_countries

NAME>'Luxembourg'

83

ne_110m_admin_0_countries

NAME<='Luxembourg'

94

ne_110m_admin_0_countries

NAME<'Luxembourg'

93

ne_110m_admin_0_countries

NAME<>'Luxembourg'

176

ne_110m_admin_0_countries

POP_EST=37589262

1

ne_110m_admin_0_countries

POP_EST>=37589262

39

ne_110m_admin_0_countries

POP_EST>37589262

38

ne_110m_admin_0_countries

POP_EST<=37589262

139

ne_110m_admin_0_countries

POP_EST<37589262

138

ne_110m_admin_0_countries

POP_EST<>37589262

176

ne_110m_populated_places_simple

name IS NOT NULL

243

ne_110m_populated_places_simple

name IS NULL

0

ne_110m_populated_places_simple

name='København'

1

ne_110m_populated_places_simple

name>='København'

137

ne_110m_populated_places_simple

name>'København'

136

ne_110m_populated_places_simple

name<='København'

107

ne_110m_populated_places_simple

name<'København'

106

ne_110m_populated_places_simple

name<>'København'

242

ne_110m_populated_places_simple

pop_other IS NOT NULL

243

ne_110m_populated_places_simple

pop_other IS NULL

0

ne_110m_populated_places_simple

pop_other=1038288

1

ne_110m_populated_places_simple

pop_other>=1038288

123

ne_110m_populated_places_simple

pop_other>1038288

122

ne_110m_populated_places_simple

pop_other<=1038288

121

ne_110m_populated_places_simple

pop_other<1038288

120

ne_110m_populated_places_simple

pop_other<>1038288

242

ne_110m_populated_places_simple

"date" IS NOT NULL

3

ne_110m_populated_places_simple

"date" IS NULL

240

ne_110m_populated_places_simple

"date"=DATE('2022-04-16')

1

ne_110m_populated_places_simple

"date">=DATE('2022-04-16')

2

ne_110m_populated_places_simple

"date">DATE('2022-04-16')

1

ne_110m_populated_places_simple

"date"<=DATE('2022-04-16')

2

ne_110m_populated_places_simple

"date"<DATE('2022-04-16')

1

ne_110m_populated_places_simple

"date"<>DATE('2022-04-16')

2

ne_110m_populated_places_simple

start IS NOT NULL

3

ne_110m_populated_places_simple

start IS NULL

240

ne_110m_populated_places_simple

start=TIMESTAMP('2022-04-16T10:13:19Z')

1

ne_110m_populated_places_simple

start<=TIMESTAMP('2022-04-16T10:13:19Z')

2

ne_110m_populated_places_simple

start<TIMESTAMP('2022-04-16T10:13:19Z')

1

ne_110m_populated_places_simple

start>=TIMESTAMP('2022-04-16T10:13:19Z')

2

ne_110m_populated_places_simple

start>TIMESTAMP('2022-04-16T10:13:19Z')

1

ne_110m_populated_places_simple

start<>TIMESTAMP('2022-04-16T10:13:19Z')

2

ne_110m_populated_places_simple

boolean IS NOT NULL

3

ne_110m_populated_places_simple

boolean IS NULL

240

ne_110m_populated_places_simple

boolean=true

2

ne_110m_populated_places_simple

boolean=false

1

+
+
+

A.3.6. Conformance Test 9

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

Test id:

+

/conf/basic-cql2/logical

+

Requirements:

Test purpose:

+

Test filter expressions with AND, OR and NOT including sub-expressions

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources.

    +
  • +
  • +

    The stored predicates for each data source.

    +
  • +
+
+
+

When:

+
+
+

Evaluate each predicate in Combinations of predicates and expected results.

+
+
+

For the data source 'ne_110m_populated_places_simple', evaluate the filter expression (NOT ({p2}) AND {p1}) OR ({p3} and {p4}) or not ({p1} OR {p4}) for each combination of predicates {p1} to {p4} in Combinations of predicates and expected results.

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the expected result is returned.

    +
  • +
+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 8. Combinations of predicates and expected results
p1p2p3p4Expected number of items

pop_other<>1038288

name<>'København'

pop_other IS NULL

name<'København'

1

pop_other<>1038288

name>'København'

name<='København'

boolean=true

107

start IS NULL

pop_other IS NOT NULL

pop_other IS NOT NULL

pop_other>1038288

124

pop_other<1038288

pop_other>1038288

pop_other IS NULL

start<TIMESTAMP('2022-04-16T10:13:19Z')

121

start=TIMESTAMP('2022-04-16T10:13:19Z')

pop_other<1038288

start=TIMESTAMP('2022-04-16T10:13:19Z')

name<>'København'

2

start<=TIMESTAMP('2022-04-16T10:13:19Z')

name<>'København'

boolean=true

name<'København'

2

pop_other=1038288

start IS NULL

start<>TIMESTAMP('2022-04-16T10:13:19Z')

boolean IS NOT NULL

242

start IS NULL

pop_other>1038288

start IS NOT NULL

name>'København'

122

pop_other<1038288

name<>'København'

name='København'

start<TIMESTAMP('2022-04-16T10:13:19Z')

2

start>=TIMESTAMP('2022-04-16T10:13:19Z')

name IS NOT NULL

start IS NULL

pop_other<1038288

120

name>='København'

start IS NOT NULL

boolean=true

start>=TIMESTAMP('2022-04-16T10:13:19Z')

137

start IS NOT NULL

name>='København'

start IS NOT NULL

name IS NOT NULL

3

name IS NULL

name<'København'

pop_other IS NOT NULL

boolean IS NOT NULL

243

start>=TIMESTAMP('2022-04-16T10:13:19Z')

name>'København'

pop_other=1038288

name<'København'

3

start<TIMESTAMP('2022-04-16T10:13:19Z')

name<='København'

boolean IS NULL

name>'København'

138

pop_other IS NOT NULL

start IS NULL

pop_other>=1038288

name>'København'

62

name='København'

start=TIMESTAMP('2022-04-16T10:13:19Z')

boolean=true

pop_other IS NULL

243

name>'København'

pop_other<1038288

pop_other>1038288

name<='København'

122

pop_other<>1038288

name='København'

name<='København'

start>TIMESTAMP('2022-04-16T10:13:19Z')

243

start<TIMESTAMP('2022-04-16T10:13:19Z')

start>=TIMESTAMP('2022-04-16T10:13:19Z')

pop_other=1038288

start IS NULL

3

name<>'København'

boolean=true

start=TIMESTAMP('2022-04-16T10:13:19Z')

start IS NULL

2

name IS NULL

start<>TIMESTAMP('2022-04-16T10:13:19Z')

start<TIMESTAMP('2022-04-16T10:13:19Z')

name IS NULL

243

start<>TIMESTAMP('2022-04-16T10:13:19Z')

name>'København'

start<=TIMESTAMP('2022-04-16T10:13:19Z')

name IS NOT NULL

3

name<>'København'

pop_other<>1038288

pop_other<1038288

start>=TIMESTAMP('2022-04-16T10:13:19Z')

2

boolean IS NULL

pop_other>1038288

boolean IS NOT NULL

pop_other IS NULL

122

pop_other=1038288

start IS NULL

start>TIMESTAMP('2022-04-16T10:13:19Z')

pop_other IS NOT NULL

2

pop_other<>1038288

start IS NULL

pop_other>1038288

boolean=true

2

start>TIMESTAMP('2022-04-16T10:13:19Z')

pop_other<1038288

name<='København'

pop_other=1038288

2

start>=TIMESTAMP('2022-04-16T10:13:19Z')

start<=TIMESTAMP('2022-04-16T10:13:19Z')

name<='København'

name<>'København'

107

boolean=true

name IS NOT NULL

boolean IS NULL

pop_other=1038288

1

start=TIMESTAMP('2022-04-16T10:13:19Z')

pop_other=1038288

pop_other<1038288

name<>'København'

122

pop_other<>1038288

start<=TIMESTAMP('2022-04-16T10:13:19Z')

start IS NOT NULL

start=TIMESTAMP('2022-04-16T10:13:19Z')

3

name<>'København'

pop_other<>1038288

pop_other IS NOT NULL

name IS NOT NULL

243

name='København'

pop_other<1038288

start IS NOT NULL

pop_other<>1038288

3

name<'København'

start<>TIMESTAMP('2022-04-16T10:13:19Z')

start>TIMESTAMP('2022-04-16T10:13:19Z')

start=TIMESTAMP('2022-04-16T10:13:19Z')

2

boolean=true

pop_other<1038288

name IS NOT NULL

start<=TIMESTAMP('2022-04-16T10:13:19Z')

3

pop_other<=1038288

name<'København'

pop_other<1038288

pop_other<1038288

243

pop_other IS NULL

name<='København'

name='København'

start>TIMESTAMP('2022-04-16T10:13:19Z')

2

pop_other<1038288

name<>'København'

pop_other<>1038288

name<>'København'

243

start<=TIMESTAMP('2022-04-16T10:13:19Z')

pop_other IS NULL

start<TIMESTAMP('2022-04-16T10:13:19Z')

name IS NOT NULL

2

start<>TIMESTAMP('2022-04-16T10:13:19Z')

name='København'

boolean IS NULL

pop_other<>1038288

241

boolean=true

pop_other<=1038288

name<>'København'

pop_other IS NULL

2

name IS NOT NULL

pop_other<=1038288

start IS NOT NULL

boolean IS NOT NULL

124

pop_other<=1038288

pop_other<1038288

start>TIMESTAMP('2022-04-16T10:13:19Z')

pop_other>1038288

1

start IS NOT NULL

boolean IS NOT NULL

name>='København'

pop_other IS NOT NULL

137

start<>TIMESTAMP('2022-04-16T10:13:19Z')

start IS NOT NULL

pop_other>1038288

pop_other<1038288

1

pop_other<=1038288

name<='København'

boolean IS NULL

start IS NOT NULL

198

name>='København'

name>='København'

name<='København'

name>='København'

107

boolean=true

start<TIMESTAMP('2022-04-16T10:13:19Z')

boolean IS NOT NULL

name<'København'

2

start>TIMESTAMP('2022-04-16T10:13:19Z')

start>=TIMESTAMP('2022-04-16T10:13:19Z')

pop_other IS NULL

pop_other<=1038288

1

pop_other<1038288

name='København'

start>=TIMESTAMP('2022-04-16T10:13:19Z')

name<'København'

181

pop_other<1038288

pop_other<=1038288

pop_other IS NULL

start IS NOT NULL

121

name>='København'

pop_other>=1038288

boolean=true

name IS NOT NULL

79

boolean IS NULL

name<>'København'

boolean IS NULL

pop_other IS NOT NULL

240

pop_other<1038288

start>=TIMESTAMP('2022-04-16T10:13:19Z')

name>'København'

pop_other<=1038288

199

name<='København'

start>TIMESTAMP('2022-04-16T10:13:19Z')

name<'København'

boolean IS NULL

106

pop_other IS NOT NULL

name<>'København'

pop_other<1038288

pop_other<=1038288

121

name>='København'

start IS NOT NULL

name>='København'

name IS NOT NULL

137

pop_other<1038288

start<TIMESTAMP('2022-04-16T10:13:19Z')

name IS NULL

pop_other>=1038288

1

pop_other>=1038288

name>'København'

boolean IS NOT NULL

start IS NOT NULL

184

start IS NOT NULL

name<>'København'

name<='København'

name IS NULL

241

name>='København'

pop_other<>1038288

start=TIMESTAMP('2022-04-16T10:13:19Z')

name<>'København'

2

boolean IS NOT NULL

pop_other<=1038288

pop_other=1038288

start=TIMESTAMP('2022-04-16T10:13:19Z')

1

name IS NOT NULL

start IS NOT NULL

start IS NOT NULL

name>='København'

241

pop_other=1038288

pop_other IS NOT NULL

start IS NOT NULL

name<>'København'

2

start=TIMESTAMP('2022-04-16T10:13:19Z')

start IS NULL

pop_other>1038288

pop_other<=1038288

1

name IS NULL

start IS NOT NULL

start=TIMESTAMP('2022-04-16T10:13:19Z')

name IS NOT NULL

1

boolean IS NOT NULL

name='København'

boolean IS NOT NULL

name IS NOT NULL

3

pop_other<>1038288

pop_other<>1038288

pop_other=1038288

pop_other<=1038288

1

pop_other IS NULL

start<>TIMESTAMP('2022-04-16T10:13:19Z')

start>TIMESTAMP('2022-04-16T10:13:19Z')

boolean IS NOT NULL

241

start<TIMESTAMP('2022-04-16T10:13:19Z')

boolean IS NULL

start>TIMESTAMP('2022-04-16T10:13:19Z')

name<'København'

2

pop_other>1038288

pop_other<>1038288

start<>TIMESTAMP('2022-04-16T10:13:19Z')

name<>'København'

2

start>=TIMESTAMP('2022-04-16T10:13:19Z')

start=TIMESTAMP('2022-04-16T10:13:19Z')

pop_other=1038288

name IS NOT NULL

2

pop_other<=1038288

start IS NOT NULL

start<=TIMESTAMP('2022-04-16T10:13:19Z')

boolean IS NOT NULL

242

boolean=true

start>TIMESTAMP('2022-04-16T10:13:19Z')

pop_other<1038288

pop_other<>1038288

122

pop_other>=1038288

pop_other>1038288

boolean IS NULL

pop_other=1038288

121

name<'København'

pop_other>1038288

start=TIMESTAMP('2022-04-16T10:13:19Z')

boolean=true

44

+
+
+
+

A.4. Conformance Class "Advanced Comparison Operators"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators

Target type

+

Servers that evaluate filter expressions

+

Parameter

+

Filter Language: "CQL2 Text" or "CQL2 JSON"

+

Requirements class

Dependency

+
+

A.4.1. Conformance Test 10

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

Test id:

+

/conf/advanced-comparison-operators/like

+

Requirements:

Test purpose:

+

Test LIKE predicate

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

For each queryable {queryable} of type String, evaluate the following filter expressions

+
+
+
    +
  • +

    {queryable} LIKE '%'

    +
  • +
  • +

    {queryable} like '_%'

    +
  • +
  • +

    {queryable} like ''

    +
  • +
  • +

    {queryable} like '%%'

    +
  • +
  • +

    {queryable} like '\\%\\_'

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets for each queryable for the pattern expression '_%' and '' have no item in common;

    +
  • +
  • +

    assert that the two result sets for each queryable for the pattern expression '%' and '%%' are identical;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.4.2. Conformance Test 11

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

Test id:

+

/conf/advanced-comparison-operators/between

+

Requirements:

Test purpose:

+

Test BETWEEN predicate

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

for each queryable {queryable} of type Number or Integer, evaluate the following filter expressions

+
+
+
    +
  • +

    {queryable} BETWEEN 0 AND 100

    +
  • +
  • +

    {queryable} between 100.0 and 1.0

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.4.3. Conformance Test 12

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

Test id:

+

/conf/advanced-comparison-operators/in

+

Requirements:

Test purpose:

+

Test IN predicate

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    for each queryable {queryable} of type Number or Integer, evaluate the following filter expression {queryable} IN (1, 2, 3);

    +
  • +
  • +

    for each queryable {queryable} of type String, evaluate the following filter expression {queryable} in ('foo', 'bar');

    +
  • +
  • +

    for each queryable {queryable} of type Boolean, evaluate the following filter expression {queryable} in (true);

    +
  • +
  • +

    for each queryable {queryable} of type Timestamp, evaluate the following filter expression {queryable} in ('2022-04-14T14:52:56Z', '2022-04-14T15:52:56Z');

    +
  • +
  • +

    for each queryable {queryable} of type Date, evaluate the following filter expression {queryable} in ('2022-04-14', '2022-04-15');

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.4.4. Conformance Test 13

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

Test id:

+

/conf/advanced-comparison-operators/test-data

+

Requirements:

+

all requirements

+

Test purpose:

+

Test predicates against the test dataset

+

Test method:

+

Given:

+
+
+
    +
  • +

    The implementation under test uses the test dataset.

    +
  • +
+
+
+

When:

+
+
+

Evaluate each predicate in Predicates and expected results.

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the expected result is returned;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 9. Predicates and expected results
Data SourcePredicateExpected number of items

ne_110m_populated_places_simple

name LIKE 'B_r%'

3

ne_110m_populated_places_simple

name NOT LIKE 'B_r%'

240

ne_110m_populated_places_simple

pop_other between 1000000 and 3000000

75

ne_110m_populated_places_simple

pop_other not between 1000000 and 3000000

168

ne_110m_populated_places_simple

name IN ('Kiev','kobenhavn','Berlin','athens','foo')

2

ne_110m_populated_places_simple

name NOT IN ('Kiev','kobenhavn','Berlin','athens','foo')

241

ne_110m_populated_places_simple

pop_other in (1038288,1611692,3013258,3013257,3013259)

3

ne_110m_populated_places_simple

pop_other not in (1038288,1611692,3013258,3013257,3013259)

240

ne_110m_populated_places_simple

"date" in (DATE('2021-04-16'),DATE('2022-04-16'),DATE('2022-04-18'))

2

ne_110m_populated_places_simple

"date" not in (DATE('2021-04-16'),DATE('2022-04-16'),DATE('2022-04-18'))

1

ne_110m_populated_places_simple

start in (TIMESTAMP('2022-04-16T10:13:19Z'))

1

ne_110m_populated_places_simple

start not in (TIMESTAMP('2022-04-16T10:13:19Z'))

2

ne_110m_populated_places_simple

boolean in (true)

2

ne_110m_populated_places_simple

boolean not in (false)

2

+
+
+

A.4.5. Conformance Test 14

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

Test id:

+

/conf/advanced-comparison-operators/logical

+

Requirements:

+

n/a

+

Test purpose:

+

Test filter expressions with AND, OR and NOT including sub-expressions

+

Test method:

+

Given:

+
+
+
    +
  • +

    The stored predicates for each data source, including from the dependencies.

    +
  • +
+
+
+

When:

+
+
+

For each data source, select at least 10 random combinations of four predicates ({p1} to {p4}) from the stored predicates and evaluate the filter expression ((NOT {p1} AND {p2}) OR ({p3} and NOT {p4}) or not ({p1} AND {p4})).

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation.

    +
  • +
+
+
+
+
+

A.5. Conformance Class "Case-insensitive Comparison"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison

Target type

+

Servers that evaluate filter expressions

+

Parameter

+

Filter Language: "CQL2 Text" or "CQL2 JSON"

+

Requirements class

Dependency

Conditional Dependency

+
+

A.5.1. Conformance Test 15

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

Test id:

+

/conf/case-insensitive-comparison/casei

+

Requirements:

Test purpose:

+

Test the CASEI function in comparisons

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

For each queryable {queryable} of type String, evaluate the following filter expressions

+
+
+
    +
  • +

    CASEI({queryable}) = casei('foo')

    +
  • +
  • +

    CASEI({queryable}) <> casei('FOO')

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets for each queryable have no item in common;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.5.2. Conformance Test 16

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

Test id:

+

/conf/case-insensitive-comparison/casei-like

+

Requirements:

Test purpose:

+

Test the CASEI function in LIKE predicates

+

Test method:

+

Given:

+
+
+ +
+
+

When:

+
+
+

For each queryable {queryable} of type String, evaluate the following filter expressions

+
+
+
    +
  • +

    CASEI({queryable}) LIKE casei('foo%')

    +
  • +
  • +

    CASEI({queryable}) LIKE casei('FOO%')

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets for each queryable are identical;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.5.3. Conformance Test 17

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

Test id:

+

/conf/case-insensitive-comparison/test-data

+

Requirements:

+

all requirements

+

Test purpose:

+

Test predicates against the test dataset

+

Test method:

+

Given:

+
+
+
    +
  • +

    The implementation under test uses the test dataset.

    +
  • +
+
+
+

When:

+
+
+

Evaluate each predicate in Predicates and expected results, if the conditional dependency is met.

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the expected result is returned;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+ + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 10. Predicates and expected results
DependencyData SourcePredicateExpected number of items

n/a

ne_110m_populated_places_simple

CASEI(name)=casei('KIEV')

1

n/a

ne_110m_populated_places_simple

CASEI(name)=casei('kiev')

1

n/a

ne_110m_populated_places_simple

CASEI(name)=casei('Kiev')

1

n/a

ne_110m_populated_places_simple

CASEI(name)=casei('København')

1

n/a

ne_110m_populated_places_simple

CASEI(name)=casei('københavn')

1

n/a

ne_110m_populated_places_simple

CASEI(name)=casei('KØBENHAVN')

1

Advanced Comparison Operators

ne_110m_populated_places_simple

CASEI(name) LIKE casei('B_r%')

3

Advanced Comparison Operators

ne_110m_populated_places_simple

CASEI(name) LIKE casei('b_r%')

3

Advanced Comparison Operators

ne_110m_populated_places_simple

CASEI(name) LIKE casei('B_R%')

3

Advanced Comparison Operators

ne_110m_populated_places_simple

CASEI(name) IN (casei('Kiev'), casei('kobenhavn'), casei('Berlin'), casei('athens'), casei('foo'))

3

+
+
+

A.5.4. Conformance Test 18

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

Test id:

+

/conf/case-insensitive-comparison/logical

+

Requirements:

+

n/a

+

Test purpose:

+

Test filter expressions with AND, OR and NOT including sub-expressions

+

Test method:

+

Given:

+
+
+
    +
  • +

    The stored predicates for each data source, including from the dependencies.

    +
  • +
+
+
+

When:

+
+
+

For each data source, select at least 10 random combinations of four predicates ({p1} to {p4}) from the stored predicates and evaluate the filter expression ((NOT {p1} AND {p2}) OR ({p3} and NOT {p4}) or not ({p1} AND {p4})).

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation.

    +
  • +
+
+
+
+
+

A.6. Conformance Class "Accent-insensitive Comparison"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison

Target type

+

Servers that evaluate filter expressions

+

Parameter

+

Filter Language: "CQL2 Text" or "CQL2 JSON"

+

Requirements class

Dependency

Conditional Dependency

Conditional Dependency

+
+

A.6.1. Conformance Test 19

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

Test id:

+

/conf/accent-insensitive-comparison/accenti

+

Requirements:

Test purpose:

+

Test the ACCENTI function in comparisons

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

For each queryable {queryable} of type String, evaluate the following filter expressions

+
+
+
    +
  • +

    ACCENTI({queryable}) = accenti('äöüéáí')

    +
  • +
  • +

    ACCENTI({queryable}) <> accenti('aoueai')

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets for each queryable have no item in common;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.6.2. Conformance Test 20

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

Test id:

+

/conf/accent-insensitive-comparison/accenti-like

+

Requirements:

Test purpose:

+

Test the ACCENTI function in LIKE predicates

+

Test method:

+

Given:

+
+
+ +
+
+

When:

+
+
+

For each queryable {queryable} of type String, evaluate the following filter expressions

+
+
+
    +
  • +

    ACCENTI({queryable}) LIKE accenti('Ä%')

    +
  • +
  • +

    ACCENTI({queryable}) LIKE accenti('A%')

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets for each queryable are identical;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.6.3. Conformance Test 21

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

Test id:

+

/conf/accent-insensitive-comparison/accenti-casei

+

Requirements:

Test purpose:

+

Test the ACCENTI function with the CASEI function

+

Test method:

+

Given:

+
+
+ +
+
+

When:

+
+
+

For each queryable {queryable} of type String, evaluate the following filter expressions

+
+
+
    +
  • +

    ACCENTI(CASEI({queryable})) = accenti(casei('ÄÉ'))

    +
  • +
  • +

    ACCENTI(CASEI({queryable})) = accenti(casei('ae'))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets for each queryable are identical;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.6.4. Conformance Test 22

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

Test id:

+

/conf/accent-insensitive-comparison/accenti-casei-like

+

Requirements:

Test purpose:

+

Test the ACCENTI function with the CASEI function in LIKE predicates

+

Test method:

+

Given:

+
+
+ +
+
+

When:

+
+
+

For each queryable {queryable} of type String, evaluate the following filter expressions

+
+
+
    +
  • +

    ACCENTI(CASEI({queryable})) LIKE accenti(casei('Ä%'))

    +
  • +
  • +

    ACCENTI(CASEI({queryable})) LIKE accenti(casei('a%'))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets for each queryable are identical;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.6.5. Conformance Test 23

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

Test id:

+

/conf/accent-insensitive-comparison/test-data

+

Requirements:

+

all requirements

+

Test purpose:

+

Test predicates against the test dataset

+

Test method:

+

Given:

+
+
+
    +
  • +

    The implementation under test uses the test dataset.

    +
  • +
+
+
+

When:

+
+
+

Evaluate each predicate in Predicates and expected results, if the conditional dependency is met.

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the expected result is returned;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+ + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 11. Predicates and expected results
DependencyData SourcePredicateExpected number of items

n/a

ne_110m_populated_places_simple

ACCENTI(name)=accenti('Chișinău')

1

n/a

ne_110m_populated_places_simple

ACCENTI(name)=accenti('Chisinau')

1

n/a

ne_110m_populated_places_simple

ACCENTI(name)=accenti('Kiev')

1

Case-insensitive Comparison

ne_110m_populated_places_simple

ACCENTI(CASEI(name))=accenti(casei('chișinău'))

1

Case-insensitive Comparison

ne_110m_populated_places_simple

ACCENTI(CASEI(name))=accenti(casei('chisinau'))

1

Case-insensitive Comparison

ne_110m_populated_places_simple

ACCENTI(CASEI(name))=accenti(casei('CHISINAU'))

1

Case-insensitive Comparison

ne_110m_populated_places_simple

ACCENTI(CASEI(name))=accenti(casei('CHIȘINĂU'))

1

Advanced Comparison Operators

ne_110m_populated_places_simple

ACCENTI(name) LIKE accenti('Ch%')

2

Case-insensitive Comparison, Advanced Comparison Operators

ne_110m_populated_places_simple

ACCENTI(CASEI(name)) LIKE accenti(casei('Chiș%'))

2

Case-insensitive Comparison, Advanced Comparison Operators

ne_110m_populated_places_simple

ACCENTI(CASEI(name)) LIKE accenti(casei('cHis%'))

2

Case-insensitive Comparison, Advanced Comparison Operators

ne_110m_populated_places_simple

ACCENTI(CASEI(name)) IN (accenti(casei('Kiev')), accenti(casei('chișinău')), accenti(casei('Berlin')), accenti(casei('athens')), accenti(casei('foo')))

4

+
+
+

A.6.6. Conformance Test 24

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

Test id:

+

/conf/accent-insensitive-comparison/logical

+

Requirements:

+

n/a

+

Test purpose:

+

Test filter expressions with AND, OR and NOT including sub-expressions

+

Test method:

+

Given:

+
+
+
    +
  • +

    The stored predicates for each data source, including from the dependencies.

    +
  • +
+
+
+

When:

+
+
+

For each data source, select at least 10 random combinations of four predicates ({p1} to {p4}) from the stored predicates and evaluate the filter expression ((NOT {p1} AND {p2}) OR ({p3} and NOT {p4}) or not ({p1} AND {p4})).

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation.

    +
  • +
+
+
+
+
+

A.7. Conformance Class "Basic Spatial Functions"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions

Target type

+

Servers that evaluate filter expressions

+

Parameter

+

Filter Language: "CQL2 Text" or "CQL2 JSON"

+

Requirements class

Dependency

+
+

The term "geometry data type" is used for the following data types: Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, Geometry, or GeometryCollection.

+
+
+

A.7.1. Conformance Test 25

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

Test id:

+

/conf/basic-spatial-functions/s_intersects

+

Requirements:

Test purpose:

+

Test the S_INTERSECTS spatial comparison function with points and bounding boxes.

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
  • +

    At least one queryable has a geometry data type.

    +
  • +
+
+
+

When:

+
+
+

For each queryable {queryable} with a geometry data type, evaluate the following filter expressions

+
+
+
    +
  • +

    S_INTERSECTS({queryable},BBOX(-180,-90,180,90))

    +
  • +
  • +

    S_INTERSECTS({queryable},POINT(7.02 49.92))

    +
  • +
  • +

    S_INTERSECTS({queryable},POINT(90 180))

    +
  • +
  • +

    S_INTERSECTS({queryable},BBOX(-180,-90,-90,90)) AND S_INTERSECTS({queryable},BBOX(90,-90,180,90))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation for the first two filter expressions;

    +
  • +
  • +

    assert unsuccessful execution of the evaluation for the third filter expressions (invalid coordinate);

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.7.2. Conformance Test 26

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

Test id:

+

/conf/basic-spatial-functions/test-data

+

Requirements:

+

all requirements

+

Test purpose:

+

Test predicates against the test dataset

+

Test method:

+

Given:

+
+
+
    +
  • +

    The implementation under test uses the test dataset.

    +
  • +
+
+
+

When:

+
+
+

Evaluate each predicate in Predicates and expected results.

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the expected result is returned;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 12. Predicates and expected results
Data SourcePredicateExpected number of items

ne_110m_admin_0_countries

S_INTERSECTS(geom,BBOX(0,40,10,50))

8

ne_110m_admin_0_countries

S_INTERSECTS(geom,BBOX(150,-90,-150,90))

10

ne_110m_admin_0_countries

S_INTERSECTS(geom,POINT(7.02 49.92))

1

ne_110m_admin_0_countries

S_INTERSECTS(geom,BBOX(0,40,10,50)) and S_INTERSECTS(geom,BBOX(5,50,10,60))

3

ne_110m_admin_0_countries

S_INTERSECTS(geom,BBOX(0,40,10,50)) and not S_INTERSECTS(geom,BBOX(5,50,10,60))

5

ne_110m_admin_0_countries

S_INTERSECTS(geom,BBOX(0,40,10,50)) or S_INTERSECTS(geom,BBOX(-90,40,-60,50))

10

ne_110m_populated_places_simple

S_INTERSECTS(geom,BBOX(0,40,10,50))

7

ne_110m_rivers_lake_centerlines

S_INTERSECTS(geom,BBOX(-180,-90,0,90))

4

+
+
+

A.7.3. Conformance Test 27

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

Test id:

+

/conf/basic-spatial-functions/logical

+

Requirements:

+

n/a

+

Test purpose:

+

Test filter expressions with AND, OR and NOT including sub-expressions

+

Test method:

+

Given:

+
+
+
    +
  • +

    The stored predicates for each data source, including from the dependencies.

    +
  • +
+
+
+

When:

+
+
+

For each data source, select at least 10 random combinations of four predicates ({p1} to {p4}) from the stored predicates and evaluate the filter expression ((NOT {p1} AND {p2}) OR ({p3} and NOT {p4}) or not ({p1} AND {p4})).

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation.

    +
  • +
+
+
+
+
+

A.8. Conformance Class "Basic Spatial Functions with additional Spatial Literals"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus

Target type

+

Servers that evaluate filter expressions

+

Parameter

+

Filter Language: "CQL2 Text" or "CQL2 JSON"

+

Requirements class

Dependency

+
+

The term "geometry data type" is used for the following data types: Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, or GeometryCollection.

+
+
+

A.8.1. Conformance Test 28

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

Test id:

+

/conf/basic-spatial-functions-plus/s_intersects

+

Requirements:

Test purpose:

+

Test the S_INTERSECTS spatial comparison function with points, multi-points, line strings, multi-line string, polygons, multi-polygons, geometry collections and bounding boxes.

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
  • +

    At least one queryable has a geometry data type.

    +
  • +
+
+
+

When:

+
+
+

For each queryable {queryable} with a geometry data type, evaluate the following filter expressions

+
+
+
    +
  • +

    S_INTERSECTS({queryable},MULTIPOINT(7.02 49.92, 90 180))

    +
  • +
  • +

    S_INTERSECTS({queryable},LINESTRING(-180 -45, 0 -45))

    +
  • +
  • +

    S_INTERSECTS({queryable},MULTILINESTRING((-180 -45, 0 -45), (0 45, 180 45)))

    +
  • +
  • +

    S_INTERSECTS({queryable},POLYGON((-180 -90, -90 -90, -90 90, -180 90, -180 -90), (-120 -50, -100 -50, -100 -40, -120 -40, -120 -50)))

    +
  • +
  • +

    S_INTERSECTS({queryable},MULTIPOLYGON(((-180 -90, -90 -90, -90 90, -180 90, -180 -90), (-120 -50, -100 -50, -100 -40, -120 -40, -120 -50)),((0 0, 10 0, 10 10, 0 10, 0 0))))

    +
  • +
  • +

    S_INTERSECTS({queryable},GEOMETRYCOLLECTION(POINT(7.02 49.92), POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation for all filter expressions except the first;

    +
  • +
  • +

    assert unsuccessful execution of the evaluation for the first filter expressions (invalid coordinate);

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.8.2. Conformance Test 29

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

Test id:

+

/conf/basic-spatial-functions-plus/test-data

+

Requirements:

+

all requirements

+

Test purpose:

+

Test predicates against the test dataset

+

Test method:

+

Given:

+
+
+
    +
  • +

    The implementation under test uses the test dataset.

    +
  • +
+
+
+

When:

+
+
+

Evaluate each predicate in Predicates and expected results.

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the expected result is returned.

    +
  • +
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 13. Predicates and expected results
Data SourcePredicateExpected number of items

ne_110m_admin_0_countries

S_INTERSECTS(geom,LINESTRING(-180 -45, 0 -45))

2

ne_110m_admin_0_countries

S_INTERSECTS(geom,MULTILINESTRING((-180 -45, 0 -45), (0 45, 180 45)))

14

ne_110m_admin_0_countries

S_INTERSECTS(geom,POLYGON((-180 -90, -90 -90, -90 90, -180 90, -180 -90), (-120 -50, -100 -50, -100 -40, -120 -40, -120 -50)))

8

ne_110m_admin_0_countries

S_INTERSECTS(geom,MULTIPOLYGON(((-180 -90, -90 -90, -90 90, -180 90, -180 -90), (-120 -50, -100 -50, -100 -40, -120 -40, -120 -50)),((0 0, 10 0, 10 10, 0 10, 0 0))))

15

ne_110m_admin_0_countries

S_INTERSECTS(geom,GEOMETRYCOLLECTION(POINT(7.02 49.92), POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))))

8

ne_110m_admin_0_countries

S_INTERSECTS(geom,POLYGON((-180 -90, -90 -90, -90 90, -180 90, -180 -90), (-120 -50, -100 -50, -100 -40, -120 -40, -120 -50))) or S_INTERSECTS(geom,POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)))

15

ne_110m_admin_0_countries

S_INTERSECTS(geom,POLYGON((-180 -90, -90 -90, -90 90, -180 90, -180 -90), (-120 -50, -100 -50, -100 -40, -120 -40, -120 -50))) and not S_INTERSECTS(geom,POLYGON((-130 0, 0 0, 0 50, -130 50, -130 0)))

3

+
+
+
+

A.9. Conformance Class "Spatial Functions"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions

Target type

+

Servers that evaluate filter expressions

+

Parameter

+

Filter Language: "CQL2 Text" or "CQL2 JSON"

+

Requirements class

Dependency

+
+

A.9.1. Conformance Test 30

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

Test id:

+

/conf/spatial-functions/s_intersects

+

Requirements:

Test purpose:

+

Test the S_INTERSECTS spatial function

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
  • +

    At least one queryable has a geometry data type.

    +
  • +
+
+
+

When:

+
+
+

For each queryable {queryable} with a geometry data type, evaluate the following filter expressions

+
+
+
    +
  • +

    S_INTERSECTS({queryable},BBOX(-180,-90,180,90))

    +
  • +
  • +

    S_INTERSECTS({queryable},POLYGON((-180 -90,180 -90,180 90,-180 90,-180 -90)))

    +
  • +
  • +

    S_INTERSECTS({queryable},LINESTRING(7 50, 10 51))

    +
  • +
  • +

    S_INTERSECTS({queryable},POINT(7.02 49.92))

    +
  • +
  • +

    S_INTERSECTS({queryable},POINT(90 180))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation for the first four filter expressions;

    +
  • +
  • +

    assert unsuccessful execution of the evaluation for the fifth filter expressions (invalid coordinate);

    +
  • +
  • +

    assert that the two result sets of the first two filter expressions for each queryable are identical;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.9.2. Conformance Test 31

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

Test id:

+

/conf/spatial-functions/s_disjoint

+

Requirements:

Test purpose:

+

Test the S_DISJOINT spatial function

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

for each queryable {queryable} with a geometry data type, evaluate the following filter expressions

+
+
+
    +
  • +

    S_DISJOINT({queryable},BBOX(-180,-90,180,90))

    +
  • +
  • +

    S_DISJOINT({queryable},POLYGON((-180 -90,180 -90,180 90,-180 90,-180 -90)))

    +
  • +
  • +

    S_DISJOINT({queryable},LINESTRING(7 50,10 51))

    +
  • +
  • +

    S_DISJOINT({queryable},POINT(7.02 49.92))

    +
  • +
  • +

    S_DISJOINT({queryable},POINT(90 180))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation for the first four filter expressions;

    +
  • +
  • +

    assert unsuccessful execution of the evaluation for the fifth filter expressions (invalid coordinate);

    +
  • +
  • +

    assert that the two result sets of the first two filter expressions for each queryable are empty;

    +
  • +
  • +

    assert that the results sets of the third and fourth filter expressions for each queryable do not have an item in common with the corresponding S_INTERSECTS expression;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.9.3. Conformance Test 32

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

Test id:

+

/conf/spatial-functions/s_equals

+

Requirements:

Test purpose:

+

Test the S_EQUALS spatial function

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

for each queryable {queryable} with a geometry data type, evaluate the following filter expressions

+
+
+
    +
  • +

    S_EQUALS({queryable},POLYGON((-180 -90,180 -90,180 90,-180 90,-180 -90)))

    +
  • +
  • +

    S_EQUALS({queryable},LINESTRING(7 50,10 51))

    +
  • +
  • +

    S_EQUALS({queryable},POINT(7.02 49.92))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets of the first two filter expressions for each queryable are identical;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.9.4. Conformance Test 33

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

Test id:

+

/conf/spatial-functions/s_touches

+

Requirements:

Test purpose:

+

Test the S_TOUCHES spatial function

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

for each queryable {queryable} with a geometry data type, evaluate the following filter expressions

+
+
+
    +
  • +

    S_TOUCHES({queryable},BBOX(-180,-90,180,90))

    +
  • +
  • +

    S_TOUCHES({queryable},POLYGON((-180 -90,180 -90,180 90,-180 90,-180 -90)))

    +
  • +
  • +

    S_TOUCHES({queryable},LINESTRING(7 50,10 51))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.9.5. Conformance Test 34

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

Test id:

+

/conf/spatial-functions/s_crosses

+

Requirements:

Test purpose:

+

Test the S_CROSSES spatial function

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

for each queryable {queryable} of type Point, MultiPoint, LineString or MultiLineString, evaluate the following filter expressions

+
+
+
    +
  • +

    S_CROSSES({queryable},BBOX(-180,-90,180,90))

    +
  • +
  • +

    S_CROSSES({queryable},POLYGON((-180 -90,180 -90,180 90,-180 90,-180 -90)))

    +
  • +
  • +

    S_CROSSES({queryable},LINESTRING(7 50,10 51))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.9.6. Conformance Test 35

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

Test id:

+

/conf/spatial-functions/s_within

+

Requirements:

Test purpose:

+

Test the S_WITHIN spatial function

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

for each queryable {queryable} with a geometry data type, evaluate the following filter expressions

+
+
+
    +
  • +

    S_WITHIN({queryable},BBOX(-180,-90,180,90))

    +
  • +
  • +

    S_WITHIN({queryable},POLYGON((-180 -90,180 -90,180 90,-180 90,-180 -90)))

    +
  • +
  • +

    S_WITHIN({queryable},LINESTRING(7 50,10 51))

    +
  • +
  • +

    S_WITHIN({queryable},MULTIPOINT(7 50,10 51))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets of the first two filter expressions for each queryable are identical;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.9.7. Conformance Test 36

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

Test id:

+

/conf/spatial-functions/s_contains

+

Requirements:

Test purpose:

+

Test the S_CONTAINS spatial function

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

for each queryable {queryable} with a geometry data type, evaluate the following filter expressions

+
+
+
    +
  • +

    S_CONTAINS({queryable},BBOX(-180,-90,180,90))

    +
  • +
  • +

    S_CONTAINS({queryable},POLYGON((-180 -90,180 -90,180 90,-180 90,-180 -90)))

    +
  • +
  • +

    S_CONTAINS({queryable},LINESTRING(7 50,10 51))

    +
  • +
  • +

    S_CONTAINS({queryable},MULTIPOINT(7 50,10 51))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets of the first two filter expressions for each queryable are identical;

    +
  • +
  • +

    assert that the results sets for each queryable do not have an item in common with the corresponding S_WITHIN expression;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.9.8. Conformance Test 37

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

Test id:

+

/conf/spatial-functions/s_overlaps

+

Requirements:

Test purpose:

+

Test the S_OVERLAPS spatial function

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    For each queryable {queryable} of type Point or MultiPoint, evaluate the filter expression S_OVERLAPS({queryable},MULTIPOINT(7 50,10 51))

    +
  • +
  • +

    For each queryable {queryable} of type LineString or MultiLineString, evaluate the filter expression S_OVERLAPS({queryable},LINESTRING(7 50,10 51))

    +
  • +
  • +

    For each queryable {queryable} of type Polygon or MultiPolygon, evaluate the filter expression S_OVERLAPS({queryable},POLYGON((-180 -90,180 -90,180 90,-180 90,-180 -90)))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.9.9. Conformance Test 38

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

Test id:

+

/conf/spatial-functions/test-data

+

Requirements:

+

all requirements

+

Test purpose:

+

Test predicates against the test dataset

+

Test method:

+

Given:

+
+
+
    +
  • +

    The implementation under test uses the test dataset.

    +
  • +
+
+
+

When:

+
+
+

Evaluate each predicate in Predicates and expected results.

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the expected result is returned;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 14. Predicates and expected results
Data SourcePredicateExpected number of items

ne_110m_admin_0_countries

S_INTERSECTS(geom,POLYGON((0 40,10 40,10 50,0 50,0 40)))

8

ne_110m_admin_0_countries

S_INTERSECTS(geom,LINESTRING(0 40,10 50))

4

ne_110m_populated_places_simple

S_INTERSECTS(geom,POLYGON((0 40,10 40,10 50,0 50,0 40)))

7

ne_110m_rivers_lake_centerlines

S_INTERSECTS(geom,LINESTRING(-60 -90,-60 90))

2

ne_110m_admin_0_countries

S_DISJOINT(geom,BBOX(0,40,10,50))

169

ne_110m_admin_0_countries

S_DISJOINT(geom,POLYGON((0 40,10 40,10 50,0 50,0 40)))

169

ne_110m_admin_0_countries

S_DISJOINT(geom,LINESTRING(0 40,10 50))

173

ne_110m_admin_0_countries

S_DISJOINT(geom,POINT(7.02 49.92))

176

ne_110m_populated_places_simple

S_DISJOINT(geom,BBOX(0,40,10,50))

236

ne_110m_populated_places_simple

S_DISJOINT(geom,POLYGON((0 40,10 40,10 50,0 50,0 40)))

236

ne_110m_rivers_lake_centerlines

S_DISJOINT(geom,BBOX(-180,-90,0,90))

9

ne_110m_rivers_lake_centerlines

S_DISJOINT(geom,LINESTRING(-60 -90,-60 90))

11

ne_110m_populated_places_simple

S_EQUALS(geom,POINT(6.1300028 49.6116604))

1

ne_110m_admin_0_countries

S_TOUCHES(geom,POLYGON((6.043073357781111 50.128051662794235,6.242751092156993 49.90222565367873,6.186320428094177 49.463802802114515,5.897759230176348 49.44266714130711,5.674051954784829 49.529483547557504,5.782417433300907 50.09032786722122,6.043073357781111 50.128051662794235)))

3

ne_110m_admin_0_countries

S_TOUCHES(geom,POINT(6.043073357781111 50.128051662794235))

3

ne_110m_admin_0_countries

S_TOUCHES(geom,POINT(6.242751092156993 49.90222565367873))

2

ne_110m_admin_0_countries

S_TOUCHES(geom,LINESTRING(6.043073357781111 50.128051662794235,6.242751092156993 49.90222565367873))

3

ne_110m_rivers_lake_centerlines

S_CROSSES(geom,BBOX(0,40,10,50))

1

ne_110m_rivers_lake_centerlines

S_CROSSES(geom,LINESTRING(-60 -90,-60 90))

2

ne_110m_admin_0_countries

S_WITHIN(geom,BBOX(-180,-90,0,90))

44

ne_110m_populated_places_simple

S_WITHIN(geom,BBOX(-180,-90,0,90))

74

ne_110m_rivers_lake_centerlines

S_WITHIN(geom,BBOX(-180,-90,0,90))

4

ne_110m_admin_0_countries

S_CONTAINS(geom,BBOX(7,50,8,51))

1

ne_110m_admin_0_countries

S_CONTAINS(geom,LINESTRING(7 50,8 51))

1

ne_110m_admin_0_countries

S_CONTAINS(geom,POINT(7.02 49.92))

1

ne_110m_admin_0_countries

S_OVERLAPS(geom,BBOX(-180,-90,0,90))

11

+
+
+

A.9.10. Conformance Test 39

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

Test id:

+

/conf/spatial-functions/logical

+

Requirements:

+

n/a

+

Test purpose:

+

Test filter expressions with AND, OR and NOT including sub-expressions

+

Test method:

+

Given:

+
+
+
    +
  • +

    The stored predicates for each data source, including from the dependencies.

    +
  • +
+
+
+

When:

+
+
+

For each data source, select at least 10 random combinations of four predicates ({p1} to {p4}) from the stored predicates and evaluate the filter expression ((NOT {p1} AND {p2}) OR ({p3} and NOT {p4}) or not ({p1} AND {p4})).

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation.

    +
  • +
+
+
+
+
+

A.10. Conformance Class "Temporal Functions"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions

Target type

+

Servers that evaluate filter expressions

+

Parameter

+

Filter Language: "CQL2 Text" or "CQL2 JSON"

+

Requirements class

Dependency

+
+

The term "temporal data type" is used for the following data types: Timestamp, Date, or Interval.

+
+
+

A.10.1. Conformance Test 40

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

Test id:

+

/conf/temporal-functions/temporal-functions-1

+

Requirements:

Test purpose:

+

Test the T_AFTER, T_BEFORE, T_DISJOINT, T_EQUALS, T_INTERSECTS temporal comparison functions.

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables with at least one queryable of type Timestamp or Date.

    +
  • +
+
+
+

When:

+
+
+

For each queryable {queryable} of data type Timestamp, evaluate the following filter expressions

+
+
+
    +
  • +

    T_AFTER({queryable},TIMESTAMP('2022-04-24T07:59:57Z'))

    +
  • +
  • +

    T_AFTER({queryable},INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_BEFORE({queryable},TIMESTAMP('2022-04-24T07:59:57Z'))

    +
  • +
  • +

    T_BEFORE({queryable},INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_DISJOINT({queryable},TIMESTAMP('2022-04-24T07:59:57Z'))

    +
  • +
  • +

    T_DISJOINT({queryable},INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_EQUALS({queryable},TIMESTAMP('2022-04-24T07:59:57Z'))

    +
  • +
  • +

    T_EQUALS({queryable},INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_INTERSECTS({queryable},TIMESTAMP('2022-04-24T07:59:57Z'))

    +
  • +
  • +

    T_INTERSECTS({queryable},INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
+
+
+

For each queryable {queryable} of data type Date, evaluate the following filter expressions

+
+
+
    +
  • +

    T_AFTER({queryable},DATE('2022-04-24'))

    +
  • +
  • +

    T_AFTER({queryable},INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_BEFORE({queryable},DATE('2022-04-24'))

    +
  • +
  • +

    T_BEFORE({queryable},INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_DISJOINT({queryable},DATE('2022-04-24'))

    +
  • +
  • +

    T_DISJOINT({queryable},INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_EQUALS({queryable},DATE('2022-04-24'))

    +
  • +
  • +

    T_EQUALS({queryable},INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_INTERSECTS({queryable},DATE('2022-04-24'))

    +
  • +
  • +

    T_INTERSECTS({queryable},INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.10.2. Conformance Test 41

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

Test id:

+

/conf/temporal-functions/temporal-functions-2

+

Requirements:

Test purpose:

+

Test the temporal comparison functions with intervals

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables with at least two queryables of type Timestamp or Date.

    +
  • +
+
+
+

When:

+
+
+

For each pair of queryables {queryable2} and {queryable2} of data type Timestamp, evaluate the following filter expressions

+
+
+
    +
  • +

    T_AFTER(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_BEFORE(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_DISJOINT(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_EQUALS(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_INTERSECTS(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_CONTAINS(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_DURING(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_FINISHEDBY(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_FINISHES(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_MEETS(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_METBY(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_OVERLAPPEDBY(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_OVERLAPS(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_STARTEDBY(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
  • +

    T_STARTS(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z'))

    +
  • +
+
+
+

For each pair of queryables {queryable2} and {queryable2} of data type Date, evaluate the following filter expressions

+
+
+
    +
  • +

    T_AFTER(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_BEFORE(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_DISJOINT(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_EQUALS(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_INTERSECTS(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_CONTAINS(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_DURING(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_FINISHEDBY(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_FINISHES(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_MEETS(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_METBY(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_OVERLAPPEDBY(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_OVERLAPS(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_STARTEDBY(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
  • +

    T_STARTS(INTERVAL({queryable1},{queryable2}),INTERVAL('2021-01-01','2021-12-31'))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.10.3. Conformance Test 42

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

Test id:

+

/conf/temporal-functions/test-data

+

Requirements:

+

all requirements

+

Test purpose:

+

Test predicates against the test dataset

+

Test method:

+

Given:

+
+
+
    +
  • +

    The implementation under test uses the test dataset.

    +
  • +
+
+
+

When:

+
+
+

Evaluate each predicate in Predicates and expected results.

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the expected result is returned;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 15. Predicates and expected results
Data SourcePredicateExpected number of items

ne_110m_populated_places_simple

t_after("date",date('2022-04-16'))

1

ne_110m_populated_places_simple

t_before("date",date('2022-04-16'))

1

ne_110m_populated_places_simple

t_disjoint("date",date('2022-04-16'))

2

ne_110m_populated_places_simple

t_equals("date",date('2022-04-16'))

1

ne_110m_populated_places_simple

t_intersects("date",date('2022-04-16'))

1

ne_110m_populated_places_simple

t_after("date",interval('2022-01-01','2022-12-31'))

1

ne_110m_populated_places_simple

t_before("date",interval('2022-01-01','2022-12-31'))

1

ne_110m_populated_places_simple

t_disjoint("date",interval('2022-01-01','2022-12-31'))

2

ne_110m_populated_places_simple

t_equals("date",interval('2022-01-01','2022-12-31'))

0

ne_110m_populated_places_simple

t_equals("date",interval('2022-04-16','2022-04-16'))

1

ne_110m_populated_places_simple

t_intersects("date",interval('2022-01-01','2022-12-31'))

1

ne_110m_populated_places_simple

t_after(start,timestamp('2022-04-16T10:13:19Z'))

1

ne_110m_populated_places_simple

t_before(start,timestamp('2022-04-16T10:13:19Z'))

1

ne_110m_populated_places_simple

t_disjoint(start,timestamp('2022-04-16T10:13:19Z'))

2

ne_110m_populated_places_simple

t_equals(start,timestamp('2022-04-16T10:13:19Z'))

1

ne_110m_populated_places_simple

t_intersects(start,timestamp('2022-04-16T10:13:19Z'))

1

ne_110m_populated_places_simple

t_after(start,interval('2022-01-01T00:00:00Z','2022-12-31T23:59:59Z'))

0

ne_110m_populated_places_simple

t_before(start,interval('2022-01-01T00:00:00Z','2022-12-31T23:59:59Z'))

1

ne_110m_populated_places_simple

t_disjoint(start,interval('2022-01-01T00:00:00Z','2022-12-31T23:59:59Z'))

1

ne_110m_populated_places_simple

t_equals(start,interval('2022-01-01T00:00:00Z','2022-12-31T23:59:59Z'))

0

ne_110m_populated_places_simple

t_intersects(start,interval('2022-01-01T00:00:00Z','2022-12-31T23:59:59Z'))

2

ne_110m_populated_places_simple

t_after(interval(start,end),interval('..','2022-04-16T10:13:19Z'))

1

ne_110m_populated_places_simple

t_before(interval(start,end),interval('2023-01-01T00:00:00Z','..'))

2

ne_110m_populated_places_simple

t_disjoint(interval(start,end),interval('2022-04-16T10:13:19Z','2022-04-16T10:15:09Z'))

1

ne_110m_populated_places_simple

t_equals(interval(start,end),interval('2021-04-16T10:15:59Z','2022-04-16T10:16:06Z'))

1

ne_110m_populated_places_simple

t_intersects(interval(start,end),interval('2022-04-16T10:13:19Z','2022-04-16T10:15:09Z'))

2

ne_110m_populated_places_simple

T_CONTAINS(interval(start,end),interval('2022-04-16T10:13:19Z','2022-04-16T10:15:10Z'))

1

ne_110m_populated_places_simple

T_DURING(interval(start,end),interval('2022-01-01T00:00:00Z','2022-12-31T23:59:59Z'))

1

ne_110m_populated_places_simple

T_FINISHES(interval(start,end),interval('2020-04-16T10:13:19Z','2022-04-16T10:16:06Z'))

1

ne_110m_populated_places_simple

T_FINISHEDBY(interval(start,end),interval('2022-04-16T10:13:19Z','2022-04-16T10:16:06Z'))

1

ne_110m_populated_places_simple

T_MEETS(interval(start,end),interval('2022-04-16T10:13:19Z','2022-04-16T10:15:10Z'))

0

ne_110m_populated_places_simple

T_METBY(interval(start,end),interval('2022-04-16T10:13:19Z','2022-04-16T10:15:10Z'))

1

ne_110m_populated_places_simple

T_OVERLAPPEDBY(interval(start,end),interval('2020-04-16T10:13:19Z','2022-04-16T10:15:10Z'))

2

ne_110m_populated_places_simple

T_OVERLAPS(interval(start,end),interval('2022-04-16T10:13:19Z','2023-04-16T10:15:10Z'))

1

ne_110m_populated_places_simple

T_STARTEDBY(interval(start,end),interval('2022-04-16T10:13:19Z','2022-04-16T10:15:10Z'))

1

ne_110m_populated_places_simple

T_STARTS(interval(start,end),interval('2022-04-16T10:13:19Z','2022-04-16T10:15:10Z'))

0

+
+
+

A.10.4. Conformance Test 43

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

Test id:

+

/conf/temporal-functions/logical

+

Requirements:

+

n/a

+

Test purpose:

+

Test filter expressions with AND, OR and NOT including sub-expressions

+

Test method:

+

Given:

+
+
+
    +
  • +

    The stored predicates for each data source, including from the dependencies.

    +
  • +
+
+
+

When:

+
+
+

For each data source, select at least 10 random combinations of four predicates ({p1} to {p4}) from the stored predicates and evaluate the filter expression ((NOT {p1} AND {p2}) OR ({p3} and NOT {p4}) or not ({p1} AND {p4})).

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation.

    +
  • +
+
+
+
+
+

A.11. Conformance Class "Array Functions"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/array-functions

Target type

+

Servers that evaluate filter expressions

+

Parameter

+

Filter Language: "CQL2 Text" or "CQL2 JSON"

+

Requirements class

Dependency

+
+

A.11.1. Conformance Test 44

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

Test id:

+

/conf/array-functions/array-predicates

+

Requirements:

Test purpose:

+

Test the array comparison functions

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
  • +

    At least one queryable has an array data type.

    +
  • +
+
+
+

When:

+
+
+

For each queryable {queryable} with an array data type, evaluate the following filter expressions

+
+
+
    +
  • +

    A_CONTAINS({queryable},("foo","bar"))

    +
  • +
  • +

    A_CONTAINEDBY({queryable},("foo","bar"))

    +
  • +
  • +

    A_EQUALS({queryable},("foo","bar"))

    +
  • +
  • +

    A_OVERLAPS({queryable},("foo","bar"))

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.11.2. Conformance Test 45

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

Test id:

+

/conf/array-functions/logical

+

Requirements:

+

n/a

+

Test purpose:

+

Test filter expressions with AND, OR and NOT including sub-expressions

+

Test method:

+

Given:

+
+
+
    +
  • +

    The stored predicates for each data source, including from the dependencies.

    +
  • +
+
+
+

When:

+
+
+

For each data source, select at least 10 random combinations of four predicates ({p1} to {p4}) from the stored predicates and evaluate the filter expression ((NOT {p1} AND {p2}) OR ({p3} and NOT {p4}) or not ({p1} AND {p4})).

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation.

    +
  • +
+
+
+
+
+

A.12. Conformance Class "Property-Property Comparisons"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/property-property

Target type

+

Servers that evaluate filter expressions

+

Parameter

+

Filter Language: "CQL2 Text" or "CQL2 JSON"

+

Requirements class

Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

Conditional Dependency

+
+

A.12.1. Conformance Test 46

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

Test id:

+

/conf/property-property/comparison-value-property

+

Requirements:

Test purpose:

+

Test comparison predicates with properties on the right-hand side and values on the left-hand side

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

For each queryable {queryable} of one of the data types String, Boolean, Number, Integer, Timestamp or Date, evaluate the following filter expressions

+
+
+
    +
  • +

    {value} = {queryable}

    +
  • +
  • +

    {value} <> {queryable}

    +
  • +
  • +

    {value} > {queryable}

    +
  • +
  • +

    {value} < {queryable}

    +
  • +
  • +

    {value} >= {queryable}

    +
  • +
  • +

    {value} <= {queryable}

    +
  • +
+
+
+

where {value} depends on the data type:

+
+
+
    +
  • +

    String: 'foo'

    +
  • +
  • +

    Boolean: true

    +
  • +
  • +

    Number: 3.14

    +
  • +
  • +

    Integer: 1

    +
  • +
  • +

    Timestamp: TIMESTAMP('2022-04-14T14:48:46Z')

    +
  • +
  • +

    Date: DATE('2022-04-14')

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the two result sets for each queryable for the operators = and <> have no item in common;

    +
  • +
  • +

    assert that the two result sets for each queryable for the operators > and <= have no item in common;

    +
  • +
  • +

    assert that the two result sets for each queryable for the operators < and >= have no item in common;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.12.2. Conformance Test 47

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

Test id:

+

/conf/property-property/comparison-property-property

+

Requirements:

Test purpose:

+

Test comparison predicates with properties on both sides

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
+
+
+

When:

+
+
+

For each queryable {queryable} of one of the data types String, Boolean, Number, Integer, Timestamp or Date, evaluate the following filter expressions

+
+
+
    +
  • +

    {queryable} = {queryable}

    +
  • +
  • +

    {queryable} <> {queryable}

    +
  • +
  • +

    {queryable} > {queryable}

    +
  • +
  • +

    {queryable} < {queryable}

    +
  • +
  • +

    {queryable} >= {queryable}

    +
  • +
  • +

    {queryable} <= {queryable}

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the result sets for each queryable for the operators <>, < and > is empty;

    +
  • +
  • +

    assert that the result sets for each queryable for the operators =, >= and <= are identical;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.12.3. Conformance Test 48

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

Test id:

+

/conf/property-property/comparison-value-value

+

Requirements:

Test purpose:

+

Test comparison predicates with values on both sides

+

Test method:

+

Given:

+
+
+
    +
  • +

    n/a

    +
  • +
+
+
+

When:

+
+
+

Evaluate the following filter expressions

+
+
+
    +
  • +

    {value} = {value}

    +
  • +
  • +

    {value} <> {value}

    +
  • +
  • +

    {value} > {value}

    +
  • +
  • +

    {value} < {value}

    +
  • +
  • +

    {value} >= {value}

    +
  • +
  • +

    {value} <= {value}

    +
  • +
+
+
+

for each {value} from the following list:

+
+
+
    +
  • +

    'foo'

    +
  • +
  • +

    true

    +
  • +
  • +

    3.14

    +
  • +
  • +

    1

    +
  • +
  • +

    TIMESTAMP('2022-04-14T14:48:46Z')

    +
  • +
  • +

    DATE('2022-04-14')

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the result sets for each queryable for the operators <>, < and > is empty;

    +
  • +
  • +

    assert that the result sets for each queryable for the operators =, >= and <= are identical;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+
+
+

A.12.4. Conformance Test 49

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

Test id:

+

/conf/property-property/test-data

+

Requirements:

+

all requirements

+

Test purpose:

+

Test predicates against the test dataset

+

Test method:

+

Given:

+
+
+
    +
  • +

    The implementation under test uses the test dataset.

    +
  • +
+
+
+

When:

+
+
+

Evaluate each predicate in Predicates and expected results, if the conditional dependency is met.

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the expected result is returned;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+ + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 16. Predicates and expected results
DependencyData SourcePredicateExpected number of items

n/a

ne_110m_populated_places_simple

'København'=name

1

n/a

ne_110m_populated_places_simple

'København'<=name

137

n/a

ne_110m_populated_places_simple

'København'<name

136

n/a

ne_110m_populated_places_simple

'København'>=name

107

n/a

ne_110m_populated_places_simple

'København'>name

106

n/a

ne_110m_populated_places_simple

'København'<>name

242

n/a

ne_110m_populated_places_simple

name=nameascii

230

n/a

ne_110m_populated_places_simple

name>=nameascii

243

n/a

ne_110m_populated_places_simple

name>nameascii

13

n/a

ne_110m_populated_places_simple

name<=nameascii

230

n/a

ne_110m_populated_places_simple

name<nameascii

0

n/a

ne_110m_populated_places_simple

name<>nameascii

13

n/a

ne_110m_populated_places_simple

1038288=pop_other

1

n/a

ne_110m_populated_places_simple

1038288<=pop_other

123

n/a

ne_110m_populated_places_simple

1038288<pop_other

122

n/a

ne_110m_populated_places_simple

1038288>=pop_other

121

n/a

ne_110m_populated_places_simple

1038288>pop_other

120

n/a

ne_110m_populated_places_simple

1038288<>pop_other

242

n/a

ne_110m_populated_places_simple

pop_min=pop_max

27

n/a

ne_110m_populated_places_simple

pop_min<=pop_max

243

n/a

ne_110m_populated_places_simple

pop_min<pop_max

216

n/a

ne_110m_populated_places_simple

pop_min>=pop_max

27

n/a

ne_110m_populated_places_simple

pop_min>pop_max

0

n/a

ne_110m_populated_places_simple

pop_min<>pop_max

216

n/a

ne_110m_populated_places_simple

start=end

0

n/a

ne_110m_populated_places_simple

start<=end

3

n/a

ne_110m_populated_places_simple

start<end

3

n/a

ne_110m_populated_places_simple

start>=end

0

n/a

ne_110m_populated_places_simple

start>end

0

n/a

ne_110m_populated_places_simple

start<>end

3

Advanced Comparison Operators

ne_110m_populated_places_simple

'København' LIKE 'K_benhavn'

243

Advanced Comparison Operators

ne_110m_populated_places_simple

'København' NOT LIKE 'K_benhavn'

0

Advanced Comparison Operators

ne_110m_populated_places_simple

pop_other between pop_min and pop_max

94

Advanced Comparison Operators

ne_110m_populated_places_simple

pop_other not between pop_min and pop_max

149

Basic Spatial Functions

ne_110m_admin_0_countries

S_INTERSECTS(BBOX(0,40,10,50),geom)

8

Basic Spatial Functions

ne_110m_admin_0_countries

S_INTERSECTS(BBOX(150,-90,-150,90),geom)

10

Basic Spatial Functions

ne_110m_admin_0_countries

S_INTERSECTS(POINT(7.02 49.92),geom)

1

Basic Spatial Functions

ne_110m_populated_places_simple

S_INTERSECTS(BBOX(0,40,10,50),geom)

7

Basic Spatial Functions

ne_110m_rivers_lake_centerlines

S_INTERSECTS(BBOX(-180,-90,0,90),geom)

4

Spatial Functions

ne_110m_admin_0_countries

S_INTERSECTS(POLYGON((0 40,10 40,10 50,0 50,0 40)),geom)

8

Spatial Functions

ne_110m_admin_0_countries

S_INTERSECTS(LINESTRING(0 40,10 50),geom)

4

Spatial Functions

ne_110m_populated_places_simple

S_INTERSECTS(POLYGON((0 40,10 40,10 50,0 50,0 40)),geom)

7

Spatial Functions

ne_110m_rivers_lake_centerlines

S_INTERSECTS(LINESTRING(-60 -90,-60 90),geom)

2

Spatial Functions

ne_110m_admin_0_countries

S_DISJOINT(BBOX(0,40,10,50),geom)

169

Spatial Functions

ne_110m_admin_0_countries

S_DISJOINT(POLYGON((0 40,10 40,10 50,0 50,0 40)),geom)

169

Spatial Functions

ne_110m_admin_0_countries

S_DISJOINT(LINESTRING(0 40,10 50),geom)

173

Spatial Functions

ne_110m_admin_0_countries

S_DISJOINT(POINT(7.02 49.92),geom)

176

Spatial Functions

ne_110m_populated_places_simple

S_DISJOINT(BBOX(0,40,10,50),geom)

236

Spatial Functions

ne_110m_populated_places_simple

S_DISJOINT(POLYGON((0 40,10 40,10 50,0 50,0 40)),geom)

236

Spatial Functions

ne_110m_rivers_lake_centerlines

S_DISJOINT(BBOX(-180,-90,0,90),geom)

9

Spatial Functions

ne_110m_rivers_lake_centerlines

S_DISJOINT(LINESTRING(-60 -90,-60 90),geom)

11

Spatial Functions

ne_110m_populated_places_simple

S_EQUALS(POINT(6.1300028 49.6116604),geom)

1

Spatial Functions

ne_110m_admin_0_countries

S_TOUCHES(POLYGON((6.043073357781111 50.128051662794235,6.242751092156993 49.90222565367873,6.186320428094177 49.463802802114515,5.897759230176348 49.44266714130711,5.674051954784829 49.529483547557504,5.782417433300907 50.09032786722122,6.043073357781111 50.128051662794235)),geom)

3

Spatial Functions

ne_110m_admin_0_countries

S_TOUCHES(POINT(6.043073357781111 50.128051662794235),geom)

3

Spatial Functions

ne_110m_admin_0_countries

S_TOUCHES(POINT(6.242751092156993 49.90222565367873),geom)

2

Spatial Functions

ne_110m_admin_0_countries

S_TOUCHES(LINESTRING(6.043073357781111 50.128051662794235,6.242751092156993 49.90222565367873),geom)

3

Spatial Functions

ne_110m_rivers_lake_centerlines

S_CROSSES(BBOX(0,40,10,50),geom)

1

Spatial Functions

ne_110m_rivers_lake_centerlines

S_CROSSES(LINESTRING(-60 -90,-60 90),geom)

2

Spatial Functions

ne_110m_admin_0_countries

S_CONTAINS(BBOX(-180,-90,0,90),geom)

44

Spatial Functions

ne_110m_populated_places_simple

S_CONTAINS(BBOX(-180,-90,0,90),geom)

74

Spatial Functions

ne_110m_rivers_lake_centerlines

S_CONTAINS(BBOX(-180,-90,0,90),geom)

4

Spatial Functions

ne_110m_admin_0_countries

S_WITHIN(BBOX(7,50,8,51),geom)

1

Spatial Functions

ne_110m_admin_0_countries

S_WITHIN(LINESTRING(7 50,8 51),geom)

1

Spatial Functions

ne_110m_admin_0_countries

S_WITHIN(POINT(7.02 49.92),geom)

1

Spatial Functions

ne_110m_admin_0_countries

S_OVERLAPS(BBOX(-180,-90,0,90),geom)

11

Temporal Functions

ne_110m_populated_places_simple

t_after(date('2022-04-16'),"date")

1

Temporal Functions

ne_110m_populated_places_simple

t_before(date('2022-04-16'),"date")

1

Temporal Functions

ne_110m_populated_places_simple

t_disjoint(date('2022-04-16'),"date")

2

Temporal Functions

ne_110m_populated_places_simple

t_equals(date('2022-04-16'),"date")

1

Temporal Functions

ne_110m_populated_places_simple

t_intersects(date('2022-04-16'),"date")

1

Temporal Functions

ne_110m_populated_places_simple

t_after(interval('2022-01-01','2022-12-31'),"date")

1

Temporal Functions

ne_110m_populated_places_simple

t_before(interval('2022-01-01','2022-12-31'),"date")

1

Temporal Functions

ne_110m_populated_places_simple

t_disjoint(interval('2022-01-01','2022-12-31'),"date")

2

Temporal Functions

ne_110m_populated_places_simple

t_equals(interval('2022-01-01','2022-12-31'),"date")

0

Temporal Functions

ne_110m_populated_places_simple

t_equals(interval('2022-04-16','2022-04-16'),"date")

1

Temporal Functions

ne_110m_populated_places_simple

t_intersects(interval('2022-01-01','2022-12-31'),"date")

1

Temporal Functions

ne_110m_populated_places_simple

t_after(timestamp('2022-04-16T10:13:19Z'),start)

1

Temporal Functions

ne_110m_populated_places_simple

t_before(timestamp('2022-04-16T10:13:19Z'),start)

1

Temporal Functions

ne_110m_populated_places_simple

t_disjoint(timestamp('2022-04-16T10:13:19Z'),start)

2

Temporal Functions

ne_110m_populated_places_simple

t_equals(timestamp('2022-04-16T10:13:19Z'),start)

1

Temporal Functions

ne_110m_populated_places_simple

t_intersects(timestamp('2022-04-16T10:13:19Z'),start)

1

Temporal Functions

ne_110m_populated_places_simple

t_after(interval('2022-01-01T00:00:00Z','2022-12-31T23:59:59Z'),start)

1

Temporal Functions

ne_110m_populated_places_simple

t_before(interval('2022-01-01T00:00:00Z','2022-12-31T23:59:59Z'),start)

0

Temporal Functions

ne_110m_populated_places_simple

t_disjoint(interval('2022-01-01T00:00:00Z','2022-12-31T23:59:59Z'),start)

1

Temporal Functions

ne_110m_populated_places_simple

t_equals(interval('2022-01-01T00:00:00Z','2022-12-31T23:59:59Z'),start)

0

Temporal Functions

ne_110m_populated_places_simple

t_intersects(interval('2022-01-01T00:00:00Z','2022-12-31T23:59:59Z'),start)

2

Temporal Functions

ne_110m_populated_places_simple

t_after(interval('2023-01-01T00:00:00Z','..'),interval(start,end))

2

Temporal Functions

ne_110m_populated_places_simple

t_before(interval('..','2022-04-16T10:13:19Z'),interval(start,end))

1

Temporal Functions

ne_110m_populated_places_simple

t_disjoint(interval('2022-04-16T10:13:19Z','2022-04-16T10:15:09Z'),interval(start,end))

1

Temporal Functions

ne_110m_populated_places_simple

t_equals(interval('2021-04-16T10:15:59Z','2022-04-16T10:16:06Z'),interval(start,end))

1

Temporal Functions

ne_110m_populated_places_simple

t_intersects(interval('2022-04-16T10:13:19Z','2022-04-16T10:15:09Z'),interval(start,end))

2

Temporal Functions

ne_110m_populated_places_simple

T_CONTAINS(interval('2021-04-16T10:13:19Z','2023-04-16T10:15:10Z'),interval(start,end))

2

Temporal Functions

ne_110m_populated_places_simple

T_DURING(interval('2022-07-01T00:00:00Z','2022-12-31T23:59:59Z'),interval(start,end))

1

Temporal Functions

ne_110m_populated_places_simple

T_FINISHES(interval('2022-04-16T10:13:19Z','2022-04-16T10:16:06Z'),interval(start,end))

1

Temporal Functions

ne_110m_populated_places_simple

T_FINISHEDBY(interval('2022-04-16T10:13:19Z','2022-04-16T10:16:06Z'),interval(start,end))

0

Temporal Functions

ne_110m_populated_places_simple

T_MEETS(interval('2022-04-16T10:13:19Z','2022-04-16T10:15:10Z'),interval(start,end))

1

Temporal Functions

ne_110m_populated_places_simple

T_METBY(interval('2022-04-16T10:13:19Z','2022-04-16T10:15:10Z'),interval(start,end))

0

Temporal Functions

ne_110m_populated_places_simple

T_OVERLAPPEDBY(interval('2020-04-16T10:13:19Z','2022-04-16T10:15:10Z'),interval(start,end))

0

Temporal Functions

ne_110m_populated_places_simple

T_OVERLAPS(interval('2022-04-16T10:13:19Z','2023-04-16T10:15:10Z'),interval(start,end))

0

Temporal Functions

ne_110m_populated_places_simple

T_STARTEDBY(interval('2022-04-16T10:13:19Z','2022-04-16T10:15:10Z'),interval(start,end))

0

Temporal Functions

ne_110m_populated_places_simple

T_STARTS(interval('2022-04-16T10:13:19Z','2022-04-16T10:15:10Z'),interval(start,end))

1

+
+
+

A.12.5. Conformance Test 50

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

Test id:

+

/conf/property-property/logical

+

Requirements:

+

n/a

+

Test purpose:

+

Test filter expressions with AND, OR and NOT including sub-expressions

+

Test method:

+

Given:

+
+
+
    +
  • +

    The stored predicates for each data source, including from the dependencies.

    +
  • +
+
+
+

When:

+
+
+

For each data source, select at least 10 random combinations of four predicates ({p1} to {p4}) from the stored predicates and evaluate the filter expression ((NOT {p1} AND {p2}) OR ({p3} and NOT {p4}) or not ({p1} AND {p4})).

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation.

    +
  • +
+
+
+
+
+

A.13. Conformance Class "Functions"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/functions

Target type

+

Servers that evaluate filter expressions

+

Parameter

+

Filter Language: "CQL2 Text" or "CQL2 JSON"

+

Requirements class

Dependency

+
+

A.13.1. Conformance Test 51

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

Test id:

+

/conf/functions/functions

+

Requirements:

Test purpose:

+

Test predicates with functions

+

Test method:

+

Given:

+
+
+
    +
  • +

    The list of functions with arguments and return type supported by the implementation under test.

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    For each function construct multiple valid filter expressions involving different operators.

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation.

    +
  • +
+
+
+
+
+

A.14. Conformance Class "Arithmetic Expressions"

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

Conformance Class

http://www.opengis.net/spec/cql2/1.0/conf/arithmetic

Target type

+

Servers that evaluate filter expressions

+

Parameter

+

Filter Language: "CQL2 Text" or "CQL2 JSON"

+

Requirements class

Dependency

Conditional Dependency

Conditional Dependency

+
+

A.14.1. Conformance Test 52

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

Test id:

+

/conf/arithmetic/arithmetic

+

Requirements:

Test purpose:

+

Test predicates with arithmetic expressions

+

Test method:

+

Given:

+
+
+
    +
  • +

    One or more data sources, each with a list of queryables.

    +
  • +
  • +

    At least one queryable has a numeric data type.

    +
  • +
+
+
+

When:

+
+
+
    +
  • +

    For each queryable construct multiple valid filter expressions involving arithmetic expressions.

    +
  • +
+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation.

    +
  • +
+
+
+
+

A.14.2. Conformance Test 53

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

Test id:

+

/conf/arithmetic/test-data

+

Requirements:

+

all requirements

+

Test purpose:

+

Test predicates against the test dataset

+

Test method:

+

Given:

+
+
+
    +
  • +

    The implementation under test uses the test dataset.

    +
  • +
+
+
+

When:

+
+
+

Evaluate each predicate in Predicates and expected results, if the conditional dependency is met.

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation;

    +
  • +
  • +

    assert that the expected result is returned;

    +
  • +
  • +

    store the valid predicates for each data source.

    +
  • +
+
+ + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 17. Predicates and expected results
DependencyData SourcePredicateExpected number of items

n/a

ne_110m_populated_places_simple

pop_other=1038280+8

1

n/a

ne_110m_populated_places_simple

pop_other>=1038290-2*2^0

123

n/a

ne_110m_populated_places_simple

pop_other>1038290-20/10

122

n/a

ne_110m_populated_places_simple

pop_other>1038290-21 div 10

122

n/a

ne_110m_populated_places_simple

pop_other>1038290-5%2

122

n/a

ne_110m_populated_places_simple

pop_other<=1038200+8*11

121

n/a

ne_110m_populated_places_simple

pop_other<1038280+2^3

120

n/a

ne_110m_populated_places_simple

pop_other<>1038290-2^1

242

Advanced Comparison Operators

ne_110m_populated_places_simple

pop_other between 4000000/4 and (3*(900000+100000))

75

Advanced Comparison Operators

ne_110m_populated_places_simple

pop_other not between 4000000/4 and (3*(900000+100000))

168

Advanced Comparison Operators

ne_110m_populated_places_simple

pop_other in (1000000+38288,1000000+600000+11692,3*1000000+13258,3*1000000+13257,30*100000+13259)

3

Advanced Comparison Operators

ne_110m_populated_places_simple

pop_other not in (1000000+38288,1000000+600000+11692,3*1000000+13258,3*1000000+13257,30*100000+13259)

240

Property-Property Comparisons

ne_110m_populated_places_simple

1038280+8=pop_other

1

+
+
+

A.14.3. Conformance Test 54

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

Test id:

+

/conf/arithmetic/logical

+

Requirements:

+

n/a

+

Test purpose:

+

Test filter expressions with AND, OR and NOT including sub-expressions

+

Test method:

+

Given:

+
+
+
    +
  • +

    The stored predicates for each data source, including from the dependencies.

    +
  • +
+
+
+

When:

+
+
+

For each data source, select at least 10 random combinations of four predicates ({p1} to {p4}) from the stored predicates and evaluate the filter expression ((NOT {p1} AND {p2}) OR ({p3} and NOT {p4}) or not ({p1} AND {p4})).

+
+
+

Then:

+
+
+
    +
  • +

    assert successful execution of the evaluation.

    +
  • +
+
+
+
+
+
+
+

Annex B: CQL2 BNF (Normative)

+
+
+ + + + + +
+
Note
+
+
+

Because there are many variations of EBNF, this standard has focused on verifying that this grammar validates using the following online validator:

+
+ +
+

If other tools are used (e.g. ANTLR), the grammar will likely need to be adapted to suit the target implementation context.

+
+
+
+
+
+
#
+# MODULE:  cql2.bnf
+# PURPOSE: A BNF grammar for the Common Query Language (CQL2).
+# HISTORY:
+# DATE         EMAIL                                  DESCRIPTION
+# 13-SEP-2019  pvretano[at]cubewerx.com               Initial creation
+# 28-OCT-2019  pvretano[at]cubewerx.com               Initial check-in into github
+# 22-DEC-2020  pvretano[at]cubewerx.com               1.0.0-draft.1 (version for public review)
+#              portele[at]interactive-instruments.de  
+# 07-MAR-2024  pvretano[at]cubewerx.com               1.0.0-rc.1 (release candidate)
+#              portele[at]interactive-instruments.de  
+# 02-JUL-2024  pvretano[at]cubewerx.com               1.0.0 (final release)
+#              portele[at]interactive-instruments.de  
+
+#=============================================================================#
+# A CQL2 filter is a logically connected expression of one or more predicates.
+# Predicates include scalar or comparison predicates, spatial predicates or
+# temporal predicates.
+#
+# *** DISCLAIMER: ***
+# Because there are many variations of EBNF, this standard has focused
+# on verifying that this grammar validates using the following online
+# validator:
+#
+# https://www.icosaedro.it/bnf_chk/bnf_chk-on-line.html
+#
+# If other tools are used (e.g. ANTLR), the grammar will likely need to be
+# adapted to suite the target implementation context.
+#=============================================================================#
+booleanExpression = booleanTerm [ {"OR" booleanTerm} ];
+
+booleanTerm = booleanFactor [ {"AND" booleanFactor} ];
+
+booleanFactor = ["NOT"] booleanPrimary;
+
+booleanPrimary = function
+               | predicate
+               | booleanLiteral
+               | "(" booleanExpression ")";
+
+predicate = comparisonPredicate
+          | spatialPredicate
+          | temporalPredicate
+          | arrayPredicate;
+
+#=============================================================================#
+# A comparison predicate evaluates if two scalar expression statisfy the
+# specified comparison operator.  The comparion operators includes an operator
+# to evaluate pattern matching expressions (LIKE), a range evaluation operator
+# and an operator to test if a scalar expression is NULL or not.
+#=============================================================================#
+comparisonPredicate = binaryComparisonPredicate
+                    | isLikePredicate
+                    | isBetweenPredicate
+                    | isInListPredicate
+                    | isNullPredicate;
+
+# Binary comparison predicate
+#
+binaryComparisonPredicate = scalarExpression
+                            comparisonOperator
+                            scalarExpression;
+
+scalarExpression = characterClause
+                 | numericLiteral
+                 | instantInstance
+                 | arithmeticExpression
+                 | booleanLiteral
+                 | propertyName
+                 | function;
+
+comparisonOperator = "="      # equal
+                   | "<" ">"  # not equal
+                   | "<"      # less than
+                   | ">"      # greater than
+                   | "<" "="  # less than or equal
+                   | ">" "="; # greater than or equal
+
+# LIKE predicate
+#
+isLikePredicate =  characterExpression ["NOT"] "LIKE" patternExpression;
+
+patternExpression = "CASEI" "(" patternExpression ")"
+                  | "ACCENTI" "(" patternExpression ")"
+                  | characterLiteral;
+
+# BETWEEN predicate
+#
+isBetweenPredicate = numericExpression ["NOT"] "BETWEEN"
+                     numericExpression "AND" numericExpression;
+
+numericExpression = arithmeticExpression
+                  | numericLiteral
+                  | propertyName
+                  | function;
+
+# IN LIST predicate
+#
+isInListPredicate = scalarExpression ["NOT"] "IN" "(" inList ")";
+
+inList = scalarExpression [ {"," scalarExpression} ];
+
+# IS NULL predicate
+#
+isNullPredicate = isNullOperand "IS" ["NOT"] "NULL";
+
+isNullOperand = characterClause
+              | numericLiteral
+              | temporalInstance
+              | spatialInstance
+              | arithmeticExpression
+              | booleanExpression
+              | propertyName
+              | function;
+
+#=============================================================================#
+# A spatial predicate evaluates if two spatial expressions satisfy the
+# condition implied by a standardized spatial comparison function.  If the
+# conditions of the spatial comparison function are met, the function returns
+# a Boolean value of true.  Otherwise the function returns false.
+#=============================================================================#
+spatialPredicate =  spatialFunction "(" geomExpression "," geomExpression ")";
+
+# NOTE: The buffer functions (DWITHIN and BEYOND) are not included because
+#       these are outside the scope of a "simple" core for CQL2.  These
+#       can be added as extensions.
+#
+spatialFunction = "S_INTERSECTS"
+                | "S_EQUALS"
+                | "S_DISJOINT"
+                | "S_TOUCHES"
+                | "S_WITHIN"
+                | "S_OVERLAPS"
+                | "S_CROSSES"
+                | "S_CONTAINS";
+
+# A geometric expression is a property name of a geometry-valued property,
+# a geometric literal (expressed as WKT) or a function that returns a
+# geometric value.
+#
+geomExpression = spatialInstance
+               | propertyName
+               | function;
+
+#=============================================================================#
+# A temporal predicate evaluates if two temporal expressions satisfy the
+# condition implied by a standardized temporal comparison function.  If the
+# conditions of the temporal comparison function are met, the function returns
+# a Boolean value of true.  Otherwise the function returns false.
+#=============================================================================#
+temporalPredicate = temporalFunction 
+                    "(" temporalExpression "," temporalExpression ")";
+
+temporalExpression = temporalInstance
+                   | propertyName
+                   | function;
+
+temporalFunction = "T_AFTER"
+                 | "T_BEFORE"
+                 | "T_CONTAINS"
+                 | "T_DISJOINT"
+                 | "T_DURING"
+                 | "T_EQUALS"
+                 | "T_FINISHEDBY"
+                 | "T_FINISHES"
+                 | "T_INTERSECTS"
+                 | "T_MEETS"
+                 | "T_METBY"
+                 | "T_OVERLAPPEDBY"
+                 | "T_OVERLAPS"
+                 | "T_STARTEDBY"
+                 | "T_STARTS";
+
+#=============================================================================#
+# An array predicate evaluates if two array expressions satisfy the
+# condition implied by a standardized array comparison function.  If the
+# conditions of the array comparison function are met, the function returns
+# a Boolean value of true.  Otherwise the function returns false.
+#=============================================================================#
+arrayPredicate = arrayFunction
+                 "(" arrayExpression "," arrayExpression ")";
+
+arrayExpression = array
+                | propertyName
+                | function;
+
+# An array is a parentheses-delimited, comma-separated list of array
+# elements.
+array = "(" ")"
+      | "(" arrayElement [ { "," arrayElement } ] ")";
+
+# An array element is either a character literal, a numeric literal,
+# a geometric literal, a temporal instance, a property name, a function,
+# an arithmetic expression or an array.
+arrayElement = characterClause
+             | numericLiteral
+             | temporalInstance
+             | spatialInstance
+             | array
+             | arithmeticExpression
+             | booleanExpression
+             | propertyName
+             | function;
+
+arrayFunction = "A_EQUALS"
+              | "A_CONTAINS"
+              | "A_CONTAINEDBY"
+              | "A_OVERLAPS";
+
+#=============================================================================#
+# An arithmetic expression is an expression composed of an arithmetic
+# operand (a property name, a number or a function that returns a number),
+# an arithmetic operators (+,-,*,/,%,div,^) and another arithmetic operand.
+#=============================================================================#
+
+arithmeticExpression = arithmeticTerm [ {arithmeticOperatorPlusMinus arithmeticTerm} ];
+
+arithmeticOperatorPlusMinus = "+" | "-";
+
+arithmeticTerm = powerTerm [ {arithmeticOperatorMultDiv powerTerm} ];
+
+arithmeticOperatorMultDiv = "*" | "/" | "%" | "div";
+
+powerTerm = arithmeticFactor [ "^" arithmeticFactor ];
+
+arithmeticFactor = "(" arithmeticExpression ")"
+                 | [ "-" ] arithmeticOperand;
+
+arithmeticOperand = numericLiteral
+                  | propertyName
+                  | function;
+
+#=============================================================================#
+# Definition of a PROPERTYNAME
+# Production copied from: https://www.w3.org/TR/REC-xml/#sec-common-syn,
+#                         "Names and Tokens".
+#=============================================================================#
+propertyName = identifier | "\"" identifier "\"";
+
+identifier = identifierStart [ { identifierPart } ];
+
+identifierPart = identifierStart
+               | "."                    # "\x002E"
+               | digit                  # 0-9
+               | "\x0300".."\x036F"     # combining and diacritical marks
+               | "\x203F".."\x2040";    # ‿ and ⁀
+
+identifierStart = "\x003A"              # colon
+                | "\x005F"              # underscore
+                | "\x0041".."\x005A"    # A-Z
+                | "\x0061".."\x007A"    # a-z
+                | "\x00C0".."\x00D6"    # À-Ö Latin-1 Supplement Letters
+                | "\x00D8".."\x00F6"    # Ø-ö Latin-1 Supplement Letters
+                | "\x00F8".."\x02FF"    # ø-ÿ Latin-1 Supplement Letters
+                | "\x0370".."\x037D"    # Ͱ-ͽ Greek and Coptic (without ";")
+                | "\x037F".."\x1FFE"    # See note 1.
+                | "\x200C".."\x200D"    # zero width non-joiner and joiner
+                | "\x2070".."\x218F"    # See note 2.
+                | "\x2C00".."\x2FEF"    # See note 3.
+                | "\x3001".."\xD7FF"    # See note 4.
+                | "\xF900".."\xFDCF"    # See note 5.
+                | "\xFDF0".."\xFFFD"    # See note 6.
+                | "\x10000".."\xEFFFF"; # See note 7.
+
+# See: https://unicode-table.com/en/blocks/
+
+# Note 1: Greek, Coptic, Cyrillic, Cyrillic Supplement, Armenian, Hebrew,
+#         Arabic, Syriac, Arabic Supplement, Thaana, NKo, Samaritan, Mandaic,
+#         Syriac Supplement, Arabic Extended-A, Devanagari, Bengali, Gurmukhi,
+#         Gujarati, Oriya, Tamil, Telugu, Kannada, Malayalam, Sinhala, Thai,
+#         Lao, Tibetan, Myanmar, Georgian, Hangul Jamo, Ethiopic, Ethiopic
+#         Supplement, Cherokee, Unified Canadian Aboriginal Syllabics, Ogham,
+#         Runic, Tagalog, Hanunoo, Buhid, Tagbanwa, Khmer, Mongolian, Unified
+#         Canadian Aboriginal Syllabics Extended, Limbu, Tai Le, New Tai Lue,
+#         Khmer Symbols, Buginese, Tai Tham, Combining Diacritical Marks
+#         Extended, Balinese, Sundanese, Batak, Lepcha, Ol Chiki, Cyrillic
+#         Extended C, Georgian Extended, Sundanese Supplement, Vedic
+#         Extensions, Phonetic Extensions, Phonetic Extensions Supplement,
+#         Combining Diacritical Marks Supplement, Latin Extended Additional,
+#         Greek Extended
+#
+# Note 2: Superscripts and Subscripts, Currency Symbols, Combining Diacritical
+#         Marks for Symbols, Letterlike Symbols, Number Forms (e.g. Roman
+#         numbers)
+#
+# Note 3: Glagolitic, Latin Extended-C, Coptic, Georgian Supplement, Tifinagh,
+#         Ethiopic Extended, Cyrillic Extended-A, Supplemental Punctuation,
+#         CJK Radicals Supplement, Kangxi Radicals
+#
+# Note 4: CJK Symbols and Punctuation Hiragana, Katakana, Bopomofo, Hangul
+#         Compatibility Jamo, Kanbun, Bopomofo Extended, CJK Strokes, Katakana
+#         Phonetic Extensions, Enclosed CJK Letters and Months, CJK
+#         Compatibility, CJK Unified Ideographs Extension A, Yijing Hexagram
+#         Symbols, CJK Unified Ideographs, Yi Syllables, Yi Radicals, Lisu,
+#         Vai, Cyrillic Extended-B, Bamum, Modifier Tone Letters, Latin
+#         Extended-D, Syloti Nagri, Common Indic Number Forms, Phags-pa,
+#         Saurashtra, Devanagari Extended, Kayah Li, Rejang, Hangul Jamo
+#         Extended-A, Javanese, Myanmar Extended-B, Cham, Myanmar Extended-A,
+#         Tai Viet, Meetei Mayek Extensions, Ethiopic Extended-A, Latin
+#         Extended-E, Cherokee Supplement, Meetei Mayek, Hangul Syllables,
+#         Hangul Jamo Extended-B
+#
+# Note 5: CJK Compatibility Ideographs, Alphabetic Presentation Forms, 
+#         Arabic Presentation Forms-A
+#
+# Note 6: Arabic Presentation Forms-A, Variation Selectors, Vertical Forms,
+#         Combining Half Marks, CJK Compatibility Forms, Small Form Variants,
+#         Arabic Presentation Forms-B, Halfwidth and Fullwidth Forms, Specials
+#
+# Note 7: Linear B Syllabary, Linear B Ideograms, Aegean Numbers, Ancient
+#         Greek Numbers, Ancient Symbols, Phaistos Disc, Lycian, Carian,
+#         Coptic Epact Numbers, Old Italic, Gothic, Old Permic, Ugaritic, Old
+#         Persian, Deseret, Shavian, Osmanya, Osage, Elbasan, Caucasian
+#         Albanian, Linear A, Cypriot Syllabary, Imperial Aramaic, Palmyrene,
+#         Nabataean, Hatran, Phoenician, Lydian, Meroitic Hieroglyphs,
+#         Meroitic Cursive, Kharoshthi, Old South Arabian, Old North Arabian,
+#         Manichaean, Avestan, Inscriptional Parthian, Inscriptional Pahlavi,
+#         Psalter Pahlavi, Old Turkic, Old Hungarian, Hanifi Rohingya, Rumi
+#         Numeral Symbols, Yezidi, Old Sogdian, Sogdian, Chorasmian, Elymaic,
+#         Brahmi, Kaithi, Sora Sompeng, Chakma, Mahajani, Sharada, Sinhala
+#         Archaic Numbers, Khojki, Multani, Khudawadi, Grantha, Newa, Tirhuta,
+#         Siddham, Modi, Mongolian Supplement, Takri, Ahom, Dogra, Warang Citi,
+#         Dives Akuru, Nandinagari, Zanabazar Square, Soyombo, Pau Cin Hau,
+#         Bhaiksuki, Marchen, Masaram Gondi, Gunjala Gondi, Makasar, Lisu
+#         Supplement, Tamil Supplement, Cuneiform, Cuneiform Numbers and
+#         Punctuation, Early Dynastic Cuneiform, Egyptian Hieroglyphs,
+#         Egyptian Hieroglyph Format Controls, Anatolian Hieroglyphs,Bamum
+#         Supplement, Mro, Bassa Vah, Pahawh Hmong, Medefaidrin, Miao,
+#         Ideographic Symbols and Punctuation, Tangut, Tangut Components,
+#         Khitan Small Script, Tangut Supplement, Kana Supplement, Kana
+#         Extended-A, Small Kana Extension, Nushu, Duployan, Shorthand Format
+#         Controls, Byzantine Musical Symbols, Musical Symbols, Ancient Greek
+#         Musical Notation, Mayan Numerals, Tai Xuan Jing Symbols, Counting
+#         Rod Numerals, Mathematical Alphanumeric Symbols, Sutton SignWriting,
+#         Glagolitic Supplement, Nyiakeng Puachue Hmong, Wancho, Mende Kikakui,
+#         Adlam, Indic Siyaq Numbers, Ottoman Siyaq Numbers, Arabic
+#         Mathematical Alphabetic Symbols, Mahjong Tiles, Domino Tiles,
+#         Playing Cards, Enclosed Alphanumeric Supplement, Enclosed Ideographic
+#         Supplement, Miscellaneous Symbols and Pictographs, Emoticons (Emoji),
+#         Ornamental Dingbats, Transport and Map Symbols, Alchemical Symbols,
+#         Geometric Shapes Extended, Supplemental Arrows-C, Supplemental
+#         Symbols and Pictographs, Chess Symbols, Symbols and Pictographs
+#         Extended-A, Symbols for Legacy Computing, CJK Unified Ideographs
+#         Extension B, CJK Unified Ideographs Extension C, CJK Unified
+#         Ideographs Extension D, CJK Unified Ideographs Extension E, CJK
+#         Unified Ideographs Extension F, CJK Compatibility Ideographs
+#         Supplement, CJK Unified Ideographs Extension G, Tags, Variation
+#         Selectors Supplement
+
+#=============================================================================#
+# Definition of a FUNCTION
+#=============================================================================#
+function = identifier "(" {argumentList} ")";
+
+argumentList = argument [ { "," argument } ];
+
+argument = characterClause
+         | numericLiteral
+         | temporalInstance
+         | spatialInstance
+         | array
+         | arithmeticExpression
+         | booleanExpression
+         | propertyName
+         | function;
+
+#=============================================================================#
+# Character expression
+#=============================================================================#
+characterExpression = characterClause
+                    | propertyName
+                    | function;
+
+characterClause = "CASEI" "(" characterExpression ")"
+                | "ACCENTI" "(" characterExpression ")"
+                | characterLiteral;
+
+#=============================================================================#
+# Definition of CHARACTER literals
+#=============================================================================#
+characterLiteral = "'" [ {character} ] "'";
+
+character = alpha | digit | whitespace | escapeQuote;
+
+escapeQuote = "''" | "\\'";
+
+# character & digit productions copied from:
+# https://www.w3.org/TR/REC-xml/#charsets
+#
+alpha = "\x0007".."\x0008"     # bell, bs
+      | "\x0021".."\x0026"     # !, ", #, $, %, &
+      | "\x0028".."\x002F"     # (, ), *, +, comma, -, ., /
+      | "\x003A".."\x0084"     # --+
+      | "\x0086".."\x009F"     #   |
+      | "\x00A1".."\x167F"     #   |
+      | "\x1681".."\x1FFF"     #   |
+      | "\x200B".."\x2027"     #   +-> :,;,<,=,>,?,@,A-Z,[,\,],^,_,`,a-z,...
+      | "\x202A".."\x202E"     #   |
+      | "\x2030".."\x205E"     #   |
+      | "\x2060".."\x2FFF"     #   |
+      | "\x3001".."\xD7FF"     # --+
+      | "\xE000".."\xFFFD"     # See note 8.
+      | "\x10000".."\x10FFFF"; # See note 9.
+
+# Note 8: Private Use, CJK Compatibility Ideographs, Alphabetic Presentation
+#         Forms, Arabic Presentation Forms-A, Combining Half Marks, CJK
+#         Compatibility Forms, Small Form Variants, Arabic Presentation Forms-B,
+#         Specials, Halfwidth and Fullwidth Forms, Specials
+# Note 9: Linear B Syllabary, Linear B Ideograms, Aegean Numbers, Ancient Greek
+#         Numbers, Ancient Symbols, Phaistos Disc, Lycian, Carian, Coptic
+#         Epact Numbers, Old Italic, Gothic, Old Permic, Ugaritic, Old Persian,
+#         Deseret, Shavian, Osmanya, Osage, Elbasan, Caucasian Albanian,
+#         Vithkuqi, Linear A, Latin Extended-F, Cypriot Syllabary, Imperial
+#         Aramaic, Palmyrene, Nabataean, Hatran, Phoenician, Lydian, Meroitic
+#         Hieroglyphs, Meroitic Cursive, Kharoshthi, Old South Arabian, Old
+#         North Arabian, Manichaean, Avestan, Inscriptional Parthian,
+#         Inscriptional Pahlavi, Psalter Pahlavi, Old Turkic, Old Hungarian,
+#         Hanifi Rohingya, Rumi Numeral Symbols, Yezidi, Arabic Extended-C,
+#         Old Sogdian, Sogdian, Old Uyghur, Chorasmian, Elymaic, Brahmi,
+#         Kaithi, Sora Sompeng, Chakma, Mahajani, Sharada, Sinhala Archaic
+#         Numbers, Khojki, Multani, Khudawadi, Grantha, Newa, Tirhuta, Siddham,
+#         Modi, Mongolian Supplement, Takri, Ahom, Dogra, Warang Citi, Dives
+#         Akuru, Nandinagari, Zanabazar Square, Soyombo, Unified Canadian
+#         Aboriginal Syllabics Extended-A, Pau Cin Hau, Devanagari Extended-A,
+#         Bhaiksuki, Marchen, Masaram Gondi, Gunjala Gondi, Makasar, Kawi,
+#         Lisu Supplement, Tamil Supplement, Cuneiform, Cuneiform Numbers and
+#         Punctuation, Early Dynastic Cuneiform, Cypro-Minoan, Egyptian
+#         Hieroglyphs, Egyptian Hieroglyph Format Controls, Anatolian
+#         Hieroglyphs, Bamum Supplement, Mro, Tangsa, Bassa Vah, Pahawh Hmong,
+#         Medefaidrin, Miao, Ideographic Symbols and Punctuation, Tangut,
+#         Tangut Components, Khitan Small Script, Tangut Supplement, Kana
+#         Extended-B, Kana Supplement, Kana Extended-A, Small Kana Extension,
+#         Nushu, Duployan, Shorthand Format Controls, Znamenny Musical Notation,
+#         Byzantine Musical Symbols, Musical Symbols, Ancient Greek Musical
+#         Notation, Kaktovik Numerals, Mayan Numerals, Tai Xuan Jing Symbols,
+#         Counting Rod Numerals, Mathematical Alphanumeric Symbols, Sutton
+#         SignWriting, Latin Extended-G, Glagolitic Supplement, Cyrillic
+#         Extended-D, Nyiakeng Puachue Hmong, Toto, Wancho, Nag Mundari,
+#         Ethiopic Extended-B, Mende Kikakui, Adlam, Indic Siyaq Numbers,
+#         Ottoman Siyaq Numbers, Arabic Mathematical Alphabetic Symbols,
+#         Mahjong Tiles, Domino Tiles, Playing Cards, Enclosed Alphanumeric
+#         Supplement, Enclosed Ideographic Supplement, Miscellaneous Symbols
+#         and Pictographs, Emoticons, Ornamental Dingbats, Transport and Map
+#         Symbols, Alchemical Symbols, Geometric Shapes Extended, Supplemental
+#         Arrows-C, Supplemental Symbols and Pictographs, Chess Symbols, Symbols
+#         and Pictographs Extended-A, Symbols for Legacy Computing, CJK Unified
+#         Ideographs Extension B, CJK Unified Ideographs Extension C, CJK
+#         Unified Ideographs Extension D, CJK Unified Ideographs Extension E,
+#         CJK Unified Ideographs Extension F, CJK Compatibility Ideographs
+#         Supplement, CJK Unified Ideographs Extension G, CJK Unified
+#         Ideographs Extension H, Tags, Variation Selectors Supplement,
+#         Supplementary Private Use Area-A, Supplementary Private Use Area-B
+
+digit = "\x0030".."\x0039";
+
+whitespace = "\x0009"  # Character tabulation
+           | "\x000A"  # Line feed
+           | "\x000B"  # Line tabulation
+           | "\x000C"  # Form feed
+           | "\x000D"  # Carriage return
+           | "\x0020"  # Space
+           | "\x0085"  # Next line
+           | "\x00A0"  # No-break space
+           | "\x1680"  # Ogham space mark
+           | "\x2000"  # En quad
+           | "\x2001"  # Em quad
+           | "\x2002"  # En space
+           | "\x2003"  # Em space
+           | "\x2004"  # Three-per-em space
+           | "\x2005"  # Four-per-em space
+           | "\x2006"  # Six-per-em space
+           | "\x2007"  # Figure space
+           | "\x2008"  # Punctuation space
+           | "\x2009"  # Thin space
+           | "\x200A"  # Hair space
+           | "\x2028"  # Line separator
+           | "\x2029"  # Paragraph separator
+           | "\x202F"  # Narrow no-break space
+           | "\x205F"  # Medium mathematical space
+           | "\x3000"; # Ideographic space
+
+#=============================================================================#
+# Definition of NUMERIC literals
+#=============================================================================#
+numericLiteral = unsignedNumericLiteral | signedNumericLiteral;
+
+unsignedNumericLiteral = decimalNumericLiteral | scientificNumericLiteral;
+
+signedNumericLiteral = [sign] unsignedNumericLiteral;
+
+decimalNumericLiteral = unsignedInteger [ "." [ unsignedInteger ] ]
+                        | "." unsignedInteger;
+
+scientificNumericLiteral = mantissa "E" exponent;
+
+mantissa = decimalNumericLiteral;
+
+exponent = signedInteger;
+
+signedInteger = [ sign ] unsignedInteger;
+
+unsignedInteger = {digit};
+
+sign = "+" | "-";
+
+#=============================================================================#
+# Boolean literal
+#=============================================================================#
+#
+booleanLiteral = "TRUE" | "FALSE";
+
+#=============================================================================#
+# Definition of GEOMETRIC literals
+#
+# NOTE: This is basically BNF that define WKT encoding. It would be nice
+#       to instead reference some normative BNF for WKT.
+#=============================================================================#
+spatialInstance = geometryLiteral       
+                | geometryCollectionTaggedText
+                | bboxTaggedText;
+
+geometryLiteral = pointTaggedText
+                | linestringTaggedText
+                | polygonTaggedText
+                | multipointTaggedText
+                | multilinestringTaggedText
+                | multipolygonTaggedText;
+
+pointTaggedText = "POINT" ["Z"] pointText;
+
+linestringTaggedText = "LINESTRING" ["Z"] lineStringText;
+
+polygonTaggedText = "POLYGON" ["Z"] polygonText;
+
+multipointTaggedText = "MULTIPOINT" ["Z"] multiPointText;
+
+multilinestringTaggedText = "MULTILINESTRING" ["Z"] multiLineStringText;
+
+multipolygonTaggedText = "MULTIPOLYGON" ["Z"] multiPolygonText;
+
+geometryCollectionTaggedText = "GEOMETRYCOLLECTION" ["Z"] geometryCollectionText;
+
+pointText = "(" point ")";
+
+point = xCoord yCoord [zCoord];
+
+xCoord = signedNumericLiteral;
+
+yCoord = signedNumericLiteral;
+
+zCoord = signedNumericLiteral;
+
+lineStringText = "(" point "," point {"," point} ")";
+
+linearRingText = emptySet | "(" point "," point "," point "," point {"," point } ")";
+
+polygonText =  "(" linearRingText {"," linearRingText} ")";
+
+multiPointText = "(" pointText {"," pointText} ")";
+
+multiLineStringText = "(" lineStringText {"," lineStringText} ")";
+
+multiPolygonText = "(" polygonText {"," polygonText} ")";
+
+geometryCollectionText = "(" geometryLiteral {"," geometryLiteral} ")";
+
+bboxTaggedText = "BBOX" bboxText;
+
+bboxText = "(" westBoundLon "," southBoundLat "," [minElev ","] eastBoundLon "," northBoundLat ["," maxElev] ")";
+
+westBoundLon = signedNumericLiteral;
+
+eastBoundLon = signedNumericLiteral;
+
+northBoundLat = signedNumericLiteral;
+
+southBoundLat = signedNumericLiteral;
+
+minElev = signedNumericLiteral;
+
+maxElev = signedNumericLiteral;
+
+temporalInstance = instantInstance | intervalInstance;
+
+instantInstance = dateInstant | timestampInstant;
+
+dateInstant = "DATE" 
+              "(" dateInstantString ")";
+
+dateInstantString = "'" fullDate "'";
+
+timestampInstant = "TIMESTAMP" 
+                   "(" timestampInstantString ")";
+
+timestampInstantString = "'" fullDate "T" utcTime "'";
+
+intervalInstance = "INTERVAL" "(" instantParameter "," instantParameter ")";
+
+instantParameter = dateInstantString
+                 | timestampInstantString
+                 | "'..'"
+                 | propertyName
+                 | function;
+
+fullDate   = dateYear "-" dateMonth "-" dateDay;
+
+dateYear   = digit digit digit digit;
+
+dateMonth  = digit digit;
+
+dateDay    = digit digit;
+
+utcTime  = timeHour ":" timeMinute ":" timeSecond "Z";
+
+timeHour   = digit digit;
+
+timeMinute = digit digit;
+
+timeSecond = digit digit ["." digit {digit}];
+
+
+
+
+
+

Annex C: JSON schemas for CQL2 (Normative)

+
+
+

C.1. JSON Schema for CQL2

+
+

The following document specifies the schema for CQL2 according to JSON Schema version '2020-12':

+
+
+
+
{
+  "$schema": "https://json-schema.org/draft/2020-12/schema",
+  "$dynamicAnchor": "cql2expression",
+  "oneOf": [
+    {"$ref": "#/$defs/andOrExpression"    },
+    {"$ref": "#/$defs/notExpression"      },
+    {"$ref": "#/$defs/comparisonPredicate"},
+    {"$ref": "#/$defs/spatialPredicate"   },
+    {"$ref": "#/$defs/temporalPredicate"  },
+    {"$ref": "#/$defs/arrayPredicate"     },
+    {"$ref": "#/$defs/functionRef"        },
+    {"type": "boolean"                    }
+  ],
+  "$defs": {
+    "andOrExpression": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op": { "type": "string", "enum": ["and", "or"] },
+        "args": {
+          "type": "array",
+          "minItems": 2,
+          "items": {"$dynamicRef": "#cql2expression"}
+        }
+      }
+    },
+    "notExpression": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op": { "type": "string", "enum": ["not"] },
+        "args": {
+          "type": "array",
+          "minItems": 1,
+          "maxItems": 1,
+          "items": {"$dynamicRef": "#cql2expression"}
+        }
+      }
+    },
+    "comparisonPredicate": {
+      "oneOf": [
+        {"$ref": "#/$defs/binaryComparisonPredicate"},
+        {"$ref": "#/$defs/isLikePredicate"          },
+        {"$ref": "#/$defs/isBetweenPredicate"       },
+        {"$ref": "#/$defs/isInListPredicate"        },
+        {"$ref": "#/$defs/isNullPredicate"          }
+      ]
+    },
+    "binaryComparisonPredicate": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op": { "type": "string", "enum": ["=", "<>", "<", ">", "<=", ">="] },
+        "args": {"$ref": "#/$defs/scalarOperands"}
+      }
+    },
+    "scalarOperands": {
+      "type": "array",
+      "minItems": 2,
+      "maxItems": 2,
+      "items": {"$ref": "#/$defs/scalarExpression"}
+    },
+    "scalarExpression": {
+      "oneOf": [
+        {"$ref": "#/$defs/characterExpression"},
+        {"$ref": "#/$defs/numericExpression"}  ,
+        {"type": "boolean"}  ,
+        {"$ref": "#/$defs/instantInstance"}    ,
+        {"$ref": "#/$defs/functionRef"},
+        {"$ref": "#/$defs/propertyRef"}
+      ]
+    },
+    "isLikePredicate": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op"  : { "type": "string", "enum": ["like"] },
+        "args": {"$ref": "#/$defs/isLikeOperands"}
+      }
+    },
+    "isLikeOperands": {
+      "type": "array",
+      "minItems": 2,
+      "maxItems": 2,
+      "prefixItems": [
+        {
+          "oneOf": [
+            {"$ref": "#/$defs/characterExpression"},
+            {"$ref": "#/$defs/propertyRef"        },
+            {"$ref": "#/$defs/functionRef"        }
+          ]
+        },
+        {"$ref": "#/$defs/patternExpression"}
+      ]
+    },
+    "patternExpression": {
+      "oneOf": [
+        {
+          "type": "object",
+          "required": ["op", "args"],
+          "properties": {
+            "op": { "type": "string", "enum": ["casei"] },
+            "args": {
+              "type": "array",
+              "items": {"$ref": "#/$defs/patternExpression"},
+              "minItems": 1,
+              "maxItems": 1
+            }
+          }
+        },
+        {
+          "type": "object",
+          "required": ["op", "args"],
+          "properties": {
+            "op": { "type": "string", "enum": ["accenti"] },
+            "args": {
+              "type": "array",
+              "items": {"$ref": "#/$defs/patternExpression"},
+              "minItems": 1,
+              "maxItems": 1
+            }
+          }
+        },
+        {"type": "string"}
+      ]
+    },
+    "isBetweenPredicate": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op"  : { "type": "string", "enum": ["between"] },
+        "args": {"$ref": "#/$defs/isBetweenOperands"}
+      }
+    },
+    "isBetweenOperands": {
+      "type": "array",
+      "minItems": 3,
+      "maxItems": 3,
+      "items": {
+        "oneOf": [
+          {"$ref": "#/$defs/numericExpression"},
+          {"$ref": "#/$defs/propertyRef"      },
+          {"$ref": "#/$defs/functionRef"      }
+        ]
+      }
+    },
+    "numericExpression": {
+      "oneOf": [ {"$ref": "#/$defs/arithmeticExpression"}, {"type": "number"} ]
+    },
+    "isInListPredicate": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op"  : { "type": "string", "enum": ["in"] },
+        "args": {"$ref": "#/$defs/inListOperands"}
+      }
+    },
+    "inListOperands": {
+      "type": "array",
+      "minItems": 2,
+      "maxItems": 2,
+      "prefixItems": [
+        {"$ref": "#/$defs/scalarExpression"}                              ,
+        { "type": "array", "items": {"$ref": "#/$defs/scalarExpression"} }
+      ]
+    },
+    "isNullPredicate": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op"  : { "type": "string", "enum": ["isNull"] },
+        "args": {"$ref": "#/$defs/isNullOperand"}
+      }
+    },
+    "isNullOperand": {
+      "type": "array",
+      "minItems": 1,
+      "maxItems": 1,
+      "items": {
+        "oneOf": [
+          {"$ref": "#/$defs/characterExpression"},
+          {"$ref": "#/$defs/numericExpression"}  ,
+          {"$dynamicRef": "#cql2expression"}     ,
+          {"$ref": "#/$defs/spatialInstance"}    ,
+          {"$ref": "#/$defs/temporalInstance"}   ,
+          {"$ref": "#/$defs/propertyRef"}
+        ]
+      }
+    },
+    "spatialPredicate": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op": {
+          "type": "string",
+          "enum": [
+            "s_contains"  , "s_crosses"   , "s_disjoint"  , "s_equals"    ,
+            "s_intersects", "s_overlaps"  , "s_touches"   , "s_within"
+          ]
+        },
+        "args": {"$ref": "#/$defs/spatialOperands"}
+      }
+    },
+    "spatialOperands": {
+      "type": "array",
+      "minItems": 2,
+      "maxItems": 2,
+      "items": {
+        "oneOf": [
+          {"$ref": "#/$defs/spatialInstance"},
+          {"$ref": "#/$defs/propertyRef"    },
+          {"$ref": "#/$defs/functionRef"    }
+        ]
+      }
+    },
+    "temporalPredicate": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op": {
+          "type": "string",
+          "enum": [
+            "t_after"       , "t_before"      , "t_contains"    ,
+            "t_disjoint"    , "t_during"      , "t_equals"      ,
+            "t_finishedBy"  , "t_finishes"    , "t_intersects"  ,
+            "t_meets"       , "t_metBy"       , "t_overlappedBy",
+            "t_overlaps"    , "t_startedBy"   , "t_starts"
+          ]
+        },
+        "args": {"$ref": "#/$defs/temporalOperands"}
+      }
+    },
+    "temporalOperands": {
+      "type": "array",
+      "minItems": 2,
+      "maxItems": 2,
+      "items": {
+        "oneOf": [
+          {"$ref": "#/$defs/temporalInstance"},
+          {"$ref": "#/$defs/propertyRef"     },
+          {"$ref": "#/$defs/functionRef"     }
+        ]
+      }
+    },
+    "arrayPredicate": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op": {
+          "type": "string",
+          "enum": ["a_containedBy", "a_contains", "a_equals", "a_overlaps"]
+        },
+        "args": {"$ref": "#/$defs/arrayExpression"}
+      }
+    },
+    "arrayExpression": {
+      "type": "array",
+      "minItems": 2,
+      "maxItems": 2,
+      "items": {
+        "oneOf": [
+          {"$ref": "#/$defs/array"      },
+          {"$ref": "#/$defs/propertyRef"},
+          {"$ref": "#/$defs/functionRef"}
+        ]
+      }
+    },
+    "array": {
+      "type": "array",
+      "items": {
+        "oneOf": [
+          {"$ref": "#/$defs/characterExpression"},
+          {"$ref": "#/$defs/numericExpression"}  ,
+          {"$dynamicRef": "#cql2expression"}     ,
+          {"$ref": "#/$defs/spatialInstance"}    ,
+          {"$ref": "#/$defs/temporalInstance"}   ,
+          {"$ref": "#/$defs/array"}              ,
+          {"$ref": "#/$defs/propertyRef"}
+        ]
+      }
+    },
+    "arithmeticExpression": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op": {
+          "type": "string",
+          "enum": ["+", "-", "*", "/", "^", "%", "div"]
+        },
+        "args": {"$ref": "#/$defs/arithmeticOperands"}
+      }
+    },
+    "arithmeticOperands": {
+      "type": "array",
+      "minItems": 2,
+      "maxItems": 2,
+      "items": {
+        "oneOf": [
+          {"$ref": "#/$defs/arithmeticExpression"                  },
+          {"$ref": "#/$defs/propertyRef"                           },
+          {"$ref": "#/$defs/functionRef"                           },
+          {                                        "type": "number"}
+        ]
+      }
+    },
+    "propertyRef": {
+      "type": "object",
+      "required": ["property"],
+      "properties": { "property": {"type": "string"} }
+    },
+    "casei": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op": { "type": "string", "enum": ["casei"] },
+        "args": {
+          "type": "array",
+          "items": {
+            "oneOf": [
+              {"$ref": "#/$defs/characterExpression"},
+              {"$ref": "#/$defs/propertyRef"        },
+              {"$ref": "#/$defs/functionRef"        }
+            ]
+          },
+          "minItems": 1,
+          "maxItems": 1
+        }
+      }
+    },
+    "accenti": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op": { "type": "string", "enum": ["accenti"] },
+        "args": {
+          "type": "array",
+          "items": {
+            "oneOf": [
+              {"$ref": "#/$defs/characterExpression"},
+              {"$ref": "#/$defs/propertyRef"        },
+              {"$ref": "#/$defs/functionRef"        }
+            ]
+          },
+          "minItems": 1,
+          "maxItems": 1
+        }
+      }
+    },
+    "characterExpression": {
+      "oneOf": [
+        {"$ref": "#/$defs/casei"                    },
+        {"$ref": "#/$defs/accenti"                  },
+        {                           "type": "string"}
+      ]
+    },
+    "functionRef": {
+      "type": "object",
+      "required": ["op", "args"],
+      "properties": {
+        "op": {
+          "type": "string",
+          "not": {
+            "enum": [
+              "and"           , "or"            , "not"           ,
+              "="             , "<>"            , "<"             ,
+              ">"             , "<="            , ">="            ,
+              "like"          , "between"       , "in"            ,
+              "isNull"        , "casei"         , "accenti"       ,
+              "s_contains"    , "s_crosses"     , "s_disjoint"    ,
+              "s_equals"      , "s_intersects"  , "s_overlaps"    ,
+              "s_touches"     , "s_within"      , "t_after"       ,
+              "t_before"      , "t_contains"    , "t_disjoint"    ,
+              "t_during"      , "t_equals"      , "t_finishedBy"  ,
+              "t_finishes"    , "t_intersects"  , "t_meets"       ,
+              "t_metBy"       , "t_overlappedBy", "t_overlaps"    ,
+              "t_startedBy"   , "t_starts"      , "a_containedBy" ,
+              "a_contains"    , "a_equals"      , "a_overlaps"    ,
+              "+"             , "-"             , "*"             ,
+              "/"             , "^"             , "%"             ,
+              "div"
+            ]
+          }
+        },
+        "args": {
+          "type": "array",
+          "items": {
+            "oneOf": [
+              {"$ref": "#/$defs/characterExpression"},
+              {"$ref": "#/$defs/numericExpression"}  ,
+              {"$dynamicRef": "#cql2expression"}     ,
+              {"$ref": "#/$defs/spatialInstance"}    ,
+              {"$ref": "#/$defs/temporalInstance"}   ,
+              {"$ref": "#/$defs/array"}              ,
+              {"$ref": "#/$defs/propertyRef"}
+            ]
+          }
+        }
+      }
+    },
+    "spatialInstance": {
+      "oneOf": [
+        {"$ref": "#/$defs/geometryLiteral"},
+        {"$ref": "#/$defs/bboxLiteral"    }
+      ]
+    },
+    "geometryLiteral": {
+      "oneOf": [
+        {"$ref": "#/$defs/point"             },
+        {"$ref": "#/$defs/linestring"        },
+        {"$ref": "#/$defs/polygon"           },
+        {"$ref": "#/$defs/multipoint"        },
+        {"$ref": "#/$defs/multilinestring"   },
+        {"$ref": "#/$defs/multipolygon"      },
+        {"$ref": "#/$defs/geometrycollection"}
+      ]
+    },
+    "point": {
+      "title": "GeoJSON Point",
+      "type": "object",
+      "required": ["type", "coordinates"],
+      "properties": {
+        "type": { "type": "string", "enum": ["Point"] },
+        "coordinates": {
+          "type": "array",
+          "minItems": 2,
+          "items": {"type": "number"}
+        },
+        "bbox": { "type": "array", "minItems": 4, "items": {"type": "number"} }
+      }
+    },
+    "linestring": {
+      "title": "GeoJSON LineString",
+      "type": "object",
+      "required": ["type", "coordinates"],
+      "properties": {
+        "type": { "type": "string", "enum": ["LineString"] },
+        "coordinates": {
+          "type": "array",
+          "minItems": 2,
+          "items": {
+            "type": "array",
+            "minItems": 2,
+            "items": {"type": "number"}
+          }
+        },
+        "bbox": { "type": "array", "minItems": 4, "items": {"type": "number"} }
+      }
+    },
+    "polygon": {
+      "title": "GeoJSON Polygon",
+      "type": "object",
+      "required": ["type", "coordinates"],
+      "properties": {
+        "type": { "type": "string", "enum": ["Polygon"] },
+        "coordinates": {
+          "type": "array",
+          "items": {
+            "type": "array",
+            "minItems": 4,
+            "items": {
+              "type": "array",
+              "minItems": 2,
+              "items": {"type": "number"}
+            }
+          }
+        },
+        "bbox": { "type": "array", "minItems": 4, "items": {"type": "number"} }
+      }
+    },
+    "multipoint": {
+      "title": "GeoJSON MultiPoint",
+      "type": "object",
+      "required": ["type", "coordinates"],
+      "properties": {
+        "type": { "type": "string", "enum": ["MultiPoint"] },
+        "coordinates": {
+          "type": "array",
+          "items": {
+            "type": "array",
+            "minItems": 2,
+            "items": {"type": "number"}
+          }
+        },
+        "bbox": { "type": "array", "minItems": 4, "items": {"type": "number"} }
+      }
+    },
+    "multilinestring": {
+      "title": "GeoJSON MultiLineString",
+      "type": "object",
+      "required": ["type", "coordinates"],
+      "properties": {
+        "type": { "type": "string", "enum": ["MultiLineString"] },
+        "coordinates": {
+          "type": "array",
+          "items": {
+            "type": "array",
+            "minItems": 2,
+            "items": {
+              "type": "array",
+              "minItems": 2,
+              "items": {"type": "number"}
+            }
+          }
+        },
+        "bbox": { "type": "array", "minItems": 4, "items": {"type": "number"} }
+      }
+    },
+    "multipolygon": {
+      "title": "GeoJSON MultiPolygon",
+      "type": "object",
+      "required": ["type", "coordinates"],
+      "properties": {
+        "type": { "type": "string", "enum": ["MultiPolygon"] },
+        "coordinates": {
+          "type": "array",
+          "items": {
+            "type": "array",
+            "items": {
+              "type": "array",
+              "minItems": 4,
+              "items": {
+                "type": "array",
+                "minItems": 2,
+                "items": {"type": "number"}
+              }
+            }
+          }
+        },
+        "bbox": { "type": "array", "minItems": 4, "items": {"type": "number"} }
+      }
+    },
+    "geometrycollection": {
+      "title": "GeoJSON GeometryCollection",
+      "type": "object",
+      "required": ["type", "geometries"],
+      "properties": {
+        "type": { "type": "string", "enum": ["GeometryCollection"] },
+        "geometries": {
+          "type": "array",
+          "minItems": 2,
+          "items": {
+            "oneOf": [
+              {"$ref": "#/$defs/point"          },
+              {"$ref": "#/$defs/linestring"     },
+              {"$ref": "#/$defs/polygon"        },
+              {"$ref": "#/$defs/multipoint"     },
+              {"$ref": "#/$defs/multilinestring"},
+              {"$ref": "#/$defs/multipolygon"   }
+            ]
+          }
+        }
+      }
+    },
+    "bboxLiteral": {
+      "type": "object",
+      "required": ["bbox"],
+      "properties": { "bbox": {"$ref": "#/$defs/bbox"} }
+    },
+    "bbox": {
+      "type": "array",
+      "oneOf": [
+        {"minItems": 4, "maxItems": 4},
+        {"minItems": 6, "maxItems": 6}
+      ],
+      "items": {"type": "number"}
+    },
+    "temporalInstance": {
+      "oneOf": [
+        {"$ref": "#/$defs/instantInstance" },
+        {"$ref": "#/$defs/intervalInstance"}
+      ]
+    },
+    "instantInstance": {
+      "oneOf": [
+        {"$ref": "#/$defs/dateInstant"     },
+        {"$ref": "#/$defs/timestampInstant"}
+      ]
+    },
+    "dateInstant": {
+      "type": "object",
+      "required": ["date"],
+      "properties": { "date": {"$ref": "#/$defs/dateString"} }
+    },
+    "timestampInstant": {
+      "type": "object",
+      "required": ["timestamp"],
+      "properties": { "timestamp": {"$ref": "#/$defs/timestampString"} }
+    },
+    "instantString": {
+      "oneOf": [
+        {"$ref": "#/$defs/dateString"     },
+        {"$ref": "#/$defs/timestampString"}
+      ]
+    },
+    "dateString": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$"},
+    "timestampString": {
+      "type"   : "string"                                                  ,
+      "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$"
+    },
+    "intervalInstance": {
+      "type": "object",
+      "required": ["interval"],
+      "properties": { "interval": {"$ref": "#/$defs/intervalArray"} }
+    },
+    "intervalArray": {
+      "type": "array",
+      "minItems": 2,
+      "maxItems": 2,
+      "items": {
+        "oneOf": [
+          {"$ref": "#/$defs/instantString"}   ,
+          { "type": "string", "enum": [".."] },
+          {"$ref": "#/$defs/propertyRef"}     ,
+          {"$ref": "#/$defs/functionRef"}
+        ]
+      }
+    }
+  }
+}
+
+
+
+
+

C.2. OpenAPI 3.0 schema for CQL2

+
+

The following document specifies the schema for CQL2 as an OpenAPI 3.0 schema in YAML:

+
+
+
+
---
+openapi: 3.0.3
+info:
+  title: Schema of Common Query Language (CQL2)
+  description: 'For use in OpenAPI 3.0 documents.'
+  version: '1.0.0-SNAPSHOT'
+paths: {}
+components:
+  schemas:
+    booleanExpression:
+      oneOf:
+        - $ref: '#/components/schemas/andOrExpression'
+        - $ref: '#/components/schemas/notExpression'
+        - $ref: '#/components/schemas/comparisonPredicate'
+        - $ref: '#/components/schemas/spatialPredicate'
+        - $ref: '#/components/schemas/temporalPredicate'
+        - $ref: '#/components/schemas/arrayPredicate'
+        - $ref: '#/components/schemas/functionRef'
+        - type: boolean
+    andOrExpression:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - and
+            - or
+        args:
+          type: array
+          minItems: 2
+          items:
+            $ref: '#/components/schemas/booleanExpression'
+    notExpression:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - not
+        args:
+          type: array
+          minItems: 1
+          maxItems: 1
+          items:
+            $ref: '#/components/schemas/booleanExpression'
+    comparisonPredicate:
+      oneOf:
+        - $ref: '#/components/schemas/binaryComparisonPredicate'
+        - $ref: '#/components/schemas/isLikePredicate'
+        - $ref: '#/components/schemas/isBetweenPredicate'
+        - $ref: '#/components/schemas/isInListPredicate'
+        - $ref: '#/components/schemas/isNullPredicate'
+    binaryComparisonPredicate:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - '='
+            - <>
+            - <
+            - '>'
+            - <=
+            - '>='
+        args:
+          $ref: '#/components/schemas/scalarOperands'
+    scalarOperands:
+      type: array
+      minItems: 2
+      maxItems: 2
+      items:
+        $ref: '#/components/schemas/scalarExpression'
+    scalarExpression:
+      oneOf:
+        - $ref: '#/components/schemas/characterExpression'
+        - $ref: '#/components/schemas/numericExpression'
+        - type: 'boolean'
+        - $ref: '#/components/schemas/instantInstance'
+        - $ref: '#/components/schemas/functionRef'
+        - $ref: '#/components/schemas/propertyRef'
+    isLikePredicate:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - like
+        args:
+          $ref: '#/components/schemas/isLikeOperands'
+    isLikeOperands:
+      type: array
+      minItems: 2
+      maxItems: 2
+      items:
+        oneOf:
+          - oneOf:
+              - $ref: '#/components/schemas/characterExpression'
+              - $ref: '#/components/schemas/propertyRef'
+              - $ref: '#/components/schemas/functionRef'
+          - $ref: '#/components/schemas/patternExpression'
+    patternExpression:
+      oneOf:
+        - type: object
+          required:
+            - op
+            - args
+          properties:
+            op:
+              type: string
+              enum:
+                - casei
+            args:
+              type: array
+              items:
+                $ref: '#/components/schemas/patternExpression'
+              minItems: 1
+              maxItems: 1
+        - type: object
+          required:
+            - op
+            - args
+          properties:
+            op:
+              type: string
+              enum:
+                - accenti
+            args:
+              type: array
+              items:
+                $ref: '#/components/schemas/patternExpression'
+              minItems: 1
+              maxItems: 1
+        - type: string
+    isBetweenPredicate:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - between
+        args:
+          $ref: '#/components/schemas/isBetweenOperands'
+    isBetweenOperands:
+      type: array
+      minItems: 3
+      maxItems: 3
+      items:
+        oneOf:
+          - $ref: '#/components/schemas/numericExpression'
+          - $ref: '#/components/schemas/propertyRef'
+          - $ref: '#/components/schemas/functionRef'
+    numericExpression:
+      oneOf:
+        - $ref: '#/components/schemas/arithmeticExpression'
+        - type: number
+    isInListPredicate:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - in
+        args:
+          $ref: '#/components/schemas/inListOperands'
+    inListOperands:
+      type: array
+      minItems: 2
+      maxItems: 2
+      items:
+        oneOf:
+          - $ref: '#/components/schemas/scalarExpression'
+          - type: array
+            items:
+              $ref: '#/components/schemas/scalarExpression'
+    isNullPredicate:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - isNull
+        args:
+          $ref: '#/components/schemas/isNullOperand'
+    isNullOperand:
+      type: array
+      minItems: 1
+      maxItems: 1
+      items:
+        oneOf:
+          - $ref: '#/components/schemas/characterExpression'
+          - $ref: '#/components/schemas/numericExpression'
+          - $ref: '#/components/schemas/booleanExpression'
+          - $ref: '#/components/schemas/spatialInstance'
+          - $ref: '#/components/schemas/temporalInstance'
+          - $ref: '#/components/schemas/propertyRef'
+    spatialPredicate:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - s_contains
+            - s_crosses
+            - s_disjoint
+            - s_equals
+            - s_intersects
+            - s_overlaps
+            - s_touches
+            - s_within
+        args:
+          $ref: '#/components/schemas/spatialOperands'
+    spatialOperands:
+      type: array
+      minItems: 2
+      maxItems: 2
+      items:
+        oneOf:
+          - $ref: '#/components/schemas/spatialInstance'
+          - $ref: '#/components/schemas/propertyRef'
+          - $ref: '#/components/schemas/functionRef'
+    temporalPredicate:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - t_after
+            - t_before
+            - t_contains
+            - t_disjoint
+            - t_during
+            - t_equals
+            - t_finishedBy
+            - t_finishes
+            - t_intersects
+            - t_meets
+            - t_metBy
+            - t_overlappedBy
+            - t_overlaps
+            - t_startedBy
+            - t_starts
+        args:
+          $ref: '#/components/schemas/temporalOperands'
+    temporalOperands:
+      type: array
+      minItems: 2
+      maxItems: 2
+      items:
+        oneOf:
+          - $ref: '#/components/schemas/temporalInstance'
+          - $ref: '#/components/schemas/propertyRef'
+          - $ref: '#/components/schemas/functionRef'
+    arrayPredicate:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - a_containedBy
+            - a_contains
+            - a_equals
+            - a_overlaps
+        args:
+          $ref: '#/components/schemas/arrayExpression'
+    arrayExpression:
+      type: array
+      minItems: 2
+      maxItems: 2
+      items:
+        oneOf:
+          - $ref: '#/components/schemas/array'
+          - $ref: '#/components/schemas/propertyRef'
+          - $ref: '#/components/schemas/functionRef'
+    array:
+      type: array
+      items:
+        oneOf:
+          - $ref: '#/components/schemas/characterExpression'
+          - $ref: '#/components/schemas/numericExpression'
+          - $ref: '#/components/schemas/booleanExpression'
+          - $ref: '#/components/schemas/spatialInstance'
+          - $ref: '#/components/schemas/temporalInstance'
+          - $ref: '#/components/schemas/array'
+          - $ref: '#/components/schemas/propertyRef'
+    arithmeticExpression:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - +
+            - '-'
+            - '*'
+            - /
+            - ^
+            - '%'
+            - div
+        args:
+          $ref: '#/components/schemas/arithmeticOperands'
+    arithmeticOperands:
+      type: array
+      minItems: 2
+      maxItems: 2
+      items:
+        oneOf:
+          - $ref: '#/components/schemas/arithmeticExpression'
+          - $ref: '#/components/schemas/propertyRef'
+          - $ref: '#/components/schemas/functionRef'
+          - type: number
+    propertyRef:
+      type: object
+      required:
+        - property
+      properties:
+        property:
+          type: string
+    casei:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - casei
+        args:
+          type: array
+          items:
+            oneOf:
+              - $ref: '#/components/schemas/characterExpression'
+              - $ref: '#/components/schemas/propertyRef'
+              - $ref: '#/components/schemas/functionRef'
+          minItems: 1
+          maxItems: 1
+    accenti:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          enum:
+            - accenti
+        args:
+          type: array
+          items:
+            oneOf:
+              - $ref: '#/components/schemas/characterExpression'
+              - $ref: '#/components/schemas/propertyRef'
+              - $ref: '#/components/schemas/functionRef'
+          minItems: 1
+          maxItems: 1
+    characterExpression:
+      oneOf:
+        - $ref: '#/components/schemas/casei'
+        - $ref: '#/components/schemas/accenti'
+        - type: string
+    functionRef:
+      type: object
+      required:
+        - op
+        - args
+      properties:
+        op:
+          type: string
+          not:
+            enum:
+              - and
+              - or
+              - not
+              - '='
+              - <>
+              - <
+              - '>'
+              - <=
+              - '>='
+              - like
+              - between
+              - in
+              - isNull
+              - casei
+              - accenti
+              - s_contains
+              - s_crosses
+              - s_disjoint
+              - s_equals
+              - s_intersects
+              - s_overlaps
+              - s_touches
+              - s_within
+              - t_after
+              - t_before
+              - t_contains
+              - t_disjoint
+              - t_during
+              - t_equals
+              - t_finishedBy
+              - t_finishes
+              - t_intersects
+              - t_meets
+              - t_metBy
+              - t_overlappedBy
+              - t_overlaps
+              - t_startedBy
+              - t_starts
+              - a_containedBy
+              - a_contains
+              - a_equals
+              - a_overlaps
+              - +
+              - '-'
+              - '*'
+              - /
+              - ^
+              - '%'
+              - div
+        args:
+          type: array
+          items:
+            oneOf:
+              - $ref: '#/components/schemas/characterExpression'
+              - $ref: '#/components/schemas/numericExpression'
+              - $ref: '#/components/schemas/booleanExpression'
+              - $ref: '#/components/schemas/spatialInstance'
+              - $ref: '#/components/schemas/temporalInstance'
+              - $ref: '#/components/schemas/array'
+              - $ref: '#/components/schemas/propertyRef'
+    spatialInstance:
+      oneOf:
+        - $ref: '#/components/schemas/geometryLiteral'
+        - $ref: '#/components/schemas/bboxLiteral'
+    geometryLiteral:
+      oneOf:
+        - $ref: '#/components/schemas/point'
+        - $ref: '#/components/schemas/linestring'
+        - $ref: '#/components/schemas/polygon'
+        - $ref: '#/components/schemas/multipoint'
+        - $ref: '#/components/schemas/multilinestring'
+        - $ref: '#/components/schemas/multipolygon'
+        - $ref: '#/components/schemas/geometrycollection'
+    point:
+      title: GeoJSON Point
+      type: object
+      required:
+        - type
+        - coordinates
+      properties:
+        type:
+          type: string
+          enum:
+            - Point
+        coordinates:
+          type: array
+          minItems: 2
+          items:
+            type: number
+        bbox:
+          type: array
+          minItems: 4
+          items:
+            type: number
+    linestring:
+      title: GeoJSON LineString
+      type: object
+      required:
+        - type
+        - coordinates
+      properties:
+        type:
+          type: string
+          enum:
+            - LineString
+        coordinates:
+          type: array
+          minItems: 2
+          items:
+            type: array
+            minItems: 2
+            items:
+              type: number
+        bbox:
+          type: array
+          minItems: 4
+          items:
+            type: number
+    polygon:
+      title: GeoJSON Polygon
+      type: object
+      required:
+        - type
+        - coordinates
+      properties:
+        type:
+          type: string
+          enum:
+            - Polygon
+        coordinates:
+          type: array
+          items:
+            type: array
+            minItems: 4
+            items:
+              type: array
+              minItems: 2
+              items:
+                type: number
+        bbox:
+          type: array
+          minItems: 4
+          items:
+            type: number
+    multipoint:
+      title: GeoJSON MultiPoint
+      type: object
+      required:
+        - type
+        - coordinates
+      properties:
+        type:
+          type: string
+          enum:
+            - MultiPoint
+        coordinates:
+          type: array
+          items:
+            type: array
+            minItems: 2
+            items:
+              type: number
+        bbox:
+          type: array
+          minItems: 4
+          items:
+            type: number
+    multilinestring:
+      title: GeoJSON MultiLineString
+      type: object
+      required:
+        - type
+        - coordinates
+      properties:
+        type:
+          type: string
+          enum:
+            - MultiLineString
+        coordinates:
+          type: array
+          items:
+            type: array
+            minItems: 2
+            items:
+              type: array
+              minItems: 2
+              items:
+                type: number
+        bbox:
+          type: array
+          minItems: 4
+          items:
+            type: number
+    multipolygon:
+      title: GeoJSON MultiPolygon
+      type: object
+      required:
+        - type
+        - coordinates
+      properties:
+        type:
+          type: string
+          enum:
+            - MultiPolygon
+        coordinates:
+          type: array
+          items:
+            type: array
+            items:
+              type: array
+              minItems: 4
+              items:
+                type: array
+                minItems: 2
+                items:
+                  type: number
+        bbox:
+          type: array
+          minItems: 4
+          items:
+            type: number
+    geometrycollection:
+      title: GeoJSON GeometryCollection
+      type: object
+      required:
+        - type
+        - geometries
+      properties:
+        type:
+          type: string
+          enum:
+            - GeometryCollection
+        geometries:
+          type: array
+          minItems: 2
+          items:
+            oneOf:
+              - $ref: '#/components/schemas/point'
+              - $ref: '#/components/schemas/linestring'
+              - $ref: '#/components/schemas/polygon'
+              - $ref: '#/components/schemas/multipoint'
+              - $ref: '#/components/schemas/multilinestring'
+              - $ref: '#/components/schemas/multipolygon'
+    bboxLiteral:
+      type: object
+      required:
+        - bbox
+      properties:
+        bbox:
+          $ref: '#/components/schemas/bbox'
+    bbox:
+      type: array
+      oneOf:
+        - minItems: 4
+          maxItems: 4
+        - minItems: 6
+          maxItems: 6
+      items:
+        type: number
+    temporalInstance:
+      oneOf:
+        - $ref: '#/components/schemas/instantInstance'
+        - $ref: '#/components/schemas/intervalInstance'
+    instantInstance:
+      oneOf:
+        - $ref: '#/components/schemas/dateInstant'
+        - $ref: '#/components/schemas/timestampInstant'
+    dateInstant:
+      type: object
+      required:
+        - date
+      properties:
+        date:
+          $ref: '#/components/schemas/dateString'
+    timestampInstant:
+      type: object
+      required:
+        - timestamp
+      properties:
+        timestamp:
+          $ref: '#/components/schemas/timestampString'
+    instantString:
+      oneOf:
+        - $ref: '#/components/schemas/dateString'
+        - $ref: '#/components/schemas/timestampString'
+    dateString:
+      type: string
+      pattern: ^\d{4}-\d{2}-\d{2}$
+    timestampString:
+      type: string
+      pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$
+    intervalInstance:
+      type: object
+      required:
+        - interval
+      properties:
+        interval:
+          $ref: '#/components/schemas/intervalArray'
+    intervalArray:
+      type: array
+      minItems: 2
+      maxItems: 2
+      items:
+        oneOf:
+          - $ref: '#/components/schemas/instantString'
+          - type: string
+            enum:
+              - ..
+          - $ref: '#/components/schemas/propertyRef'
+          - $ref: '#/components/schemas/functionRef'
+
+
+
+
+
+
+
+

Annex D: Revision History

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

2021-09-27

1.0.0-SNAPSHOT

C. Portele

all

+

split from OGC API - Features - Part 3: Filtering

+

2024-03-07

1.0.0-rc.1

C. Portele, P. Vretanos

all

+

release candidate, submission for the OGC approval process

+

2024-03-26

1.0.0-rc.2

C. Portele, P. Vretanos

all

+

release candidate

+
+
+
    +
  • +

    #902 CQL2 JSON: fix schema and some examples;

    +
  • +
  • +

    #904 CQL2 Text: update spatialLiteral rule;

    +
  • +
  • +

    #915 simplify scalarExpression;

    +
  • +
  • +

    #907 update title of the basic-spatial-functions-plus requirements class.

    +
  • +
+

2024-06-29

1.0.0

C. Portele, P. Vretanos, G. Hobona

all

+

prepare for publication

+
+
+
+
+
+

Annex E: Bibliography

+
+
+
    +
  • +

    Internet Engineering Task Force (IETF). RFC 5234: Augmented BNF for Syntax Specifications: ABNF [online]. Edited by D. Crocker, P. Overell. 2008. Available at https://www.rfc-editor.org/rfc/rfc5234.html

    +
  • +
  • +

    Internet Engineering Task Force (IETF). draft-bhutton-json-schema-validation-01: JSON Schema Validation: A Vocabulary for Structural Validation of JSON [online]. Edited by A. Wright, H. Andrews, B. Hutton. 2020. Available at https://json-schema.org/draft/2020-12/json-schema-validation

    +
  • +
  • +

    ISO 8601-1:2019, Date and time — Representations for information interchange — Part 1: Basic rules

    +
  • +
  • +

    ISO 8601-2:2019, Date and time — Representations for information interchange — Part 2: Extensions

    +
  • +
  • +

    ISO 15836-2:2019, Information and documentation — The Dublin Core metadata element set — Part 2: DCMI Properties and classes

    +
  • +
  • +

    Open Geospatial Consortium (OGC). OGC API - Features - Part 3: Filtering [online]. Edited by P. Vretanos, C. Portele. Available at https://docs.ogc.org/is/19-079r2/19-079r2.html

    +
  • +
  • +

    PostGIS. Dimensionally Extended 9-Intersection Model [online]. Available at https://postgis.net/workshops/postgis-intro/de9im.html.

    +
  • +
  • +

    Wikipedia. DE-9IM [online]. Available at https://en.wikipedia.org/wiki/DE-9IM.

    +
  • +
+
+
+
+
+ + + + +
\ No newline at end of file From 3f72f08897998f5d136912f9f361363a872b929c Mon Sep 17 00:00:00 2001 From: ghobona Date: Mon, 5 Aug 2024 10:16:18 +0100 Subject: [PATCH 2/4] Update 21-065r2.csv --- specification-elements/mappings/21-065r2.csv | 406 +++++++++---------- 1 file changed, 192 insertions(+), 214 deletions(-) diff --git a/specification-elements/mappings/21-065r2.csv b/specification-elements/mappings/21-065r2.csv index f9ff1a90..c12f47bd 100644 --- a/specification-elements/mappings/21-065r2.csv +++ b/specification-elements/mappings/21-065r2.csv @@ -1,214 +1,192 @@ -https://docs.ogc.org/is/21-065r2/21-065r2.html,http://www.opengis.net/doc/IS/cql2/1.0 -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2 -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/array-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/property-property -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/cql2-text -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_class_uris,http://www.opengis.net/spec/cql2/1.0/conf/cql2-json -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_basic-cql2,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2 -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-cql2_cql2-filter,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter -https://docs.ogc.org/is/21-065r2/21-065r2.html#per_basic-cql2_cql2-filter,http://www.opengis.net/spec/cql2/1.0/per/basic-cql2/cql2-filter -https://docs.ogc.org/is/21-065r2/21-065r2.html#_escaping_in_string_literals,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/escaping -https://docs.ogc.org/is/21-065r2/21-065r2.html#per_basic-cql2_type-casts,http://www.opengis.net/spec/cql2/1.0/per/basic-cql2/type-casts -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-cql2_property,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/property -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-cql2_binary-comparison-predicate,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/binary-comparison-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#rec_core_string-normalization,http://www.opengis.net/spec/cql2/1.0/rec/core/string-normalization -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-cql2_null-predicate,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/null-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_advanced-comparison-operators,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_advanced-comparison-operators_like-predicate,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/like-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#per_advanced-comparison-operators_like-predicate,http://www.opengis.net/spec/cql2/1.0/per/advanced-comparison-operators/like-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_advanced-comparison-operators_between-predicate,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/between-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#per_advanced-comparison-operators_between-predicate,http://www.opengis.net/spec/cql2/1.0/per/advanced-comparison-operators/between-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_advanced-comparison-operators_in-predicate,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/in-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#per_advanced-comparison-operators_in-predicate,http://www.opengis.net/spec/cql2/1.0/per/advanced-comparison-operators/in-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_case-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/req/case-insensitive-comparison -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_case-insensitive-comparison_casei-function,http://www.opengis.net/spec/cql2/1.0/req/case-insensitive-comparison/casei-function -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_accent-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_accent-insensitive-comparison_accenti-function,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function -https://docs.ogc.org/is/21-065r2/21-065r2.html#rec_accent-insensitive-comparison_japanese-non-spacing-marks,http://www.opengis.net/spec/cql2/1.0/rec/accent-insensitive-comparison/japanese-non-spacing-marks -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_basic-spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-spatial-functions_spatial-predicate,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-operators/spatial-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-spatial-functions_spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#per_basic-spatial-functions_spatial-predicates,http://www.opengis.net/spec/cql2/1.0/per/basic-spatial-functions/spatial-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#per_basic-spatial-functions_spatial-data-types,http://www.opengis.net/spec/cql2/1.0/per/basic-spatial-functions/spatial-data-types -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_basic-spatial-functions-plus,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-spatial-functions-plus_spatial-data-types,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus/spatial-data-types -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_spatial-functions_spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_temporal-functions,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_temporal-functions_temporal-predicates,http://www.opengis.net/spec/cql2/1.0/req/temporal-operators/temporal-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_temporal-functions_temporal-functions,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#per_temporal-functions_temporal-operands,http://www.opengis.net/spec/cql2/1.0/per/temporal-functions/temporal-operands -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_array-functions,http://www.opengis.net/spec/cql2/1.0/req/array-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_array-functions_array-predicates,http://www.opengis.net/spec/cql2/1.0/req/array-functions/array-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#per_array-predicates,http://www.opengis.net/spec/cql2/1.0/per/array-functions/array-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_property-property,http://www.opengis.net/spec/cql2/1.0/req/property-property -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_property-property_withdraw-permissions,http://www.opengis.net/spec/cql2/1.0/req/property-property/withdraw-permissions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_property-property_withdraw-permissions,http://www.opengis.net/spec/cql2/1.0/per/basic-cql2/cql2filter -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_property-property_withdraw-permissions,http://www.opengis.net/spec/cql2/1.0/per/advanced-comparison-operators/like-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_property-property_withdraw-permissions,http://www.opengis.net/spec/cql2/1.0/per/advanced-comparison-operators/between-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_property-property_withdraw-permissions,http://www.opengis.net/spec/cql2/1.0/per/advanced-comparison-operators/in-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_property-property_withdraw-permissions,http://www.opengis.net/spec/cql2/1.0/per/basic-spatial-functions/spatial-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_property-property_withdraw-permissions,http://www.opengis.net/spec/cql2/1.0/per/temporal-functions/temporal-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_property-property_withdraw-permissions,http://www.opengis.net/spec/cql2/1.0/per/array-functions/array-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_functions,http://www.opengis.net/spec/cql2/1.0/req/functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_functions,http://www.opengis.net/spec/cql2/1.0/req/functions/functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_arithmetic,http://www.opengis.net/spec/cql2/1.0/req/arithmetic -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_arithmetic,http://www.opengis.net/spec/cql2/1.0/req/arithmetic/arithmetic -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_cql2-text,http://www.opengis.net/spec/cql2/1.0/req/cql2-text -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_basic-cql2,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/basic-cql2 -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_escaping,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/escaping -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_advanced-comparison-operators,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/advanced-comparison-operators -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_case-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/case-insensitive-comparison -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_accent-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/accent-insensitive-comparison -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_basic-spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/basic-spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_basic-spatial-functions-plus,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/basic-spatial-functions-plus -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_temporal-functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/temporal-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_arrays,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/arrays -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_property-property,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/property-property -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_arithmetic,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/arithmetic -https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_cql2-json,http://www.opengis.net/spec/cql2/1.0/req/cql2-json -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_basic-cql2,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/basic-cql2 -https://docs.ogc.org/is/21-065r2/21-065r2.html#per_cql2-json_basic-cql2,http://www.opengis.net/spec/cql2/1.0/per/cql2-json/basic-cql2 -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_advanced-comparison-operators,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/advanced-comparison-operators -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_case-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/case-insensitive-comparison -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_accent-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/accent-insensitive-comparison -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_basic-spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/basic-spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_basic-spatial-functions-plus,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/basic-spatial-functions-plus -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_temporal-functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/temporal-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_arrays,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/arrays -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_property-property,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/property-property -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_arithmetic,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/arithmetic -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_cql2-text,http://www.opengis.net/spec/cql2/1.0/conf/cql2-text -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_1,http://www.opengis.net/spec/cql2/1.0/conf/cql2-text/validate -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_2,http://www.opengis.net/spec/cql2/1.0/conf/cql2-text/escaping -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_2,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/escaping -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_cql2-json,http://www.opengis.net/spec/cql2/1.0/conf/cql2-json -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_3,http://www.opengis.net/spec/cql2/1.0/conf/cql2-json/validate -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_basic-cql2,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2 -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_4,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/basic-test -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/comparison -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/property -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/binary-comparison-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/basic-test' -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/is-null -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/property -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/null-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/basic-test' -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_7,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/boolean -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_7,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_7,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/basic-test' -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_8,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/test-data -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_9,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/logical -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_9,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_advanced-comparison-operators,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_10,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/like -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_10,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/like-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_11,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/between -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_11,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/between-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_12,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/in -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_12,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/in-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_13,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/test-data -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_14,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/logical -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_case-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_15,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison/casei -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_15,http://www.opengis.net/spec/cql2/1.0/req/case-insensitive-comparison/casei-function -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_16,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison/casei-like -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_16,http://www.opengis.net/spec/cql2/1.0/req/case-insensitive-comparison/casei-function -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_17,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison/test-data -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_18,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison/logical -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_accent-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_19,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/accenti -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_19,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_20,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/accenti-like -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_20,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_21,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/accenti-casei -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_21,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_22,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/accenti-casei-like -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_22,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_23,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/test-data -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_24,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/logical -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_basic-spatial-functions,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_25,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions/s_intersects -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_25,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions/spatial-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_25,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_25,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions/spatial-data-types -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_26,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions/test-data -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_27,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions/logical -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_basic-spatial-functions-plus,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_28,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus/s_intersects -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_28,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus/spatial-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_28,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_28,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus/spatial-data-types -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_29,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus/test-data -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_spatial-functions,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_30,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_intersects -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_30,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_30,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_31,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_disjoint -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_31,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_31,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_32,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_equals -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_32,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_32,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_33,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_touches -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_33,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_33,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_34,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_crosses -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_34,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_34,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_35,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_within -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_35,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_35,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_36,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_contains -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_36,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_36,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_37,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_overlaps -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_37,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_37,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_38,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/test-data -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_39,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/logical -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_temporal-functions,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_40,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions/temporal-functions-1 -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_40,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_40,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_41,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions/temporal-functions-2 -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_41,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_41,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_42,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions/test-data -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_43,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions/logical -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_array-functions,http://www.opengis.net/spec/cql2/1.0/conf/array-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_44,http://www.opengis.net/spec/cql2/1.0/conf/array-functions/array-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_44,http://www.opengis.net/spec/cql2/1.0/req/array-functions/array-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_45,http://www.opengis.net/spec/cql2/1.0/conf/array-functions/logical -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_property-property,http://www.opengis.net/spec/cql2/1.0/conf/property-property -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_46,http://www.opengis.net/spec/cql2/1.0/conf/property-property/comparison-value-property -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_46,http://www.opengis.net/spec/cql2/1.0/req/property-property/withdraw-permissions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_47,http://www.opengis.net/spec/cql2/1.0/conf/property-property/comparison-property-property -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_47,http://www.opengis.net/spec/cql2/1.0/req/property-property/withdraw-permissions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_48,http://www.opengis.net/spec/cql2/1.0/conf/property-property/comparison-value-value -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_48,http://www.opengis.net/spec/cql2/1.0/req/property-property/withdraw-permissions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_49,http://www.opengis.net/spec/cql2/1.0/conf/property-property/test-data -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_50,http://www.opengis.net/spec/cql2/1.0/conf/property-property/logical -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_functions,http://www.opengis.net/spec/cql2/1.0/conf/functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_51,http://www.opengis.net/spec/cql2/1.0/conf/functions/functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_51,http://www.opengis.net/spec/cql2/1.0/req/functions/functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_arithmetic,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_52,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic/arithmetic -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_52,http://www.opengis.net/spec/cql2/1.0/req/arithmetic/arithmetic -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_53,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic/test-data -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_54,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic/logical +https://docs.ogc.org/is/21-065r2/21-065r2.html,http://www.opengis.net/doc/IS/cql2/1.0 +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_basic-cql2,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2 +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-cql2_cql2-filter,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter +https://docs.ogc.org/is/21-065r2/21-065r2.html#per_basic-cql2_cql2-filter,http://www.opengis.net/spec/cql2/1.0/per/basic-cql2/cql2-filter +https://docs.ogc.org/is/21-065r2/21-065r2.html#per_basic-cql2_type-casts,http://www.opengis.net/spec/cql2/1.0/per/basic-cql2/type-casts +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-cql2_property,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/property +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-cql2_binary-comparison-predicate,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/binary-comparison-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#rec_core_string-normalization,http://www.opengis.net/spec/cql2/1.0/rec/core/string-normalization +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-cql2_null-predicate,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/null-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_advanced-comparison-operators,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_advanced-comparison-operators_like-predicate,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/like-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#per_advanced-comparison-operators_like-predicate,http://www.opengis.net/spec/cql2/1.0/per/advanced-comparison-operators/like-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_advanced-comparison-operators_between-predicate,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/between-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#per_advanced-comparison-operators_between-predicate,http://www.opengis.net/spec/cql2/1.0/per/advanced-comparison-operators/between-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_advanced-comparison-operators_in-predicate,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/in-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#per_advanced-comparison-operators_in-predicate,http://www.opengis.net/spec/cql2/1.0/per/advanced-comparison-operators/in-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_case-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/req/case-insensitive-comparison +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_case-insensitive-comparison_casei-function,http://www.opengis.net/spec/cql2/1.0/req/case-insensitive-comparison/casei-function +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_accent-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_accent-insensitive-comparison_accenti-function,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function +https://docs.ogc.org/is/21-065r2/21-065r2.html#rec_accent-insensitive-comparison_japanese-non-spacing-marks,http://www.opengis.net/spec/cql2/1.0/rec/accent-insensitive-comparison/japanese-non-spacing-marks +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_basic-spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-spatial-functions_spatial-predicate,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-operators/spatial-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-spatial-functions_spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#per_basic-spatial-functions_spatial-predicates,http://www.opengis.net/spec/cql2/1.0/per/basic-spatial-functions/spatial-predicates +https://docs.ogc.org/is/21-065r2/21-065r2.html#per_basic-spatial-functions_spatial-data-types,http://www.opengis.net/spec/cql2/1.0/per/basic-spatial-functions/spatial-data-types +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_basic-spatial-functions-plus,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_basic-spatial-functions-plus_spatial-data-types,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus/spatial-data-types +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_spatial-functions_spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_temporal-functions,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_temporal-functions_temporal-predicates,http://www.opengis.net/spec/cql2/1.0/req/temporal-operators/temporal-predicates +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_temporal-functions_temporal-functions,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#per_temporal-functions_temporal-operands,http://www.opengis.net/spec/cql2/1.0/per/temporal-functions/temporal-operands +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_array-functions,http://www.opengis.net/spec/cql2/1.0/req/array-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_array-functions_array-predicates,http://www.opengis.net/spec/cql2/1.0/req/array-functions/array-predicates +https://docs.ogc.org/is/21-065r2/21-065r2.html#per_array-predicates,http://www.opengis.net/spec/cql2/1.0/per/array-functions/array-predicates +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_property-property,http://www.opengis.net/spec/cql2/1.0/req/property-property +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_property-property_withdraw-permissions,http://www.opengis.net/spec/cql2/1.0/req/property-property/withdraw-permissions +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_functions,http://www.opengis.net/spec/cql2/1.0/req/functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_functions,http://www.opengis.net/spec/cql2/1.0/req/functions/functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_arithmetic,http://www.opengis.net/spec/cql2/1.0/req/arithmetic +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_arithmetic,http://www.opengis.net/spec/cql2/1.0/req/arithmetic/arithmetic +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_cql2-text,http://www.opengis.net/spec/cql2/1.0/req/cql2-text +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_basic-cql2,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/basic-cql2 +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_escaping,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/escaping +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_advanced-comparison-operators,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/advanced-comparison-operators +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_case-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/case-insensitive-comparison +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_accent-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/accent-insensitive-comparison +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_basic-spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/basic-spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_basic-spatial-functions-plus,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/basic-spatial-functions-plus +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_temporal-functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/temporal-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_arrays,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/arrays +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_property-property,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/property-property +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-text_arithmetic,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/arithmetic +https://docs.ogc.org/is/21-065r2/21-065r2.html#rc_cql2-json,http://www.opengis.net/spec/cql2/1.0/req/cql2-json +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_basic-cql2,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/basic-cql2 +https://docs.ogc.org/is/21-065r2/21-065r2.html#per_cql2-json_basic-cql2,http://www.opengis.net/spec/cql2/1.0/per/cql2-json/basic-cql2 +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_advanced-comparison-operators,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/advanced-comparison-operators +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_case-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/case-insensitive-comparison +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_accent-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/accent-insensitive-comparison +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_basic-spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/basic-spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_basic-spatial-functions-plus,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/basic-spatial-functions-plus +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_spatial-functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_temporal-functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/temporal-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_arrays,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/arrays +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_property-property,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/property-property +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_functions,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_arithmetic,http://www.opengis.net/spec/cql2/1.0/req/cql2-json/arithmetic +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_cql2-text,http://www.opengis.net/spec/cql2/1.0/conf/cql2-text +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_1,http://www.opengis.net/spec/cql2/1.0/conf/cql2-text/validate +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_2,http://www.opengis.net/spec/cql2/1.0/conf/cql2-text/escaping +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_2,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/escaping +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_cql2-json,http://www.opengis.net/spec/cql2/1.0/conf/cql2-json +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_3,http://www.opengis.net/spec/cql2/1.0/conf/cql2-json/validate +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_basic-cql2,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2 +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_4,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/basic-test +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/comparison +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/property +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/binary-comparison-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/basic-test' +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/is-null +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/property +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/null-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/basic-test' +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_7,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/boolean +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_7,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_7,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/basic-test' +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_8,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/test-data +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_9,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/logical +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_9,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_advanced-comparison-operators,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_10,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/like +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_10,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/like-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_11,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/between +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_11,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/between-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_12,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/in +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_12,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/in-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_13,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/test-data +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_14,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/logical +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_case-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_15,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison/casei +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_15,http://www.opengis.net/spec/cql2/1.0/req/case-insensitive-comparison/casei-function +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_16,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison/casei-like +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_16,http://www.opengis.net/spec/cql2/1.0/req/case-insensitive-comparison/casei-function +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_17,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison/test-data +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_18,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison/logical +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_accent-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_19,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/accenti +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_19,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_20,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/accenti-like +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_20,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_21,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/accenti-casei +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_21,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_22,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/accenti-casei-like +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_22,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_23,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/test-data +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_24,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/logical +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_basic-spatial-functions,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_25,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions/s_intersects +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_25,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions/spatial-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_25,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_25,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions/spatial-data-types +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_26,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions/test-data +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_27,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions/logical +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_basic-spatial-functions-plus,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_28,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus/s_intersects +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_28,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus/spatial-predicate +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_28,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_28,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus/spatial-data-types +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_29,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus/test-data +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_spatial-functions,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_30,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_intersects +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_30,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_30,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_31,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_disjoint +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_31,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_31,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_32,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_equals +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_32,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_32,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_33,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_touches +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_33,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_33,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_34,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_crosses +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_34,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_34,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_35,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_within +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_35,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_35,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_36,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_contains +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_36,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_36,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_37,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_overlaps +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_37,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_37,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_38,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/test-data +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_39,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/logical +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_temporal-functions,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_40,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions/temporal-functions-1 +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_40,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-predicates +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_40,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_41,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions/temporal-functions-2 +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_41,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-predicates +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_41,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_42,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions/test-data +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_43,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions/logical +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_array-functions,http://www.opengis.net/spec/cql2/1.0/conf/array-functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_44,http://www.opengis.net/spec/cql2/1.0/conf/array-functions/array-predicates +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_44,http://www.opengis.net/spec/cql2/1.0/req/array-functions/array-predicates +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_45,http://www.opengis.net/spec/cql2/1.0/conf/array-functions/logical +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_property-property,http://www.opengis.net/spec/cql2/1.0/conf/property-property +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_46,http://www.opengis.net/spec/cql2/1.0/conf/property-property/comparison-value-property +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_46,http://www.opengis.net/spec/cql2/1.0/req/property-property/withdraw-permissions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_47,http://www.opengis.net/spec/cql2/1.0/conf/property-property/comparison-property-property +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_47,http://www.opengis.net/spec/cql2/1.0/req/property-property/withdraw-permissions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_48,http://www.opengis.net/spec/cql2/1.0/conf/property-property/comparison-value-value +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_48,http://www.opengis.net/spec/cql2/1.0/req/property-property/withdraw-permissions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_49,http://www.opengis.net/spec/cql2/1.0/conf/property-property/test-data +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_50,http://www.opengis.net/spec/cql2/1.0/conf/property-property/logical +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_functions,http://www.opengis.net/spec/cql2/1.0/conf/functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_51,http://www.opengis.net/spec/cql2/1.0/conf/functions/functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_51,http://www.opengis.net/spec/cql2/1.0/req/functions/functions +https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_arithmetic,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_52,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic/arithmetic +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_52,http://www.opengis.net/spec/cql2/1.0/req/arithmetic/arithmetic +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_53,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic/test-data +https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_54,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic/logical \ No newline at end of file From d6b8851e4d07cbf5eb5f2a750932a84176d4dfaf Mon Sep 17 00:00:00 2001 From: ghobona Date: Mon, 5 Aug 2024 10:22:14 +0100 Subject: [PATCH 3/4] Update 21-065r2.csv --- specification-elements/mappings/21-065r2.csv | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/specification-elements/mappings/21-065r2.csv b/specification-elements/mappings/21-065r2.csv index c12f47bd..96fa7897 100644 --- a/specification-elements/mappings/21-065r2.csv +++ b/specification-elements/mappings/21-065r2.csv @@ -72,27 +72,15 @@ https://docs.ogc.org/is/21-065r2/21-065r2.html#req_cql2-json_arithmetic,http://w https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_cql2-text,http://www.opengis.net/spec/cql2/1.0/conf/cql2-text https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_1,http://www.opengis.net/spec/cql2/1.0/conf/cql2-text/validate https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_2,http://www.opengis.net/spec/cql2/1.0/conf/cql2-text/escaping -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_2,http://www.opengis.net/spec/cql2/1.0/req/cql2-text/escaping https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_cql2-json,http://www.opengis.net/spec/cql2/1.0/conf/cql2-json https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_3,http://www.opengis.net/spec/cql2/1.0/conf/cql2-json/validate https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_basic-cql2,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2 https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_4,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/basic-test https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/comparison -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/property -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/binary-comparison-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_5,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/basic-test' https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/is-null -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/property -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/null-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_6,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/basic-test' https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_7,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/boolean -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_7,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_7,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/basic-test' https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_8,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/test-data https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_9,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/logical -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_9,http://www.opengis.net/spec/cql2/1.0/req/basic-cql2/cql2-filter https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_advanced-comparison-operators,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_10,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/like https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_10,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/like-predicate From 64eee87f8ee37c6aeba78773abe17405a18f49ec Mon Sep 17 00:00:00 2001 From: ghobona Date: Mon, 5 Aug 2024 11:46:22 +0100 Subject: [PATCH 4/4] Update 21-065r2.csv --- specification-elements/mappings/21-065r2.csv | 37 -------------------- 1 file changed, 37 deletions(-) diff --git a/specification-elements/mappings/21-065r2.csv b/specification-elements/mappings/21-065r2.csv index 96fa7897..36c502ac 100644 --- a/specification-elements/mappings/21-065r2.csv +++ b/specification-elements/mappings/21-065r2.csv @@ -83,78 +83,43 @@ https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_8,http://www.op https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_9,http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2/logical https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_advanced-comparison-operators,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_10,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/like -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_10,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/like-predicate https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_11,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/between -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_11,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/between-predicate https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_12,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/in -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_12,http://www.opengis.net/spec/cql2/1.0/req/advanced-comparison-operators/in-predicate https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_13,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/test-data https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_14,http://www.opengis.net/spec/cql2/1.0/conf/advanced-comparison-operators/logical https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_case-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_15,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison/casei -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_15,http://www.opengis.net/spec/cql2/1.0/req/case-insensitive-comparison/casei-function https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_16,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison/casei-like -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_16,http://www.opengis.net/spec/cql2/1.0/req/case-insensitive-comparison/casei-function https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_17,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison/test-data https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_18,http://www.opengis.net/spec/cql2/1.0/conf/case-insensitive-comparison/logical https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_accent-insensitive-comparison,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_19,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/accenti -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_19,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_20,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/accenti-like -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_20,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_21,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/accenti-casei -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_21,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_22,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/accenti-casei-like -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_22,http://www.opengis.net/spec/cql2/1.0/req/accent-insensitive-comparison/accenti-function https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_23,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/test-data https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_24,http://www.opengis.net/spec/cql2/1.0/conf/accent-insensitive-comparison/logical https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_basic-spatial-functions,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_25,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions/s_intersects -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_25,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions/spatial-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_25,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_25,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions/spatial-data-types https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_26,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions/test-data https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_27,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions/logical https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_basic-spatial-functions-plus,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_28,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus/s_intersects -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_28,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus/spatial-predicate -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_28,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_28,http://www.opengis.net/spec/cql2/1.0/req/basic-spatial-functions-plus/spatial-data-types https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_29,http://www.opengis.net/spec/cql2/1.0/conf/basic-spatial-functions-plus/test-data https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_spatial-functions,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_30,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_intersects -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_30,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_30,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_31,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_disjoint -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_31,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_31,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_32,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_equals -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_32,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_32,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_33,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_touches -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_33,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_33,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_34,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_crosses -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_34,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_34,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_35,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_within -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_35,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_35,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_36,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_contains -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_36,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_36,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_37,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/s_overlaps -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_37,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_37,http://www.opengis.net/spec/cql2/1.0/req/spatial-functions/spatial-data-types https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_38,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/test-data https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_39,http://www.opengis.net/spec/cql2/1.0/conf/spatial-functions/logical https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_temporal-functions,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_40,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions/temporal-functions-1 -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_40,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_40,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-functions https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_41,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions/temporal-functions-2 -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_41,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-predicates -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_41,http://www.opengis.net/spec/cql2/1.0/req/temporal-functions/temporal-functions https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_42,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions/test-data https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_43,http://www.opengis.net/spec/cql2/1.0/conf/temporal-functions/logical https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_array-functions,http://www.opengis.net/spec/cql2/1.0/conf/array-functions @@ -172,9 +137,7 @@ https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_49,http://www.o https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_50,http://www.opengis.net/spec/cql2/1.0/conf/property-property/logical https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_functions,http://www.opengis.net/spec/cql2/1.0/conf/functions https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_51,http://www.opengis.net/spec/cql2/1.0/conf/functions/functions -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_51,http://www.opengis.net/spec/cql2/1.0/req/functions/functions https://docs.ogc.org/is/21-065r2/21-065r2.html#conf_arithmetic,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_52,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic/arithmetic -https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_52,http://www.opengis.net/spec/cql2/1.0/req/arithmetic/arithmetic https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_53,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic/test-data https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_54,http://www.opengis.net/spec/cql2/1.0/conf/arithmetic/logical \ No newline at end of file