Open Geospatial Consortium

Submission Date: <yyyy-mm-dd>

Approval Date:  <yyyy-mm-dd>

Publication Date:  <yyyy-mm-dd>

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

Internal reference number of this OGC® document:    26-008

Version: 0.1 (Editor’s draft)

Latest Published Draft: n/a

Category: OGC® PROPOSAL DRAFT

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

OGC API - Features - Part 10: Query

Copyright notice

Copyright © 2026 Open Geospatial Consortium

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

Warning

This document is not an OGC Standard. This document is distributed for review and comment. This document is subject to change without notice and may not be referred to as an OGC Standard.

Recipients of this document are invited to submit, with their comments, notification of any relevant patent rights of which they are aware and to provide supporting documentation.

Document type:    OGC® Standard (PROPOSAL DRAFT)

Document subtype:   Interface

Document stage:    Draft

Document language:  English

License Agreement

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

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

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

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

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

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

Table of Contents

i. Abstract

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

The "OGC API - Features - Part 10: Query" standard (hereafter also referred to as "this Standard" or "this document") defines the behavior of an API that adds advanced query capabilities to a server. These extended query capabilities include queries with long expression text that cannot be conveniently specified as URI parameters; queries that fetch resources from one or more collections; queries that include predicates that join two or more collections; and stored queries with and without parameters.

Note
This Standard was developed in the Features API SWG but is being written as a generic extension that is applicable to a variety of resource types including features. The feature-specific portions of this extension are isolated to the clause titled Features. It is anticipated that the bulk of this extension will eventually be moved into 'OGC API - Common' and only the feature-specific content will remain to be managed by the Features API SWG.

ii. Keywords

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

resource feature collection instance spatial data openapi stored query REST PUT POST DELETE join filter CQL2

iii. Preface

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

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

iv. Submitting organizations

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

  • CubeWerx Inc.

  • interactive instruments

v. Submitters

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

Name

Affiliation

Clemens Portele (editor)_

interactive instruments

Panagiotis (Peter) A. Vretanos (editor)

CubeWerx Inc.

1. Scope

While "OGC API - Feature - Part 1: Core" provides basic searching (bounding box, temporal range, and equality) and "OGC API - Features - Part 3: Filtering" introduces complex query languages like CQL2, both are limited to single-collection searches.

This document, "OGC API - Feature - Part 10: Query", specifies extensions to the OGC API - Features suite of standards to support resource selection across one or more geodata collections. The extensions defined in this document enable complex query scenarios that were previously unsupported, including:

  • Complex Query Expressions: Queries with long text strings encoding complex query predicates that exceed URL parameter limits.

  • Bundled Requests: Multiple queries fetching resources from multiple collections encoded in a single request.

  • Cross-Collection Joins: Using predicates to join data from two or more collections.

  • Stored Query Management: Support for predefined and parameterized queries.

Specifically, this standard defines the mechanisms to:

  • Execute ad hoc queries referencing multiple collections.

  • Discover, inspect, and execute stored queries (including those with parameters).

  • Manage stored queries through lifecycle operations (Create, Replace, and Delete).

This Standard is encoding-agnostic but strongly recommends the JSON encoding defined within this document. Similarly, while any predicate language is technically permissible, the use of CQL2 (JSON encoding) is recommended for identifying resource subsets.

The following table maps the resource endpoints defined in this Standard to the HTTP methods GET, POST, PUT, and DELETE. Each cell links to the section detailing that specific resource-method combination. Any combination not explicitly listed in this table is considered undefined by this Standard.

Table 1. Supported HTTP methods by resource
Resource endpoint HTTP METHOD Description Reference

/query

GET

Get the list of stored queries.

Stored Query

POST

Execute an ad-hoc query.

Adhoc Query

/query/{queryId}

GET

Execute this stored query.

Stored Query

POST

Execute this stored query with an application/x-www-form-urlencoded body.

Stored Query

PUT

Create or replace a stored query.

Creating a stored query, Updating stored queries

DELETE

Delete this stored query.

Deleting stored queries

/query/{queryId}/definition

GET

Get the definition of a stored query.

Retrieving the definition of a stored query

/query/{queryId}/parameters

GET

Get the list of parameters for this parametertized stored query.

Retrieving the list of stored query parameters

/query/{queryId}/parameters/{parameterId}

GET

Get the definition of this query parametery.

Retrieving the definition of a query parameter

2. Conformance

This standard defines the following conformance classes:

The standardization target is "Web APIs".

The URIs of the associated conformance classes are:

Table 2. Conformance class URIs
Conformance class URI

Adhoc query

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/adhoc-query

Stored Query

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/stored-query

Multi-Resource Response

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/multi-resource-response

Join Response

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/join-response

Parameterized Stored Query

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/parameterized-stored-query

Manage Stored Queries

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/manage-stored-query

JSON Query Expression

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/query-expression-json

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

3. References

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

4. Terms, definitions and abbreviated terms

4.1. Terms and Definitions

This document uses the terms defined in Sub-clause 5.3 of [OGC 06-121r9], which is based on the ISO/IEC Directives, Part 2, Rules for the structure and drafting of International Standards. In particular, the word “shall” (not “must”) is the verb form used to indicate a requirement to be strictly followed to conform to this standard.

For the purposes of this document, the following additional terms, definitions and abbreviated terms apply in addition to those defined in OGC API - Features - Part 1: Core.

4.1.1. ad hoc query

a request for information created at the moment of need, characterized by its lack of a predetermined structure or scheduled execution; it is typically constructed using a query language (such as SQL) or a graphical interface to address a specific business question that is not covered by routine, "canned" reports

4.1.2. Application Programming Interface (API)

an interface that is defined in terms of a set of functions and procedures and enables a program to gain access to facilities within an application [oxford].

4.1.3. collection items end point

the path of the end point from which the resources of items of a collection can be accesses

EXAMPLE: For features, the collection items end point is '/collections/{collectionId}/items'.

EXAMPLE: For processes, the collection items end point is '/processes'

4.1.4. filter expression

predicate encoded for transmission between systems.

CQL2-Text or CQL2-JSON are examples how a predicate can be encoded as a filter expression.

4.1.5. parameterized stored query

a stored query that has one or more parameters.

Note
When executing a parameterized stored query, the user has to provide parameter values for each parameter of a stored query. If a parameter has a default value, a parameter can be omitted from the request to execute the stored query.

4.1.6. predicate

set of computational operations applied to a data instance which evaluate to true or false.

Note
In relational algebra, this is called a selection.

4.1.7. property selection

operation to create a copy of a data instance, restricted to a subset of the properties of the data instance.

Note
In relational algebra, this is called a projection. This term was used in the OGC Web Feature Service standard, but the Features API SWG has decided not to use the term, because in the context of geographic information the term "projection" is closely associated with map projections and causes confusion if used with a different meaning.

4.1.8. query

request for data from a dataset.

Note
A query will at least identify the data that the query operates on, the predicate(s) used to select the result set, the properties of the data instances that should be included in the response, the order in which the data instances should be included in the response, and the maximum number of data instances in the response.

4.1.9. queryable

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

4.1.10. resource end point

the path of the end point used to access a specific instance of a resource from a collection

EXAMPLE: For features, the resource end point is '/collections/{collectionId}/items/{featureId}'.

EXAMPLE: For processes, the resource end point is '/processes/{processId}'.

4.1.11. returnable

a token that represents a property of a resource that can be included in a representation of the resource.

Note
APIs implementing OGC API Features will include all returnables in a response unless the property has no value for the instance or if the property is not included in the list of requested properties (see property selection).

4.1.12. sortable

a token that represents a property of a resource that can be used to sort a collection of resource instances.

4.1.13. sorting

operation to order the data instances in a set based on the values of selected properties of each data instance.

4.1.14. Standardized API

an API that is intended to be deployed by multiple API providers with the same API definition.

Note
The only difference between the API definitions will be the URL(s) of the API deployment. All other aspects are identical (resources, content schemas, content constraints and business rules, content representations, parameters, etc.) so that any client that can use one deployment of the standardized API definition can also use all other deployments, too.
Note
If the API provides access to data, different deployments of the API will typically share different content.

4.1.15. Standards-based API

an API that conforms to one or more conformance classes specified in one or more standards.

Note
Since almost all APIs will conform to some standard, the term is usually used in the context of a specific standard or a specific family of standards. This ER considers Web APIs with a specific focus on the OGC API standards. Therefore, whenever the term is used in this ER, it is meant as an alias for an API that conforms to one or more conformance classes as defined in the OGC API standards.

4.1.16. stored query

a predefined query that is available a resource in a Web API.

Note
Stored queries can be used for two purposes. The first is to save users of the API the effort of creating their own queries. The second is to constrain what users may receive and how. The second purpose was the main purpose in the testbed where a developer creates stored queries for use by business users.

4.1.17. Web API

an API using an architectural style that is founded on the technologies of the Web [DWBP].

Note
Best Practice 24: Use Web Standards as the foundation of APIs in the W3C Data on the Web Best Practices [DWBP] provides more detail.
Note
A Web API is basically an API based on the HTTP standard(s).

4.2. Abbreviated Terms

API

Application Programming Interface

CQL2

OGC Common Query Language

CRS

Coordinate Reference System

JSON

JavaScript Object Notation

OGC

Open Geospatial Consortium

WFS

Web Feature Service

5. Conventions and background

See [ogc17-069], Clauses 5 and 6.

6. Requirements Class "Ad hoc Query"

6.1. Overview

Requirements Class

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/adhoc-query

Target type

Web API

Dependency

RFC 2616 (HTTP/1.1)

Ad hoc queries are custom, on-demand requests made on the fly to answer specific questions that fall outside the scope of pre-defined reporting.

6.2. Executing an ad-hoc query

Requirement 1

/req/adhoc-query/post-op

A

The server SHALL support the HTTP POST operation at the path /query.

Requirement 2

/req/adhoc-query/post-body

A

The body of the HTTP POST request SHALL contain a representation of a query expression.

This specification does not mandate a specific query expression language.

This specification does, however, make the following recommendation:

Recommendation 1

/rec/query-expression-json/json

A

If a query expression can be represented as JSON for its intended use, then implemenations SHOULD considing supporting Query Expression JSON.

6.3. Response

Requirement 3

/req/adhoc-query/response

A

A successful execution of the operation SHALL be reported as a response with a HTTP status code 200.

B

The response SHALL only include resources selected by the request.

7. Requirements Class "Stored Query"

7.1. Overview

Requirements Class

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/stored-query

Target type

Web API

Dependency

RFC 2616 (HTTP/1.1)

A stored query is a predefined query that is available as a resource in a Web API. This clause only deals with un-parameterized stored queries. The Parameterized Stored Query clause deals with stored queries that take parameters.

7.2. Stored Query Discovery

Requirement 4

/req/stored-query/queries-op

A

The server SHALL support the HTTP GET operation at the path /query.

Requirement 5

/req/stored-query/queries-success

A

A successful execution of the operation SHALL be reported as a response wit h a HTTP status code 200.

B

The content of that response SHALL be based upon the schema stored-queries.yaml.

---
allOf:
  - $ref: description.yaml
  - $ref: links.yaml
  - type: object
    properties:
      queries:
        type: array
        items:
          $ref: stored-query.yaml
---
allOf:
  - $ref: description.yaml
  - $ref: links.yaml
  - type: object
    required:
      - id
    properties:
      id:
        type: string
      mutable:
        type: boolean
        default: false
      query:
        description: |-
          PAV: I prefer including the entire text of the query in the
          description of the stored query so that one can see which 
          collections are being accessed, what filters are being applied,
          etc.  If we do this we don't need the parameter member since 
          the query text will include that information.  At least for the
          current json encoding of a parameterized stored query.
        oneOf:
          - type: string
          - type: object
      parameters:
        $ref: parameters.yaml
---
type: object
properties:
  title: 
    type: string
  description:
    type: string

7.3. Executing a stored query

Requirement 6

/req/stored-query/get-op

A

For every stored query identified in the stored queries response (path /query), the server SHALL support the HTTP GET operation at the path /query/{queryId}.

B

The parameter queryId is each id property in the stored queries response (JSONPath: $.queries[*].id).

7.4. Response

Requirement 7

/req/stored-query/get-success

A

A successful execution of the operation SHALL be reported as a response with a HTTP status code 200.

B

The response SHALL only include resources selected by the request.

Requirement 8

/req/stored-query/limit-response

A

The response SHALL not contain more resource than specified by the optional limit parameter.

B

If the API definition specifies a maximum value for limit parameter, the response SHALL not contain more resource than this maximum value.

C

Only items are counted that are on the first level of the nested collection. Any nested objects contained within the explicitly requested items SHALL not be counted.

8. Requirements Class "Multi-Resource Response"

8.1. Overview

Requirements Class

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/multi-resource-response

Target type

Web API

Dependency

RFC 2616 (HTTP/1.1)

Dependency

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/adhoc-query

Dependency

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/stored-query

When multiple queries are specified, the results must be organized in a way that preserves the context of each query. While simple concatenation into a single Feature Collection is possible, it introduces significant challenges regarding resource identity, duplicate handling, and metadata clarity.

To address these challenges, this Standard adopts the approach established in WFS 2.0. Rather than merging all results into a single collection response, this clause defines a response structure that returns an array of collections (one for each query in the expression). This offers several architectural benefits:

  • Conceptual Clarity: It avoids "hacks" like identifier prefixing or complex duplicate-handling logic by keeping result sets isolated.

  • Support for Joins: Since a query expression may contain queries that perform joins, the structure defined in this document also allows collections of tuples to be included within the response array.

  • JSON-FG Compatibility: This structure is highly beneficial for use with JSON-FG, where each collection can maintain its own homogeneous metadata and schema definitions.

  • Client Versatility: While single collections are slightly simpler for basic tools, JavaScript-based clients can process an array of collections with negligible overhead, benefiting from the clearer data separation.

If the same resource satisfies the criteria of multiple queries, it should ideally be included only once in a flattened result set. However, by using the array of collections model, the resource can appear in each relevant collection without causing identifier conflicts, as its context is defined by its parent collection.

8.2. JSON Response

Requirement 9

/req/multi-resource-response/json

A

A successful execution of the operation SHALL be reported as a response with a HTTP status code 200.

B

The content of that response SHALL be based upon the collection.yaml schema.

---
allOf:
  - $ref: links.yaml
  - type: object
    required:
      - type
      - collections
    properties:
      type:
        type: string
        const: Collections
      collections:
        type: array
        items:
          oneOf:
            - $ref: https://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/schemas/featureCollectionGeoJSON.yaml
            - $ref: tuples.yaml
            - comment: "other resource types here"
      timeStamp:
        type: string
        format: date-time
      numberMatched:
        type: integer
        minimum: 0
      numberReturned:
        type: integer
        minimum: 0

See also tuples.yaml

Requirement 10

/req/multi-resource-response/resource-order

A

The order of resources presented in the collections array SHALL match the order in which the queries are specified in the query expression.

Permission 1

/rec/multi-resource-response/resource-id

A

A server MAY re-write the identifier of each resource in the response to uniquely identify each resource within the response.

A common strategy for reassigning identifiers is to prefix the resource identifier with the identifier of its source collection, using a dot (e.g., collectionId.resourceId) as a separator.

Permission 2

/rec/multi-resource-response/json-pointers

A

To prevent duplication of resources in the response, a JSON pointer may be used to reference the duplicate resources.

Requirement 11

/req/multi-resource-response/limit-response

A

The response SHALL not contain more resources/tuples than specified by the optional limit parameter.

B

If the API definition specifies a maximum value for limit parameter, the response SHALL not contain more resources/tuples than this maximum value.

8.2.1. Examples

The following example illustrates a response for a query expression containing multiple queries that retrieve resources from different collections. Notably, one of these queries also incorporates a join operation.

Example 1. Example of a multiple queries in a query expression.
   CLIENT                                                               SERVER
     |                                                                     |
     |   POST /query   HTTP/1.1                                            |
     |   Host: www.someserver.com/                                         |
     |   Accept: application/json                                          |
     |   Content-Type: application/ogcqry+json                             |
     |                                                                     |
     |   {                                                                 |
     |     "queries": [                                                    |
     |       { "collections":["runwayelement"] },                          |
     |       { "collections":["taxiwayelement"] },                         |
     |       {                                                             |
     |         "collections": ["apronelement", "apron"],                   |
     |         "filter": {                                                 |
     |           "op": "and",                                              |
     |           "args": [                                                 |
     |             { "op": "=",                                            |
     |               "args": [{"property": "apronelement.associatedApron"},|
     |                        {"property": "apron.id"}]                    |
     |             },                                                      |
     |             { "op": "in",                                           |
     |               "args": [{"property": "apronelement.airport"},        |
     |                       ["JFK", "EWR", "LGA"]]                        |
     |             }                                                       |
     |           ]                                                         |
     |         }                                                           |
     |       }                                                             |
     |     ]                                                               |
     |   }                                                                 |
     |-------------------------------------------------------------------->|
     |                                                                     |
     |   Content-Type: application/json                                    |
     |   {                                                                 |
     |     type: "Collections",                                            |
     |     collections: [                                                  |
     |       {                                                             |
     |          "type": "FeatureCollection",                               |
     |          "features": [                                              |
     |            { ... feature ... },                                     |
     |            { ... feature ... },                                     |
     |            .                                                        |
     |            .                                                        |
     |            .                                                        |
     |          ]                                                          |
     |       },                                                            |
     |       {                                                             |
     |          "type": "FeatureCollection",                               |
     |          "features": [                                              |
     |            { ... feature ... },                                     |
     |            { ... feature ... },                                     |
     |            .                                                        |
     |            .                                                        |
     |            .                                                        |
     |          ]                                                          |
     |       },                                                            |
     |       {                                                             |
     |         "tuples": [                                                 |
     |           [                                                         |
     |             { ... feature ... },                                    |
     |             { ... feature ... }                                     |
     |           ],                                                        |
     |           [                                                         |
     |             { ... feature ... },                                    |
     |             { ... feature ... }                                     |
     |           ],                                                        |
     |           .                                                         |
     |           .                                                         |
     |           .                                                         |
     |         ]                                                           |
     |       }                                                             |
     |     ]                                                               |
     |   }                                                                 |
     |<--------------------------------------------------------------------|

9. Requirements Class "Join Response"

9.1. Overview

Requirements Class

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/join-response

Target type

Web API

Dependency

RFC 2616 (HTTP/1.1)

Dependency

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/adhoc-query

This Standard defines a join through the inclusion of multiple entries within the collections member of a query. This clause outlines the required server response patterns and data structures for such operations.

One approach aligns with standard SQL behavior, where properties from all participating collections are aggregated into a unified result set. However, this implementation introduces several architectural considerations that must be addressed:

  • Namespace Management: To ensure data integrity and prevent naming collisions, property identifiers in both requests and responses must follow a prefixed naming convention (e.g., collection_name.property).

  • Identity Management: A formal protocol is required for assigning unique IDs to joined features, such as the implementation of composite keys or tuple-based identifiers.

  • Geometry Resolution: Logic must be established to designate a "primary" geometry within GeoJSON representations when a join yields multiple spatial properties.

  • Data Serialization: The standard must determine whether to retain a flat, prefixed naming structure or adopt a nested object approach (grouping properties under a parent collection object) to enhance response readability.

In contrast to the SQL-style merging of properties, this Standard adopts a tuple-based approach. Rather than attempting to flatten or merge joined resources, the Standard reports each tuple with its participating resources fully intact.

To optimize performance and reduce data redundancy within each tuple, the Standard supports the use of pointers. By enforcing specific constraints on the order in which resources are encoded, the Standard effectively bypasses the previously identified challenges regarding namespace management, identity management, geometry resolution, and data serialization.

Under this model, the raw results of the join are transmitted directly to the client, providing the flexibility for the end-user application to determine the most appropriate method for processing and presenting the joined data.

9.2. JSON Response

Requirement 12

/req/join-response/json

Condition

The query expression includes a join predicate between 2 or more collections.

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 tuples.yaml schema.

---
allOf:
  - $ref: links.yaml
  - type: object
    required:
      - type
      - tuples
    properties:
      type:
        type: string
        const: TupleCollection
      tuples:
        type: array
        items:
          $ref: tuple.yaml
      timeStamp:
        type: string
        format: date-time
      numberMatched:
        type: integer
        minimum: 0
      numberReturned:
        type: integer
        minimum: 0
---
type: array
minItems: 2
items:
  $ref: https://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/schemas/featureGeoJSON.yaml

Requirement 13

/req/json-response/resource-order

A

The order of resources presented in a tuple SHALL match the order of collections specified in the collections member of a query.

Requirement 14

/req/json-response/sorting

A

Any sortby clause specified in a query expression SHALL determine the order in which tuples are presented and not the resources within each tuple.

Permission 3

/rec/join-response/resource-id

A

A server MAY re-write the identifier of each resource in the join response to uniquely identify each resource within the response.

A common strategy for reassigning identifiers is to prefix the resource identifier with the identifier of its source collection, using a dot (e.g., collectionId.resourceId) as a separator.

Permission 4

/rec/join-response/json-pointers

A

To prevent duplication of tuple members, a JSON pointer may be used to reference the duplicate resource.

Requirement 15

/req/join-response/limit-response

A

The response SHALL not contain more join tuples than specified by the optional limit parameter regardless of the number of resources per tuple.

B

If the API definition specifies a maximum value for limit parameter, the response SHALL not contain more tuples than this maximum value.

Example 2. Example of a spatial join query.

This example demonstrates how to retrieve all lakes located within Algonquin Park. The query includes a collections member that references the two geodata sources: Parks and Lakes.

The filter member uses a CQL2 expression to execute a spatial join, filtering collections based on the spatial containment of their geometries. In accordance with requirement /req/query-expression-json/join-filter, all queryables within the CQL2 expression are prefixed with the relevant collection identifier, using a dot (".") as a separator.

The resulting response is returned as an array of tuples. Since this query targets two collections, each tuple consists of a pair of features that satisfy the specified predicates.

To optimize the response and eliminate redundancy, the Parks feature—which remains constant as "Algonquin Park" across all results—is only fully encoded in the first tuple. Every subsequent tuple employs a JSON Pointer to reference the initial Algonquin Park feature rather than duplicating its data.

Each feature within each tuple is presented in the order in which the source collections where specified in the query: Parks first, then Lakes.

Finally, the individual features within each tuple are encoded using the GeoJSON standard.

   CLIENT                                                               SERVER
     |                                                                     |
     |   POST /query   HTTP/1.1                                            |
     |   Host: www.someserver.com/                                         |
     |   Accept: application/json                                          |
     |   Content-Type: application/ogcqry+json                             |
     |                                                                     |
     |   {                                                                 |
     |      "collections": ["parks","lakes"]                               |
     |      "filter": {                                                    |
     |         "and": [                                                    |
     |            {"eq": [{"property": "parks.name"},"Algonquin Park"]}    |
     |            {"contains": [{"property": "parks.geometry"},            |
     |                          {"property": "lakes.geometry"}]}           |
     |         ]                                                           |
     |      }                                                              |
     |   }                                                                 |
     |-------------------------------------------------------------------->|
     |                                                                     |
     |   Content-Type: application/json                                    |
     |   {                                                                 |
     |      "tuples": [                                                    |
     |         [                                                           |
     |            {                                                        |
     |               "id": "park.001",                                     |
     |               "type": "Feature",                                    |
     |               "geometry": { ... },                                  |
     |               "properties": { ... }                                 |
     |            },                                                       |
     |            {                                                        |
     |               "id": "lake.001",                                     |
     |               "type": "Feature",                                    |
     |               "geometry": { ... },                                  |
     |               "properties": { ... }                                 |
     |            }                                                        |
     |         ],                                                          |
     |         [                                                           |
     |            { "$ref": "#/tuples[0]/[0]" },                           |
     |            {                                                        |
     |               "id": "lake.001",                                     |
     |               "type": "Feature",                                    |
     |               "geometry": { ... },                                  |
     |               "properties": { ... }                                 |
     |            }                                                        |
     |         ],                                                          |
     |         .                                                           |
     |         .                                                           |
     |         .                                                           |
     |      ]                                                              |
     |   }                                                                 |
     |<--------------------------------------------------------------------|

10. Requirements Class "Parameterized Stored Query"

10.1. Overview

Clause Stored Query defines a server’s behavior for non-parameterized stored queries. In contrast, this section addresses parameterized stored queries, which are designed to accept arguments at runtime.

Requirements Class

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/parameterized-stored-query

Target type

Web API

Dependency

RFC 2616 (HTTP/1.1)

Dependency

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/stored-query

10.2. Parameter discovery

Requirement 16

/req/parametrized-stored-query/parameters-op

A

For each stored query identified in the stored queries response (path: /query), the server SHALL support the HTTP GET operation at the path /query/{queryId}/parameters.

B

The parameter queryId is each id property (JSONPath: $.queries[*].id) in the stored queries response (path: /query).

Requirement 17

/req/parameterized-stored-query/parameters-success

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 contains a description of all the parameters of the stored query.

See also parameters.yaml for a JSON encoding of the list of stored query parameters.

Requirement 18

/req/parametrized-stored-query/parameter-op

A

For each stored query identified in the stored queries response (path: /query), the server SHALL support the HTTP GET operation at the path /query/{queryId}/parameters/{parameterId}.

B

The parameter queryId is each id property (JSONPath: $.queries[*].id) in the stored queries response (path: /query).

C

The parameter parameterId is each id property (JSONPath: $.queries[].parameters[].id) in the stored query parameters response (path: /query/{queryId}/parameters).

Requirement 19

/req/parameterized-stored-query/parameter-success

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 a document describing the parameter.

10.3. Executing a parameterized stored query

10.3.1. Using the GET method

See Executing stored queries for instructions on running an unparameterized stored query.

Requirement 20

/req/parameterized-stored-query/parameters-url-mapping

A

Each query parameter identifier (JSON Path: $.queries[*].id in the stored queries response) SHALL also be valid URL query parameter name as defined in Uniform Resource Identifier (URI): Genertic Syntax.

To run a parameterized stored query, use the same /query/{queryId} endpoint, but append the required parameters to the URL as query strings.

Example 3. Invoking a parameterized stored query using the HTTP GET method

This example invokes a parameterized stored query with idenfitier MyQuery02 that takes two parameters myParam01 and myParam02.

GET /query/MyQuery02?myParam01=X&myParam02=Y

10.3.2. Using the POST method

Alternatively, a parameterized stored query can be executed using the POST method and a URL-encded form.

Requirement 21

/req/parameterized-stored-query/post-op

A

For every stored query identified in the stored queries response (path /query), the server SHALL support the HTTP POST operation at the path /query/{queryId}.

B

The parameter queryId is each id property in the stored queries response (JSONPath: $.queries[*].id).

C

The content type of the POST body shall be application/x-www-form-urlencoded.

11. Requirements Class "Manage Stored Query"

11.1. Overview

Requirements Class

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/manage-stored-query

Target type

Web API

Dependency

RFC 2616 (HTTP/1.1)

Dependency

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/stored-query

Servers that implement this conformance class provide the capability to create, modify, and delete stored queries. Implementers should be aware that these operations introduce significant security implications, which are addressed in detail within the Security Considerations clause.

This Standard distinguishes between "mutable" and "immutable" stored queries, recognizing that some implementations may provide preconfigured, built-in queries with opaque logic that cannot be modified.

11.2. Getting the definition of a stored query

Requirement 22

/req/stored-query/get-op

A

For every stored query identified in the stored queries response (path /query), the server SHALL support the HTTP GET operation at the path /query/{queryId}/definition.

B

The parameter queryId is each id property in the stored queries response (JSONPath: $.queries[*].id).

Requirement 23

/req/manage-stored-query/definition-success

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 schema stored-query.yaml.

11.3. Creating stored queries

Requirement 24

/req/stored-query/put-create

A

The server SHALL support the HTTP PUT operation at the path /query/{queryId}.

B

The parameter queryId SHALL be specified by the client.

Requirement 25

/req/stored-query/put-body

A

The body of a HTTP PUT request SHALL contain a representation of the query.

This specification does not mandate a specific query expression language.

This specification does, however, make the following recommendation:

Recommendation 2

/rec/query-expression-json/json

A

If a query expression can be represented as JSON for its intended use, then implemenations SHOULD considing supporting Query Expression JSON.

Requirement 26

/req/stored-query/put-create-success

A

A successful execution of the operation SHALL be reported as a response with a HTTP status code '201'.

11.4. Updating stored queries

Requirement 27

/req/stored-query/put-update

Condition

The value of the mutable parameter (JSONPath: $.queries[*].mutable) SHALL be true.

A

The server SHALL support the HTTP PUT operation at the path /query/{queryId}.

B

The parameter queryId is each id property in the stored queries response (JSONPath: $.queries[*].id).

Requirement 28

/req/stored-query/put-update-success

A

A successful execution of the operation SHALL be reported as a response with a HTTP status code '204'.

11.5. Deleting stored queries

Requirement 29

/req/stored-query/delete-op

Condition

The value of the mutable property (JSONPath: $.queries[*].mutable) SHALL be true.

A

For every stored query in the stored queries response (path '/query'), the server SHALL support the HTTP DELETE operation at the path '/query/{queryId}'.

B

The parameter queryId is each id property in the stored queries response (JSONPath: $.queries[*].id).

Requirement 30

/req/stored-query/delete-success

A

A successful execution of the operation SHALL be reported as a response wit h a HTTP status code '200'.

12. Query Expressions

12.1. Overview

This clause defines the structure of a query expression, which may consist of either a single query or multiple queries within a single request.

Each query must specify the target geodata collection(s) and may include optional projection, selection, and sorting clauses. When a query expression contains multiple queries, both local (specific to an individual query) and global selection clauses may be defined, along with the logical operation required to combine them.

Table 3. Components of a query
Component Description Requirements

Collections

The list of geodata source being accessed

Mandatory

Projection

Defines which properties are returned

Optional

Selection

Filters results based on specific criterial (local and global)

Optional

Sorting

Determines the order of the result set

Optional

Logical Ops

Defines how to combine selection clauses

Optional (default AND)

This Standard does not mandate a specific encoding for query expressions, allowing for implementation flexibility.

Permission 5

/rec/query-expression-json/other

A

Other encodings for a query expression MAY be used but their behaviour is undefined by this Standard.

This Standard, however, defines the Query Expression JSON requirements class for implementations utilizing a JSON-based encoding.

Recommendation 3

/rec/query-expression-json/json

A

If a query expression can be represented as JSON for its intended use, then implemenations SHOULD considing supporting Query Expression JSON.

12.2. Requirements Class "Query Expression JSON"

12.2.1. Overview

This clause defines the JSON encoding for a query expression.

Requirements Class

http://www.opengis.net/spec/ogcapi-features-10/1.0/req/query-expression-json

Target type

Web API

Dependency

RFC 2616 (HTTP/1.1)

12.2.2. Query expression schema

Requirement 31 /req/query-expression-json/query-expression-schema

A

The JSON encoding of a query expression SHALL be defined by the following schema fragments:

---
oneOf:
  - allOf:
      - $ref: description.yaml
      - $ref: parameters.yaml
      - $ref: limit.yaml
      - $ref: query.yaml
  - allOf:
    - $ref: description.yaml
    - $ref: parameters.yaml
    - $ref: limit.yaml
    - allOf:
        - $ref: filter.yaml
        - type: object
          required:
            - queries
          properties:
            queries:
              type: array
              minItems: 1
              items:
                $ref: query.yaml
            filterOperator:
              type: string
              default: and
              enum:
                - and
                - or
Requirement 32 /req/query-expression-json/query-schema

A

The JSON encoding of a query SHALL be defined by the following schema fragments:

---
allOf:
  - $ref: properties.yaml
  - $ref: filter.yaml
  - $ref: sortby.yaml
  - type: object
    required:
      - collections
    properties:
      collections:
        type: array
        minItems: 1
        items:
          type: string

See also description.yaml.

Recommendation 4

/rec/query-expression-json/metadata

A

A query expression SHOULD include a title and description to explain the query to users and also provide descriptive, human readable metadata, that can harvested by automated tooling such as catalogs.

12.2.3. Projection clause

Requirement 33

/req/query-expression-json/properties-schema

A

The JSON Encoding for the projection clause of a query SHALL be defined by the following schema fragments:

---
type: object
properties:
  properties:
    type: array
    minItems: 1
    items:
      type: string

Requirement 34

/req/query-expression-json/join-filter

Conditions

The collections member in a query contains more that one collection identifier.

A

In a projection clause (member: properties), each referenced property SHALL be identified by a composite name consisting of the source collection identifier followed by the property identifier, joined by a dot (".") separator.

12.2.4. Selection clause

Requirement 35 /req/query-expression-json/filter-schema

A

The JSON encoding for the selection clause of query SHALL be defined by the following schema fragments:

---
type: object
properties:
  filter-lang:
    type: string
    default: cql-json
    enum:
      - cql-json
      - cql-text
  filter-crs:
    type: string
    format: uri
    default: http://www.opengis.net/def/crs/OGC/1.3/CRS84
  filter:
    oneOf:
      - type: string
      - type: object
      - type: cql.yaml

Requirement 36

/req/query-expression-json/join-filter

Conditions

The collections member in a query contains more that one collection identifier.

A

In the selection clause (member: filter), each referenced queryable SHALL be identified by a composite name consisting of the source collection identifier followed by the queryable identifier, joined by a dot (".") separator.

12.2.5. Sorting clause

Requirement 37

/req/query-expression-json/sortby-schema

A

The JSON Encoding for the sorting clause of a query SHALL be defined by the following schema fragments:

---
type: object
properties:
  sortby:
    type: array
    minItems: 1
    items:
      type: string
      pattern: "[+

Requirement 38

/req/query-expression-json/join-sortby

Conditions

The collections member in a query contains more that one collection identifier.

A

In the sorting clause (member: sortby), each referenced sortable SHALL be identified by a composite name consisting of the source collection identifier followed by the sortable identifier, joined by a dot (".") separator.

Requirement 39

/req/query-expression-json/sortby-scope

A

The scope of a sortby clause SHALL be limited to the results for the query that contains the clause.

Note
Applying a global sortby clause requires the server to aggregate the results of all sub-queries before sorting the combined set. This approach precludes the ability to stream the response, as the entire result set must be held in memory prior to transmission.

12.2.6. Parameters

Requirement 40 /req/query-expression-json/parameters-schema

A

The JSON encoding for query parameters SHALL be defined by the following schema fragment:

---
type: object
properties:
  parameters:
    type: object
    additionalProperties:
      $ref: https://json-schema.org/draft/2020-12/schema

For parameterized stored queries, the query expression incorporates JSON objects containing a $parameter member. This member identifies the parameter by name and defines its constraints using a logical JSON Schema.

Requirement 41

/req/query-expression-json/parameters-value-schema

A

The schema describing the value of a parameter SHALL be a valid logical schema as defined in "OGC API - Features - Part 5: Schema".

Requirement 42

/req/query-expression-json/parameters-sub-logic

A

During query execution, the server SHALL performs a substitution process, replacing every instance of a $parameter object with the corresponding argument provided in the execution request.

B

The provided argument SHALL strictly adhere to the constraints defined in the parameter’s JSON Schema.

C

If a parameter declares a default value within its schema, the server SHALL apply that value automatically if no argument is provided in the execution request.

D

If a parameter is defined as an array type, the server SHALL convert comma-separated input strings into a standard JSON array.

Permission 6

/rec/query-expression-json/parameters

A

The parameters of a parameterized query expression MAY be specified in a top-level member and referenced using the $ref key.

13. Media Types

Additional JSON media types that would typically be used in a server that supports JSON are:

  • application/ogc-query+json

  • application/parameters+json

14. Security Considerations

Table 4. Security considerations for stored queries
Operation Security Risk Mitigation

Create

Injection attacks

Validate query syntax and parameters

Modify

Unauthorized access

Implement role-based access control (RBAC)

Delete

Service disruption

RBAC with admin privileges

Annex A: Abstract Test Suite (Normative)

A.1. Introduction

Note
This needs to be updated.

OGC API Features is not a Web Service in the traditional sense. Rather, it defines the behavior and content of a set of Resources exposed through a Web Application Programing Interface (Web API). Therefore, an API may expose resources in addition to those defined by the standard. A test engine must be able to traverse the API, identify and validate test points, and ignore resource paths which are not to be tested.

Annex B: Sample Expressions and Requests

B.1. Example query expressions

B.1.1. A simple, single query

{
  "title": "Fetch all apron areas",
  "collections": ["apronelement"]
}

B.1.2. A simple query with a filter, property selection and sorting of the response document

{
  "title": "Fetch all concrete apron areas of the main New York area airports (JFK, EWR and LGA)",
  "description": "Returned are the geometry, the airport and the apron type, sorted by airport.",
  "collections": ["apronelement"],
  "filter": {
    "op": "and",
    "args": [
      { "op": "=", "args": [{ "property": "composition" }, "CONC"] },
      { "op": "in", "args": [{ "property": "airport" }, ["JFK", "EWR", "LGA"]] }
    ]
  },
  "properties": ["geometry", "airport", "type"],
  "sortby": ["airport"],
  "limit": 1000
}

B.1.3. The same query with two parameters (one string and one string array)

{
  "title": "Fetch the apron areas of selected airports",
  "description": "Returned are the geometry, the airport, the apron type and the material, sorted by airport. The query accepts two parameters: the airport and the type of the apron area.",
  "collections": ["apronelement"],
  "filter": {
    "op": "and",
    "args": [
      {
        "op": "=",
        "args": [
          {"property": "type"},
          {
            "$parameter": {
              "type": {
                "title": "Type of the apron, runway or taxiway element",
                "description": "The following types are distinguished: normal use, parking, shoulder, intersection.",
                "type": "string",
                "enum": ["NORMAL", "PARKING", "INTERS", "SHOULD"],
                "default": "NORMAL"
              }
            }
          }
        ]
      },
      {
        "op": "in",
        "args": [
          {"property": "airport"},
          "$parameter": {
            "airports": {
              "title": "Airports",
              "description": "The 3-letter IATA airport codes or the airports to filter. Specify multiple values as a comma-separated list.",
              "type": "array",
              "items": {
                "type": "string",
                "enum": ["JFK", "EWR", "LGA", "BOS", "PIT", "PHL", "DCA", "BWI", "IAD"]
              },
              "default": ["JFK", "EWR", "LGA"]
            }
          }
        ]
      }
    ]
  },
  "properties": ["geometry", "airport", "type", "composition"],
  "sortby": ["airport"],
  "limit": 1000
}

B.1.4. The same query with the two parameters declared at the top level

{
  "title": "Fetch the apron areas of selected airports",
  "description": "Returned are the geometry, the airport, the apron type and the material, sorted by airport. The query accepts two parameters: the airport and the type of the apron area.",
  "collections": ["apronelement"],
  "filter": {
    "op": "and",
    "args": [
      {
        "op": "=",
        "args": [
          {"property": "type"},
          {"$parameter": {"$ref": "#/parameters/type"}}
        ]
      },
      {
        "op": "in",
        "args": [
          {"property": "airport"},
          {"$parameter": {"$ref": "#/parameters/airport"}}
        ]
      }
    ]
  },
  "properties": ["geometry", "airport", "type", "composition"],
  "sortby": ["airport"],
  "limit": 1000,
  "parameters": {
    "airports": {
      "title": "Airports",
      "description": "The 3-letter IATA airport codes or the airports to filter. Specify multiple values as a comma-separated list.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": ["JFK", "EWR", "LGA", "BOS", "PIT", "PHL", "DCA", "BWI", "IAD"]
      },
      "default": ["JFK", "EWR", "LGA"]
    },
    "type": {
      "title": "Type of the apron, runway or taxiway element",
      "description": "The following types are distinguished: normal use, parking, shoulder, intersection.",
      "type": "string",
      "enum": ["NORMAL", "PARKING", "INTERS", "SHOULD"],
      "default": "NORMAL"
    }
  }
}

B.1.5. A query on multiple collections

{
  "queries": [
    {"collections":["apronelement"]},
    {"collections":["runwayelement"]},
    {"collections":["taxiwayelement"]}
  ]
}

B.1.6. A query on mulitple collections with sorting as well as global filtering and property selection

{
  "queries": [
    {"collections":["apronelement"], "sortby": ["airport"]},
    {"collections":["runwayelement"], "sortby": ["airport"]},
    {"collections":["taxiwayelement"], "sortby": ["airport"]}
  ],
  "filter": {
    "op": "and",
    "args": [
      { "op": "=", "args": [{ "property": "composition" }, "CONC"] },
      { "op": "in", "args": [{ "property": "airport" }, ["JFK", "EWR", "LGA"]] }
    ]
  },
  "properties": ["geometry", "airport", "type"],
  "limit": 1000
}

B.1.7. A query on multiple collections with a different filter expressions for each collection

{
  "queries": [
    {
      "collections":["apronelement"],
      "filter": { ... }
    },
    {
      "collections":["runwayelement"],
      "filter": { ... }
    },
    {
      "collections":["taxiwayelement"],
      "filter": { ... }
    }
  ],
  "limit": 1000
}

B.1.8. A query on multiple collections with sorting and a different filter for each collection and a global filter plus property selection

{
  "queries": [
    {
      "collections":["apronelement"],
      "filter": { ... },
      "sortby": ["airport"]
    },
    {
      "collections":["runwayelement"],
      "filter": { ... },
      "sortby": ["airport"]
    },
    {
      "collections":["taxiwayelement"],
      "filter": { ... },
      "sortby": ["airport"]
    }
  ],
  "filter": {
    "op": "and",
    "args": [
      { "op": "=", "args": [{ "property": "composition" }, "CONC"] },
      { "op": "in", "args": [{ "property": "airport" }, ["JFK", "EWR", "LGA"]] }
    ]
  },
  "properties": ["geometry", "airport", "type"],
  "limit": 1000
}

B.1.9. A single join query

{
  "collections": ["apronelement", "apron"],
  "filter": {
    "op": "and",
    "args": [
      { "op": "=", "args": [{ "property": "apronelement.associatedApron" }, { "property": "apron.id" }] },
      { "op": "in", "args": [{ "property": "apronelement.airport" }, ["JFK", "EWR", "LGA"]] }
    ]
  },
  "sortby": ["apronelement.airport"],
  "limit": 1000
}

B.2. Example requests

This section illustrates example requests and responses in the scenario.

B.2.1. Developer Client analyzes the available data

TODO: Fetch collections, their queryables, presentables, and sortables.

B.2.2. Developer Client creates a stored query ("filtering rule")

With the following request, the Developer Client creates a parameterized stored query on a dataset with AIXM-based airport data on the Filtering Service.

The query has three parameters.

  • "collection": The feature type that is queried. Restricted to one of "apronelement," "runwayelement," or "taxiwayelement." The default is "runwayelement" if no parameter value is specified in the query.

  • "type": The type of the apron/runway/taxiway element. One of "NORMAL," "PARKING," "INTERS," or "SHOULD". If no parameter value is specified in the query the default is "NORMAL."

  • "airports": The airports for which the query should return data which is restricted to selected airports. The default is "IAD" if no parameter value is specified in the query.

The query:

  • returns only four feature properties ("geometry," "airport," "type," "composition"), all additional properties in the data are not returned;

  • sorts the response by airport; and,

  • limits the response to 10000 features: if more are matched, the response will include a "next" link to the next page.

PUT /d103_airports/search/elements-by-type-and-airport HTTP/1.1
Host: t18.ldproxy.net
Content-Type: application/json

{
  "title": "Fetch apron, taxiway or runway elements based on their type and airport",
  "description": "This query fetches apron, taxiway or runway elements based on their type and airport. The response uses paging, if more than 10000 features match the query. The result is sorted by airport.",
  "query": {
    "collections": [
      {
        "$parameter": {
          "collection": { "type": "string", "enum": ["apronelement", "runwayelement", "taxiwayelement"], "default": "apronelement" }
        }
      }
    ],
    "filter": {
      "op": "and",
      "args": [
        {
          "op": "=",
          "args": [
            {"property": "type"},
            {
              "$parameter": {
                "type": { "type": "string", "enum": ["NORMAL", "PARKING", "INTERS", "SHOULD"], "default": "NORMAL" }
              }
            }
          ]
        },
        {
          "op": "in",
          "args": [
            {"property": "airport"},
            {
              "$parameter": {
                "airports": {
                  "type": "array",
                  "items": { "type": "string", "enum": ["JFK", "EWR", "LGA", "BOS", "PIT", "DCA", "IAD", "BWI", "PHL"] },
                  "default": ["IAD", "DCA", "BWI"]
                }
              }
            }
          ]
        }
      ]
    },
    "properties": ["geometry", "airport", "type", "composition"],
    "sortby": ["airport"]
  },
  "limit": 10000
}

The server creates the stored query. If the stored query already existed, the query would be updated with the new definition.

HTTP/1.1 204 No Content

B.2.3. Business Client fetches the available queries

The Business Client wants to filter data and asks the Filtering Service for the available queries.

Note
In addition to the queries stored on the server, the Filtering Service can also allow the execution of ad-hoc queries specified by a client. This scenario assumes that the Business Client does not have the capability to construct query expressions, only the Developer Client has that capability.
GET /d103_airports/search HTTP/1.1
Host: t18.ldproxy.net
Accept: application/json

The Filtering Service responds with the list of stored queries available on the server:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "queries": [
    {
      "id": "elements-by-type-and-airport",
      "title": "Fetch apron, taxiway or runway elements based on their type and airport",
      "description": "This query fetches apron, taxiway or runway elements based on their type and airport. The response uses paging, if more than 10000 features match the query. The result is sorted by airport.",
      "links": [
        {
          "rel": "self",
          "title": "Query 'Fetch apron, taxiway or runway elements based on their type and airport'",
          "href": "https://t18.ldproxy.net/d103_airports/search/elements-by-type-and-airport"
        },
        {
          "rel": "describedby",
          "title": "Definition of query 'Fetch apron, taxiway or runway elements based on their type and airport'",
          "href": "https://t18.ldproxy.net/d103_airports/search/elements-by-type-and-airport/definition"
        }
      ],
      "parameters": {
        "type": {
          "title": "Type of the apron, runway or taxiway element",
          "description": "The following types are distinguished: normal use, parking, shoulder, intersection.",
          "type": "string",
          "enum": ["NORMAL", "PARKING", "SHOULD", "INTERS"],
          "default": "NORMAL"
        },
        "airports": {
          "title": "Airports",
          "description": "The 3-letter IATA airport codes or the airports to filter. Specify multiple values as a comma-separated list.",
          "type": "array",
          "items": {
            "type": "string",
            "enum": ["JFK", "EWR", "LGA", "BOS", "PIT", "PHL", "DCA", "BWI", "IAD"]
          },
          "default": ["IAD", "DCA", "BWI"]
        }
      }
    },
    ...
  ],
  "links": [
    {
      "rel": "self",
      "type": "application/json",
      "title": "This document",
      "href": "https://t18.ldproxy.net/d103_airports/search?f=json"
    }
  ]
}

The Business Client is interested in the first query and retrieves information about the parameters of the query with the following request:

GET /d103_airports/search/elements-by-type-and-airport/parameters HTTP/1.1
Host: t18.ldproxy.net
Accept: application/json

The Filtering Service responds with the list of parameters specified for the query:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "parameters": {
    "collection": {
      "type": "string",
      "enum": ["apronelement", "runwayelement", "taxiwayelement"],
      "default": "runwayelement"
    },
    "type": {
      "type": "string",
      "enum": ["NORMAL", "PARKING", "INTERS", "SHOULD"],
      "default": "NORMAL"
    },
    "airports": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": ["JFK", "EWR", "LGA", "BOS", "PIT", "DCA", "IAD", "BWI", "PHL"]
      },
      "default": [["IAD", "DCA", "BWI"]
    }
  }
}

B.2.4. Business Client executes the selected stored query and retrieves data

With this information, the business client can execute the stored query.

Since the query has default values for all parameters, the simplest query is one without parameter values.

GET /d103_airports/search/elements-by-type-and-airport HTTP/1.1
Host: t18.ldproxy.net
Accept: application/geo+json

The Filtering Service will respond with the normal runway elements of Dulles International Airport:

HTTP/1.1 200 OK
Content-Type: application/geo+json

{
  "type": "FeatureCollection",
  "features": [
    ...
  ]
}

A query with other parameter values can be executed as a GET or a POST request. The apron elements for parking from the three New York area airports will be requested.

First the GET variant:

GET /d103_airports/search/elements-by-type-and-airport?collection=apronelement&type=PARKING&airports=EWR,JFK,LGA HTTP/1.1
Host: t18.ldproxy.net
Accept: application/geo+json

And the POST variant, which will typically be necessary for larger parameter values, e.g. a polygon geometry:

POST /d103_airports/search/elements-by-type-and-airport HTTP/1.1
Host: t18.ldproxy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 57
Accept: application/geo+json

collection=apronelement&type=PARKING&airports=EWR,JFK,LGA

In both cases the Filtering Service will respond with the selected features as a GeoJSON feature collection:

HTTP/1.1 200 OK
Content-Type: application/geo+json

{
  "type": "FeatureCollection",
  "features": [
    ...
  ]
}

Annex C: Revision History

Date Release Editor Primary clauses modified Description

2025-10-25

1.0.0-SNAPSHOT

P. Vretanos

all

initial version

Annex D: Bibliography