Publication Date: 2021-01-13
Approval Date: 2020-12-14
Submission Date: 2020-11-19
Reference number of this document: OGC 20-039r2
Reference URL for this document: http://www.opengis.net/doc/PER/t16-D017
Category: OGC Public Engineering Report
Editor: Robert Gibb, Byron Cochrane, Matthew Purss
Title: OGC Testbed-16: DGGS and DGGS API Engineering Report
COPYRIGHT
Copyright © 2021 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/
WARNING
This document is not an OGC Standard. This document is an OGC Public Engineering Report created as a deliverable in an OGC Interoperability Initiative and is not an official position of the OGC membership. It is distributed for review and comment. It is subject to change without notice and may not be referred to as an OGC Standard. Further, any OGC Public Engineering Report should not be referenced as required or mandatory technology in procurements. However, the discussions in this document could very well lead to the definition of an OGC Standard.
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.
None of the Intellectual Property or underlying information or technology may be downloaded or otherwise exported or reexported in violation of U.S. export laws and regulations. In addition, you are responsible for complying with any local laws in your jurisdiction which may impact your right to import, export or use the Intellectual Property, and you represent that you have complied with any regulations or registration procedures required by applicable law to make this license enforceable.
- 1. Subject
- 2. Executive Summary
- 3. References
- 4. Terms and definitions
- 5. Overview
- 6. DGGS and DGGS Reference System Selection
- 7. DGGS API
- 7.1. Options for DGGS and OGC API
- 7.2. Aligning DGGS to OGC API - Features
- 7.3. Aligning DGGS to OGC API - Process
- 7.4. Implementation in the deliverables
- 7.5. Treatment of geometry
- 7.6. Operations specified for ZoneQuery
- 7.7. OGC API - Features for DGGS description
- 7.8. OGC API - Processes for DGGS description
- 7.9. Is there a need for an OGC API DGGS implementation standard?
- 8. Use Cases
- 9. DGGS Server and API
- 10. DGGS Demo Client
- 11. DGGS Enabled Data Services
- 12. Future Tasks
- 12.1. Maturing DGGS Reference libraries to meet community & future testbed needs
- 12.2. OGC API(s) for DGGS
- 12.3. DGGS processing opportunities
- 12.4. DGGS Analytics - What Does that Really Mean?
- 12.5. The evolution of the OGC DGGS Registry
- 12.6. Opportunities for DGGS API in Interoperability Experiments
- Appendix A: Revision History
- Appendix B: Bibliography
1. Subject
This OGC Testbed-16 Engineering Report (ER) documents the needs and key requirements for drafting an OGC Discrete Global Grid Systems (DGGS) Application Programming Interface (API) standard. The draft DGGS API is defined using the OpenAPI 3.0 specification. The work documented in this ER represents the beginning of a multi-initiative process to fully realize the benefits of standards compliant DGGS implementations and to help drive adoption of DGGS as a key element in advanced Spatial Data Architectures. The Testbed participants investigated a Client-Server DGGS architecture involving one (or more) DGGS Server implementations, DGGS-enabled Data Sources and a simple front-end DGGS Client. DGGS API functionality will be tested using one (or more) simple use case scenarios focusing on the two-way translation between geographic locations and DGGS Zonal Identifiers.
2. Executive Summary
2.1. Background and Expectations of the Testbed-16 DGGS thread
A Discrete Global Grid System (DGGS) represents a spherical partitioning of the Earth’s surface into a grid of cells (or zones) (Wikipedia). The OGC Members approved and maintain an Abstract Specification (AS) that captures the foundational concepts for DGGS (OGC 15-104r5). This Testbed task aims to begin the process to move towards an OGC Implementation Standard for DGGS through the creation of open-source DGGS reference implementations. Testbed-16 represents the initial effort of what is considered a multi-initiatives process.
DGGS offer a new way for geospatial information to be stored, visualized, and analyzed. Based on a partitioning of the Earth’s surface into a spherical grid, DGGS allows geospatial information to be represented in a way that more intuitively reflects relationships between data and the Earth’s surface. With DGGS, providers and consumers of geospatial information can eliminate many of the uncertainties and distortions inherently present with traditional coordinate systems. To fully realize the benefits of DGGS, standard-compliant implementations are required to allow zone-ID management across DGGS with varying structure and alignment.
DGGS presents an opportunity for the geospatial community to implement a representation of Earth that is vastly different from traditional coordinate system based approaches. DGGS has the potential to enable storage, analysis and visualization of geospatial information in a way that more accurately reflects the relationship between data and the Earth. While the OGC DGGS Abstract Specification captures fundamental DGGS concepts, the Testbed-16 DGGS thread initiated work to more concretely demonstrate DGGS in order to drive adoption. This includes advancement towards development of a DGGS reference implementation.
Key questions addressed by the work include:
-
What DGGS structure would be best for developing a reference implementation? For example, Uber’s Hexagonal Hierarchical Spatial Index or the Open Equal Area Global Grid (OpenEAGGR)
-
What is a simple application that could be used to demonstrate the value of the reference implementation?
-
What should be considered for future work oriented towards operational implementation of DGGS?
2.2. Summary of work undertaken
The participants in the Testbed-16 DGGS thread approached these questions by:
-
Undertaking a review of what is needed from a DGGS library (DGGS and DGGS Reference System Selection) and introducing new terminology (Terms and definitions) to distinguish the different roles DGGS libraries can perform.
-
Undertaking a review of existing open-source DGGS libraries against these roles and selecting two for use in the Testbed (DGGS and DGGS Reference System Selection).
-
Uber’s H3 library
-
Manaaki Whenua’s rHEALPix library
-
-
Identifying candidate Use Cases, ideally that were both aligned with other Testbed-16 threads, and achievable with the current DGGS libraries and resources available to participants. (Use Cases)
-
Identifying which OGC API would best demonstrate DGGS (DGGS API)
-
Defining DGGS variants of OGC API - Features (OGC API - Features for DGGS description) and OGC API - Processes (OGC API - Processes for DGGS description).
-
Developing server implementations and standing up server instances of each API:
-
OGC API - Features (DGGS Enabled Data Services) as a native DGGS server,
-
OGC API - Records (DGGS Enabled Data Services) as a discovery mechanism for the feature services, and
-
OGC API - Processes (DGGS Server and API) on a native DGGS datastore wrapped by GeoServer.
-
-
Populating each server with data covering the Australian Capital Territory (ACT) appropriate for the final Use Case.
-
DGGS native data for Australian Statistical Area polygons and River Catchment polygons served through OGC API - Features (DGGS Enabled Data Services), and
-
DGGS native Sentinel 2 data and processes to generate NDVI, NDBI & NDWI and band statistics served through OGC API - Processes (DGGS Server and API).
-
-
Developing native DGGS desktop and Jupyter Notebook demonstration clients to interact with the two API (DGGS Demo Client).
-
Exercising Jupyter Notebook client against the servers to show the Use Case in action.
-
Mapping the Testbed-16 Data Access and Processing API (DAPA) onto the DGGS OGC API - Processes, to demonstrate a DGGS variant of the Testbed-16 DAPA (GeoServer DGGS based DAPA API).
-
Reviewing participants experiences to assemble and prioritise recommendations for future work (Future Tasks).
2.3. Highlights from the Testbed-16 participants
Although DGGS implementations have been deployed in previous testbeds, this was the first time that a DGGS thread has appeared in an OGC Testbed. As a consequence, there were widely differing expectations both across the participants and between the participants and the sponsors. However, once all the participants had gained a common understanding of DGGS, progress was remarkably fast and a lot simpler than was anticipated.
Key highlights from this effort include:
-
Implementation of DGGS as a collection of virtual vector layers, allowing users to easily access various DGGS resolutions through formats best suited to their needs.
-
Demonstration of the ability of DGGS to incorporate widely used OGC standard services, allowing organizations to leverage past data and infrastructure investments in a new way.
-
Fast development of a robust Earth observation-oriented application, demonstrating the ability of DGGS to quickly and simply enable forms of analysis that are highly complex undertakings with traditional geospatial analysis techniques.
Both server implementations adopted a common strategy of wrapping the chosen DGGS libraries into their systems to present the DGGS Reference System (RS) as a collection of virtual vector layers. Each layer (or item in the collection) corresponds to a level of the DGGS RS grid hierarchy. In both API implementations this allowed the client to select whether it wanted a GeoJSON or a JSON payload. With the GeoJSON payload, the DGGS library created the necessary coordinates for each zone on-the-fly. With the JSON payload, a native DGGS geometry was supplied comprised only of DGGS zone-IDs (the unique identifier associated with each zone ).
For the GeoServer OGC API - Processes implementation this means that all the native GeoServer vector processing functionality, and all the existing GeoServer services - such as OGC WMS and OGC WFS - are exposed to traditional GeoServer clients to use DGGS data. A single GeoServer DGGS wrapper library was created to deliver both H3 and rHEALPix solutions. The no-SQL database ClickHouse was chosen as the GeoServer backend datastore for the DGGS data. This proved very fast for delivering Sentinel 2 data and generating both statistical summaries and index calculations (e.g. NDVI, NDBI & NDWI) on Sentinel 2 data. In the backend ClickHouse datastore, the DGGS zone ID was the primary index for the pixels of Sentinel 2 data.
In the OGC API - Features implementation, a linked data approach was taken using an Resource Description Framework (RDF) datastore. This proved very successful and this Testbed experience is already feeding into the OGC GeoSPARQL Standard roadmap. Vector data for Australia’s Level 1 Statistical Meshblocks and Hydrological Catchments were converted to DGGS RDF data with the DGGS Cell-ID as the predicate (i.e primary index) for the data. The OGC API - Features end-point presented this data as either JSON Linked Data (JSON LD) - using the DGGS zone -ID as the only representation of geometry, or as GeoJSON with the DGGS library generating vector geometries on-the-fly as required.
Participants started with an expectation that the Testbed-16 thread would deliver 'a simple application'. That participants were able to stand up an application delivering native DGGS vector and earth observation capability to users of both traditional Geographic Information Systems (GIS) clients and to native DGGS clients reinforced the versatility of DGGS and underscored its promise to deliver rapid multi-disciplinary analyses. Systems based on DGGS have been shown to have the characteristics of a chameleon that can acquire the character of both vector GIS systems and of earth observation systems. This means that both raster and vector data can be served through either raster or vector or DGGS native services. In its native form, DGGS also offer additional analytical versatility that is not present in either of these.
2.4. Overview of recommendations
Testbed participants documented future tasks in the following areas:
-
Maturing DGGS Reference Library Implementations to bring them into conformance with OGC Topic 21 v2.0 (Maturing DGGS Reference libraries to meet community & future testbed needs);
-
Drafting and elaboration of OGC APIs for DGGS (OGC API(s) for DGGS);
-
Exploring the opportunities and limitations of DGGS driven analytics (DGGS processing opportunities);
-
Implementation of OGC Registries for DGGS Implementations and DGGS enabled data services (The evolution of the OGC DGGS Registry);
-
Targeted DGGS Interoperability Experiments (Opportunities for DGGS API in Interoperability Experiments).
2.5. Document contributor contact points
All questions regarding this document should be directed to the editor or the contributors:
Contacts
| Name | Organization | Role |
|---|---|---|
Byron Cochrane |
OpenWork Ltd |
Editor |
Robert Gibb |
Manaaki Whenua Landcare research |
Editor |
Matthew Purss |
Pangaea Innovations Pty. Ltd. |
Editor |
Adrian Cochrane |
OpenWork Ltd |
Contributor |
Nicholas J. Car |
SURROUND Australia Pty Ltd |
Contributor |
Andrea Aime |
GeoSolutions S.A.S. |
Contributor |
2.6. Foreword
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 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.
3. References
The following normative documents are referenced in this document.
-
OGC: Topic 21: Discrete Global Grid Systems Abstract Specification
-
OGC: Draft Topic 21 v2 - Discrete Global Grid Systems - Part 1 Core Reference system and Operations and Equal Area Earth Reference System abstract Specification
OGC Topic 21 v2 is identical in normative content to N5348 ISO/DIS 19170-1, whose DIS Ballot was approved on 2020-Oct-10 with only minor editorial comments. -
OGC: Draft OGC API - Common - Part 1: Collections | Geospatial Data
-
Open Geospatial Consortium (OGC): OGC 17-069r3: OGC API - Features - Part 1: Core [online]. Edited by C. Portele, P. Vretanos, C. Heazel. Available at http://www.opengis.net/doc/IS/ogcapi-features-1/1.0
-
OGC: Draft OGC API - Features - Part 2: Coordinate Reference Systems by Reference
-
OGC: Draft OGC API - Features - Part 3: Common Query Language
-
Internet Engineering Task Force (IETF): RFC 7946: The GeoJSON Format [online]. Edited by H. Butler, M. Daly, A. Doyle, S. Gillies, S. Hagen, T. Schaub. 2016 [viewed 2020-03-16]. Available at http://tools.ietf.org/rfc/rfc7946.txt
-
Open Geospatial Consortium (OGC): OGC 10-100r3: Geography Markup Language (GML) Simple Features Profile [online]. Edited by L. van den Brink, C. Portele, P. Vretanos. 2012 [viewed 2020-03-16]. Available at http://portal.opengeospatial.org/files/?artifact_id=42729
-
Open Geospatial Consortium (OGC): OGC 06-103r4: OpenGIS Implementation Standard for Geographic information - Simple feature access - Part 1: Common architecture [online]. Edited by John R. Herring. 2011 [viewed 2020-11-05]. Available at https://portal.ogc.org/files/?artifact_id=80428
-
Open Geospatial Consortium (OGC): OGC 09-025r2: OGC® Web Feature Service 2.0 Interface Standard – With Corrigendum [online]. Edited by Panagiotis (Peter) A. Vretanos. 2014 [viewed 2020-11-05]. Available at http://docs.opengeospatial.org/is/09-025r2/09-025r2.html
4. Terms and definitions
For the purposes of this report, the definitions specified in Clause 4 of the OWS Common Implementation Standard OGC 06-121r9 shall apply. In addition, the following terms and definitions apply.
- ● Coordinate operation
-
A process using a mathematical model, based on a one-to-one relationship, that changes coordinates in a source CRS to coordinates in a target CRS, or that changes coordinates at a source coordinate epoch to coordinates at a target coordinate epoch within the same CRS.
SOURCE: ISO 19111:2019 Referencing by coordinates
- ● Coordinate conversion
-
A coordinate operation that changes the coordinates in a source CRS to coordinates in a target CRS based on the same datum.
Note 1 to this entry This does not represent a change to the coordinates of the described feature, but rather a different representation of the same coordinate.
Source: SOURCE: ISO 19111:2019 Referencing by coordinates
- Examples
-
-
Change Geographic coordinates (Latitude and Longitude) to Map Projection (Easting and Northing)
-
Change units from feet to meters
-
- ● Coordinate transformation
-
A coordinate operation that changes coordinates in a source CRS to coordinates in a target CRS in which the source and target CRS are based on different datums.
SOURCE: ISO 19111:2019 Referencing by coordinates
- Examples
-
-
Change from GDA94 to GDA2020
-
Change from AMG66 to MGA94
-
- ● DGGS RS
-
'DGGS Reference System' a Reference system using zonal identifiers with structured geometry as described by the UML diagram in Figure 1
- ● DGGS RS provider (DGGS RS provider service)
-
Software library that processes DGGS RS definitions to create zonal identifiers and define their geometry.
- Notes
-
-
a DGGS RS provider may be able to be used iteratively to provision a complete DGGS RS.
-
a DGGS RS provider service is a DGGS RS provider set up to operate in a web service architecture.
-
most DGGS software libraries available today are at the very least DGGS providers
-
none of the DGGS provider libraries identified in our stock-take (Table 1) support DGG_ReferenceSystem or MD_ReferenceSystem. 19170-1 is establishing a template/benchmark for what should happen.
-
- Example
-
-
DGGRID is a DGGS RS provider that needs to be used iteratively to provision a complete DGGS RS, and
-
DGGRID is a command line library that would need further configuration to operate as a DGGS RS provider service.
-
- ● DGGS RS navigator (DGGS RS navigator service)
-
Software library that processes topological queries based solely on 'ZonalIdentifiers' as specified by the 'DGGS Core::ZoneQuery' interface.
- Notes
-
-
a DGGS RS navigator service is a DGGS RS navigator set up to operate in a web service architecture.
-
Normal geometry operations: since a Cell has the behavior of Geometry as specified in ISO 19107, Cell.representativePoint and 'Cell.boundary` would be supported. For example:
-
if A and B are both ZonalIdentifiers then the DGGS RS navigator operation A.contains(B) returns a boolean.
-
Other operations in zoneQuery include all the DE-9IM operators as well as parent, child, sibling, parentOf, childOf, siblingOf and two 1D operators relativePositon and relatePosition.
-
ZoneQuery also supports operations spanning a specified number of refinement levels. So effectively queries involving grandchildren, cousins once removed etc can all be processed by adding a levels parameter to the child, sibling etc.
-
-
- Examples
-
-
rHEALPix is a DGGS RS navigator as well as a DGGS RS provider.
-
H3 is also a DGGS RS navigator as well as a DDGS RS provider.
-
DGGRID is not a DGGS RS navigator.
-
In both libraries the navigator functions would need a wrapper to comply with the nomenclature and syntax in ZoneQuery.
-
- ● DGGS datastore
-
persistent storage for observation values assigned to zonal identifiers
- Notes
-
-
each DGGS RS specifies a single geometry for their zones (cells).
-
all geometry types present in non-DGGS systems map onto collections of DGGS zones (cells).
-
there are three forms that collections of zones can take: single zone, arrays of zones, and ordered arrays of zones, where the ordering indicates a zone connectivity.
-
each element of a collection is a ZonalIdentifier.
-
- ● DGGS RDF datastore
-
storage uses ZonalIdentifiers as subject or object to represent a region of space-time and RDF predicates to associate the ZonalIdentfer(s) with observation values
- ● DGGS array datastore
-
observation values are stored using arrays in which the array is sorted by ZonalIdentifier, and may therefore define a function that relates ZonalArray offsets to array index
- ● DGGS raster datastore
-
observation values are stored as an image type sorted by lat,long (eg geotiff) and a function is defined to relate ZonalIdentifier with d/d-lat, d/d-long zone spacing
- ● DGGS analytics system
-
service providing spatial analysis of observations stored in a DGGS datastore
- ● DGGS quantization service
-
import process for converting observation data from non-DGGS format to DGGS format
- Note
-
See OGC Topic 21 v2.0 Part 1 standard for detail
- ● DGGS Query/Broadcast Service
-
export process of converting DGGS format data to non-DGGS format
- Note
-
See OGC Topic 21 v2.0 Part 1 standard for detail
- ● DGGS API
-
APIs to implement each of the above.
- ● trie
-
ordered tree data structure used to store a dynamic set or associative array where the keys are usually strings.
- Note
-
Unlike a binary search tree, no node in the tree stores the key associated with that node; instead, its position in the tree defines the key with which it is associated; i.e., the value of the key is distributed across the structure. All the descendants of a node have a common prefix of the string associated with that node, and the root is associated with the empty string. Keys tend to be associated with leaves, though some inner nodes may correspond to keys of interest. Hence, keys are not necessarily associated with every node. For the space-optimized presentation of prefix tree, see compact prefix tree.
- Note
- ● zone
-
region of space-time
- Note
-
In DGGS the zone is the fundamental unit of space-time. Each zone has a unique zonal identifier (ZoneID), and the zonal identifier has a defined position in a base CRS. The zone has geometry represented by a cell, and like all geometry, the cell has topology. Best practice is for the zonal identifier to be an encapsulation of both position and topology. The distinction between cell and zone was introduced in OGC Topic 21 v2.0 Part 1 both to encompass any spatio-temporal dimensionality, including 2D, 2D+Time, 3D & 3D+Time and to distinguish between the region and its geometry. See OGC Topic 21 v2.0 Part 1 standard for more detail.
- Note
-
cell and cell ID, are only used in this document when referring to specific objects, classes or functions in existing software implementations.
4.1. Abbreviated terms
-
API Application Programming Interface
-
AusPIX Australian rHEALPix Reference System
-
CFP Testbed-16Call For Participation
-
DAPA Testbed-16 Data Access and Processing API for Geospatial Data
-
DGGS Discrete Global Grid System
-
GIS Geographic Information System
-
H3 Uber’s Hexagonal Hierarchical Spatial Index
-
HDF5 Hierarchical Data Format v5
-
JSON JavaScript Object Notation
-
OLAP Online analytical Processing
-
rHEALPix rearranged Hierarchical Equal Area iso-Latitudinal Pixelisation
-
TB-16 Testbed-16
-
TB16Pix Testbed-16 rHEALPix Reference System
-
URI Universal Resource Identifier
-
UTM Universal Transverse Mercator
5. Overview
Preface - provides the required Preface information such as copyright, warnings and license agreement.
Subject - introduces DGGS in the context of the TB-16 experiment.
Executive Summary - provides the Executive Summary of this report.
References - lists all normative references relevant to the outcomes of this experiment.
Terms and definitions - lists the key terms and definitions relevant to this report.
Overview - (this document) provides an overview and extended Table of Contents of this report.
DGGS and DGGS Reference System Selection - discusses the key criteria and justification for the selection of the DGGS libraries and associated DGGS Reference Systems used in this experiment.
DGGS API - discusses the context and API options for the DGGS thread and the definitions of the Features and Processes APIs that have been deployed.
Use Cases - presents and discusses the Use Cases employed to demonstrate the value of DGGS in the context of this experiment.
DGGS Server and API - presents and discusses the implementation of the DGGS Server, OGC API - Features endpoint, and the preparation of the data served for this experiment.
DGGS Demo Client - presents and discusses the implementation of the DGGS Client used in this experiment.
DGGS Enabled Data Services - presents and discusses the implementation of the DGGS-enabled Data Server, OGC API - Processes endpoint, and the preparation of the data served for this experiment.
Future Tasks - discusses Future Tasks and Activities that need to be undertaken to support the standardized implementation of DGGS and services that implement the DGGS API.
6. DGGS and DGGS Reference System Selection
6.1. Semantics for DGGS libraries and their association with the current DGGS draft standards
The new draft DGGS Abstract Specification (OGC Topic 21 v2.0 / ISO/DIS 19170-1) defines 1.) a DGGS Reference system as 'referencing by zonal identifiers with structured geometry', and 2.) a DGGS as a holistic system comprising:
-
A DGGS Reference system (DGGS RS);
-
A suite of DGGS Functions for:
-
Quantizing data against the DGGS RS,
-
Querying the topology of zones in a DGGS RS, and
-
Interoperating with traditional W*S and OGC API systems.
-
Most existing DGGS libraries pre-date the new draft Abstract Specification (AS) and as a consequence they only partially fulfil the requirements of the draft AS. Furthermore, they are not structured neatly into modules that follow the above pattern. This has created confusion as to what comprises a DGGS. As such participants in this thread held diverse views of what constituted a DGGS. As the diversity was explored the need for some additional concepts or terms that reflected the different roles that a library might play in DGGS were identified. The participants also identified that some existing libraries supported a single DGGS RS, while others supported whole families of DGGS RSs. An analogy might be the difference between a library that locked in the Universal Transverse Mercator (UTM) Zones 3 projection as compared to a library that supports Transverse Mercator projections. With appropriate configuration parameters the library can support any UTM Zone - including UTM Zone 3. Following the structure outlined above, the participants distinguished between libraries that were DGGS RS providers - and those that were DGGS RS navigators.
6.1.1. DGGS RS provider
Providers support either a single DGGS RS, or configuration tools that can be used to support a family of similar DGGS RSs. For the DGGS RSs that they support, providers can generate ZoneIds and their associated geometry.
6.1.2. DGGS RS navigator
Navigators support the topological queries on zones based on ZoneIds. These are the usual Dimensionally Extended 9-Intersection Model (DE-9IM) functions such as within, overlap, contains etc.
6.2. The question of DGGS data
Early in the discussion between participants, the question was raised as to whether there was such a thing as DGGS data, and if there were, what would a DGGS datafile look like? For anybody coming into DGGS from a traditional GIS background, and thinking in terms of DGGS as a reference system, the obvious answer was no. For example, concepts such as World Geodetic System 1984 (WGS84) data or UTM 3 data have very little meaning. On the other hand, those participants heavily involved in DGGS thinking were convinced that DGGS data was a very real thing. Thinking about spatial data is typically in terms of its storage, and storage design is intimately bound to the form of the geometry being stored — Shapefiles, HDF5, GeoJSON, LASer (LAS) formatted files — are all solutions to the needs of storing geometries. Traditional reference systems are independent of geometry, and as a consequence the choice of reference systems is independent of the choice of data format.
By contrast, DGGS reference systems define their own geometry. This geometry is implied by the ZoneID. So, within a DGGS a geometry does not need to be explicitly provided as coordinates, and therefore does not need to be encoded in a traditional spatial data format. Instead, DGGS data only needs to record the ZoneId(s) associated with the feature, observation, or raster data zone (cell). This is very much like any other unique identifier associated with a list of attributes, and so DGGS data can be stored in many typical datastores. What makes it spatial data is the presence of the DGGS RS’s navigator functions that perform spatial topology operations using the ZonalID(s) in lieu of coordinate geometry. As a consequence, explicit read/write support for DGGS data in a DGGS library is not required. What is expected is handling of the quantization roles that are defined by the draft OGC DGGS Abstract Specification. These roles tell us the geometric relationship between a record and a ZoneId. They include a single coordinate (the zone centroid), or an area (enclosed by the zone’s boundary), or a tile.
6.3. DGGS libraries
A stock-take of DGGS libraries was performed and the following are the libraries found.
| Name | Author | Cell geom | Docs | Repo | Lang. Bind | License | DGGS RS prov.* | Quant.* | DGGS RS nav.* | Interop.* |
|---|---|---|---|---|---|---|---|---|---|---|
DGGrid |
hex or tri |
C++ cmd-line |
Y (config) |
N |
N |
N |
||||
DGGridR (wrapper to use DGGrid in R) |
hex or tri |
R, C++ |
Y (config) |
Y |
N |
N |
||||
H3 (built on DGGrid) |
Uber |
hex |
C, java |
Y |
N |
Y |
N |
|||
OpenEAGGR |
DSTL(UK) & RiskAware |
tri or hex |
C |
Y (config) |
N |
N |
N |
|||
rHEALPix |
quad |
python |
CC-BY 4.0 & LPGL for original code |
Y (config) |
N |
Y |
N |
|||
AUSPix (implementation of rHEALPix) |
GA & CSIRO |
quad |
python |
CC-BY 4.0 & LPGL for original code |
Y |
Y |
Y |
N |
||
PYXIS |
Perry Peterson Global Grid Systems |
hex |
n/a |
commercial product |
Y |
Y |
Y |
Y |
||
TerraNexus |
Matthew Purss, Pangaea Innovations Pty. Ltd. |
quad & tri |
n/a |
python |
commercial product |
Y |
Y |
Y |
Y |
|
… (add others here) |
|
Note
|
* None of the libraries implements complete functionality in any of the four categories. Therefore the use of 'Y' in these columns indicates partial fulfilment. However, for the proposed purposes of TB-16 DGGS thread any gaps are trivial. |
6.4. DGGS Libraries selected by the Testbed-16 DGGS thread
To demonstrate that the DGGS work undertaken was applicable to multiple DGGS, the decision was made to implement two DGGS, and the libraries chosen were H3 and rHEALPix.
-
H3: Use of H3 is resulting in the development of a significant user community and as a consequence H3 is the most mature in the sense of formal releases and bindings.
-
rHEALPix: Being used as AusPIX by the Australian Government’s Loc-I project. Also TB-16 thread participants were be able to pick up some of the additional code developed for AusPIX.
6.5. DGGS Reference systems selected by the Testbed-16 DGGS thread
H3 only supports one DGGS RS, so there are no further parameter choices to be made. The H3’s reference system is referred to as H3RS.
rHEALPix provides a number of hard-coded references systems, such as for covering spherical vs ellipsoidal earth models. For example, AusPix uses the default hard-coded WGS84 ellipsoidal reference system based on the zero meridian. Since Testbed-16 is developing solutions that may be demonstrated in a number of continents, the decision was made to choose a rotated version of the WGS84 that places all the corners of the initial cube in the sea. This reduces the area of land covered by the most distorted zones. This reference system as TB16Pix.
The code to provide TB16Pix, print the definition and export zone centers and edges for visualization in Google Earth is:
from rhealpix_dggs.projection_wrapper import *
from rhealpix_dggs.dggs import *
from rhealpix_dggs.ellipsoids import *
# define our WGS84 ellipsoid rotated so that all the corners of the cube lie in water
WGS84_TB16 = Ellipsoid(a=6378137.0, b=6356752.314140356, e=0.0578063088401, f=0.003352810681182, lon_0=-131.25)
# create our DGGS RS based on the defined ellipsoid
TB16Pix = RHEALPixDGGS(ellipsoid=WGS84_TB16, north_square=0, south_square=0, N_side=3)
# fyi print out the definition in full
print(TB16Pix)
# fyi print out the coordinates of the corners and centres of the cube's faces,
# note that the rHEALPix code doesn't support direct query of the top level zones,
# so appropriate children are used
c = TB16Pix.cell(('O', 0)); print(my_round(c.nw_vertex(plane=False),9)) # Caspian Sea
c = TB16Pix.cell(('P', 0)); print(my_round(c.nw_vertex(plane=False),9)) # Sea of Japan
c = TB16Pix.cell(('Q', 0)); print(my_round(c.nw_vertex(plane=False),9)) # NW Pacific Coast
c = TB16Pix.cell(('R', 0)); print(my_round(c.nw_vertex(plane=False),9)) # Nth Atlantic
c = TB16Pix.cell(('O', 6)); print(my_round(c.vertices(plane=False)[3],9)) # Indian Ocean
c = TB16Pix.cell(('P', 6)); print(my_round(c.vertices(plane=False)[3],9)) # Australian Bight
c = TB16Pix.cell(('Q', 6)); print(my_round(c.vertices(plane=False)[3],9)) # Sth Pacific
c = TB16Pix.cell(('R', 6)); print(my_round(c.vertices(plane=False)[3],9)) # Sth Atlantic
c = TB16Pix.cell(('N', 4)); print(my_round(c.nucleus(plane=False),3)) # N - Nth Polar face
c = TB16Pix.cell(('O', 4)); print(my_round(c.nucleus(plane=False),3)) # O - Oriental face
c = TB16Pix.cell(('P', 4)); print(my_round(c.nucleus(plane=False),3)) # P - Pacific face
c = TB16Pix.cell(('Q', 4)); print(my_round(c.nucleus(plane=False),3)) # Q - Americas face
c = TB16Pix.cell(('R', 4)); print(my_round(c.nucleus(plane=False),3)) # R - Africa face
c = TB16Pix.cell(('S', 4)); print(my_round(c.nucleus(plane=False),3)) # S - Sth Polar face
As illustration the corners of the northern and southern zones are shown in the next two figures:
| TB16Pix Zone N corners | TB16Pix Zone S corners |
|---|---|
7. DGGS API
7.1. Options for DGGS and OGC API
The participants had considerable discussions about the context in which an API that talked DGGS would be used. A couple of issues were central to the discussion:
-
DGGS RS provides geometry, and the geometry is encoded in the ZoneID. So, a true DGGS API does not need to exchange geometry in the form of coordinates, whereas OGC API - Features is built on the presumption that geometry will always be exchanged.
-
DGGS RS provide a series of successively finer Zone resolutions. Each resolution represents a defined level of known spatial precision. However, OGC API - Features has no concept of spatial precision, so some form of automatic assignment of spatial precision may be required.
The alternative contexts discussed were:
-
A DGGS client calling a DGGS server — both understand what a ZoneID represents:
-
Client and server using the same DGGS RS — no ZoneID conversion required.
-
Client and server using different DGGS RS — ZoneID conversion or negotiation required.
-
-
A DGGS client calling an OGC API - Feature server or an OGC API - Processes server:
-
DGGS client understands how to generate a ZoneID’s coordinate geometry for the API — Server does not need to understand DGGS ZoneID.
-
Server understands how to interpret ZoneID — Client does not need to generate a ZoneID’s geometry.
-
There was also discussion about whether to implement an API that conforms to OGC API - Features or OGC API - Process. While OGC API - Features would be useful for allowing people to browse a DGGS and has clarity of meaning, it would also potentially be very chatty in use for analytics (i.e. a potentially very large amount of data, in the form of JSON documents, being transferred either as very large OGC API - Features collection documents, or many transactions of individual OGC API - Features documents for each feature of a collection). By comparison OGC API - Processes is relatively opaque, but fits very well with the DGGS premise that DGGS are particularly suited to Big Data applications where processing should be passed to the data. This is as opposed to the case in which features are passed to the client for processing.
7.2. Aligning DGGS to OGC API - Features
|
Note
|
Intended content
This section will discuss the way that DGGS map onto collections and features in OGC API - Features. |
7.3. Aligning DGGS to OGC API - Process
For an API that is a profile of the draft OGC API - Process, the basic resources "are" Processes. Any particular API and API implementation offers particular processes or process types, organizes them in characteristic structures, and supports returning particular representations. The most common representations will be 1) descriptions of the processes, or 2) the result of a process "job" invoked by a request.
What really makes an API, though, is how those resources are organized. The trend with OGC API - Processes (via GET operations) is to group processes according to the primary dataset that they act on, what might be termed the process "affordance". This matches up well with the draft OGC API - Common pattern of dividing resources into collections. Depending on whether a hierarchical organization is supported, each collection is either a collection of collections, or a dataset composed of data elements. The sleight of hand, though, is that a dataset in a Processes API is not a target resource, but a means of organizing processes that are able to act on it.
What makes sense is that a DGGS be thought of as a dataset, with or without data properties, that organizes retrieval, linking, and processing types. The dual nature of a DGGS as both a processing engine and a dataset/collection of geometry objects creates flexibility in the way an OGC API for DGGS could be structured as:
-
system first (e.g.
/ogcapi/dggs/{DGGS_RS_ID}/processes/…,/ogcapi/dggs/{DGGS_RS_ID}/collections/…, etc…), or -
data first (e.g.
/ogcapi/collections/{collectionID}/dggs/{DGGS_RS_ID}/…,/ogcapi/processes/{processID}/dggs/{DGGS_RS_ID}/…, etc…).
These concepts require more elaboration during subsequent OGC standards development and/or OGC Innovation Program activities to standardize the concept of an OGC API for DGGS.
7.4. Implementation in the deliverables
As a result of these discussions the decision was made to implement DGGS in the context of two distinct APIs.
-
D139 an OGC API - Features oriented API hosted by a DGGS Server that could support both a native DGGS client, in this case the D138 Demo Client, and an OGC API - Features client that needs the geometry to be provided. The server would provide DGGS Zones as Features without data. The server would deliver some DGGS data layers, delivered either as DGGS Zones using their ZonalIds or as traditional Features using each zone’s coordinate geometry.
-
D137 an OGC API - Processes server would be built inside GeoServer. The API instance would perform a selection of ZoneQuery operations on DGGS Zones.
7.5. Treatment of geometry
Acknowledging the conundrum of how to deliver geometry, the following strategy is being used by both API implementations:
-
DGGS RS were treated as if they were a collection of feature datasets, with each level of the DGGS zone hierarchy corresponding to an item in the collection This approach provided an elegant solution to the association of geometry with a ZoneId.
-
While each DGGS RS is presented as a (collection of) datasets, in the first instance the datasets were generated on the fly as required. This was achieved by embedding the library in the server.
-
The client chooses how to receive geometry be specifying its desired protocol. For example, specifying GeoJSON results in geometry presented as traditional coordinates according to the GeoJSON specification, while specifying JSON results in geometry being passed encoded in the ZoneID on the presumption that the client does not need the coordinates.
-
Both the OGC Features and Processes APIs were designed to support all the functions specified by ZoneQuery (c.f. Table 3). However only a subset was implemented in this Testbed. In the OGC API - Features implementation, the default representation of each Zone included reference to parents, siblings and children - all generated on-the-fly. The OGC API - Processes implementation offered those same functions as processes.
7.6. Operations specified for ZoneQuery
These are the operations defined in OGC Topic 21 Part 1 v2.0 and ISO 19170-1 Core for ZoneQuery.
| Name: | ZoneQuery | |||||
|---|---|---|---|---|---|---|
Definition: |
ZoneQuery redefines the DE-9IM operations in Query2D, Query3D and provides relativePosition and relatePosition operations for the topology of zones. |
|||||
Stereotype: |
Interface |
|||||
Abstract: |
true |
|||||
Associations: |
(none) |
|||||
Public attributes: |
Name |
Definition |
Derived |
Obligation |
Maximum occurence |
Data type |
boundary |
boundary of the combined spatial geometries of the zones in the query |
true |
M |
1 |
Geometry |
|
boundaryType |
boundary type of the combined spatial geometries of the zones in the query |
M |
1 |
BoundaryType |
||
convexHull |
convex hull of the combined spatial geometries of the zones in the query |
true |
M |
1 |
Geometry |
|
Operations: |
Name |
Parameters:ParameterType |
Return type |
Definition |
||
distance |
(another:ZonalIdentifier, projectTo:DirectPosition[4])) |
Distance |
A.distance(B) |
|||
<<query>> (1D) |
relativePosition |
(another:ZonalIdentifier, projectTo:DirectPosition[4]) |
RelativePosition |
A.relativePosition(B,(0,0,0,1)) |
||
<<query>> |
contains |
(another:ZonalIdentifier, projectTo:DirectPosition[4]) |
Boolean |
A.contains(B) ⇔ A⊇B |
||
crosses |
(another:ZonalIdentifier, projectTo:DirectPosition[4]) |
Boolean |
A.crosses(B) |
|||
disjoint |
(another:ZonalIdentifier, projectTo:DirectPosition[4]) |
Boolean |
A.disjoint(B) ⇔ A∩B=0 |
|||
equals |
(another:ZonalIdentifier, projectTo:DirectPosition[4]) |
Boolean |
A.equals(B) ⇔ A=B |
|||
intersects |
(another:ZonalIdentifier, projectTo:DirectPosition[4]) |
Boolean |
A.intersects(B) ⇔ A∩B≠0 |
|||
overlaps |
(another:ZonalIdentifier, projectTo:DirectPosition[4]) |
Boolean |
A.overlaps(B) |
|||
touches |
(another:ZonalIdentifier, projectTo:DirectPosition[4]) |
Boolean |
A.touches(B) |
|||
within |
(another:ZonalIdentifier, projectTo:DirectPosition[4]) |
Boolean |
A.within(B) ⇔ B.contains(A) |
|||
withinDistance |
(another:ZonalIdentifier, dist:Distance, projectTo:DirectPosition[4]) |
Boolean |
A.withinDistance(B) ⇔ A.distance(B)<dist |
|||
parentOf |
(another:ZonalIdentifier, inheritID:Boolean, projectTo:DirectPosition[4]) |
Boolean |
A.parentOf(B) |
|||
childOf |
(another:ZonalIdentifier, inheritID:Boolean, projectTo:DirectPosition[4]) |
Boolean |
A.childOf(B) |
|||
siblingOf |
(another:ZonalIdentifier, inheritID:Boolean, projectTo:DirectPosition[4]) |
Boolean |
A.siblingOf(B) |
|||
<<set>> |
buffer |
(dist:Distance, projectTo:DirectPosition[4]) |
ZonalIdentifier |
A.buffer(dist) |
||
difference |
(another:ZonalIdentifier, rangeRefine:refinementLevelRange, projectTo:DirectPosition[4]) |
ZonalIdentifier |
A.difference(B) ⇔ A-B |
|||
intersection |
(another:ZonalIdentifier, rangeRefine:refinementLevelRange, projectTo:DirectPosition[4]) |
ZonalIdentifier |
A.intersection(B) ⇔ A∩B |
|||
symDifference |
(another:ZonalIdentifier, rangeRefine:refinementLevelRange, projectTo:DirectPosition[4]) |
ZonalIdentifier |
A.symDifference(B) ⇔ (A-B)∪(B-A) |
|||
union |
(another:ZonalIdentifier, rangeRefine:refinementLevelRange, projectTo:DirectPosition[4]) |
ZonalIdentifier |
A.union(B) ⇔ A∪B |
|||
parent |
(inheritID:Boolean, levels:Integer, projectTo:DirectPosition[4]) |
ZonalIdentifier |
A.parent(B) |
|||
child |
(inheritID:Boolean, levels:Integer, projectTo:DirectPosition[4]) |
ZonalIdentifier |
A.child(B) |
|||
sibling |
(inheritID:Boolean, levels:Integer, projectTo:DirectPosition[4]) |
ZonalIdentifier |
A.sibling(B) |
|||
<<reference>> (1D) |
relatePosition |
(another:ZonalIdentifier, relate:RelativePosition, projectTo:DirectPosition[4]) |
Boolean |
A.relatePosition(B,enum,(0,0,1,0)) |
||
<<reference>> |
relate |
(another:ZonalIdentifier, matrix:CharacterString, projectTo:DirectPosition[4]) |
Boolean |
A.relate(B,matrix) |
||
Constraints: |
(none) |
|||||
7.7. OGC API - Features for DGGS description
Addressing the Call for Participation (CFP) clause D139 DGGS Enabled Data Services, the OGC API - Features implementations for DGGS datasets should support:
-
"Cell IDs as spatial filters"
-
"Converting Cell IDs to geographic filters"
-
"Cell ID(s) to geographic location conversion"
The specifics of these implementations are documented in the next section.
7.7.1. API Features implementation
A new OGC API framework was created for this project called OGC LD API. This is based on the fact that the framework uses Linked Data mechanics to provide both OGC API and other API functionality. The implementations based on this framework pass many of the OGC API - Features tests (Abstract Tests and Requirements) with the intention being that all tests will pass in future versions of the framework.
To test the implementations against the OGC API - Features Abstract Tests and Requirements, a testing client was also developed. For this Testbed, the client was called the OGC API LD Test Client ("the TC"). This client implemented not only the Abstract Tests and Requirements of OGC API - Features but also tested lists in the Content Negotiation by Profile specification for Linked Data APIs [1].
So far, the API framework only demonstrates delivering TB16Pix DGGS data. This is due to rather than multiple DGGSs the focus was on the creation of 2+ APIs of content for the same DGGS for a DGGS client to consume.
7.7.1.1. Endpoints
Code |
Description |
Capabilities |
|
|
landing page |
information about specifications that this API conforms to |
|
the list of supported collections |
|
DGGS Access |
|
|
Describes a particular Feature Collection |
|
Access the list of Features within a Collection. Can list either all the Features, or a particular subset based on a, WGS84 bbox, a coarse DGGS CellID (equivalent to a bbox), or a DGGS quadrilateral specified by two DGGS CellIDs (equivalent to a bbox) |
|
Access the definition of a particular Feature |
Content Negotiation |
|
|
Access the list of Profiles (model views) and Formats (media types) available for the API system, a Collection, an Item List or a Feature. This is the standard Content Negotiation by Profile [1] mechanics |
7.7.1.2. Feature/Geometry association and representation
OGC APIs make a Feature/Geometry association whereby a Feature may have more than one Geometry. The APIs implemented here list features with multiple DGGS and non-DGGS geometries.
The OGC API specification [OAFC] "does not mandate a specific encoding or format for representing features or feature collections", however mandates the data model and responses to requests for each Feature and requires that the [GeoJSON] specification be used to format it. GeoJSON itself is locked into using the WGS84 Coordinate Reference System (CRS) making it unsuitable for DGGS geometries. The OGC API specification gives an example of a GeoJSON response for a feature which is reproduced here:
{
"type" : "Feature",
"links" : [ {
"href" : "http://data.example.com/collections/buildings/items/123?f=json",
"rel" : "self",
"type" : "application/geo+json",
"title" : "this document"
},
...
, {
"href" : "http://data.example.com/collections/buildings",
"rel" : "collection",
"type" : "application/json",
"title" : "the collection document"
} ],
"id" : "123",
"geometry" : {
"type" : "Polygon",
"coordinates" : [ ... ]
},
"properties" : {
"function" : "residential",
"floors" : "2",
"lastUpdate" : "2015-08-01T12:34:56Z"
}
}
The code example above is a partial reproduction of Example 13, from [OAFC].
The feature encoding in the example above contains links to related API endpoints, a geometry encoding, and several property key/value pairs. While this form of encoding is relatively flexible, it cannot natively communicate DGGS geometries. This is because all GeoJSON geometries are ordered lists of coordinate pairs (longitude & latitude or x & y etc.) that must be expressed using the WGS84 Coordinate Reference System (CRS). DGGS geometries require coordinates to be represented as lists of Cell ID and are a different CRS to WGS84.
To enable DGGS geometry encoding in a JSON format similar to GeoJSON, both the particular DGGS must be indicated and lists of Cell IDs must be used in place of coordinate pairs. Instead of the following GeoJSON:
{
...
"id" : "123",
"geometry" : {
"type" : "Polygon",
"coordinates" : [ [Long_1, Lat_1], [Long_2, Lat_2], [Long_3, Lat_3] ... [Long_N, Lat_N] ]
},
...
}
We would have:
{
...
"id" : "123",
"geometry" : {
"type" : "Polygon",
"dggs": "https://w3id.org/dggs/tb16pix",
"coordinates" : [[ CellID_1, CellID_2, CellID_3... CellID_N ]]
},
...
}
Above the URI https://w3id.org/dggs/tb16pix for the property "dggs" indicates that the TB16Pix DGGS RS is used.
This GeoJSON-like format for DGGS is trivial to specify but, currently, will not validate as GeoJSON. Thus a specification update or a separate specification is necessary for this modified format to be supported. If a specification update was selected, the property "dggs" could easily be generalised to "crs" to allow the GeoJSON update to use many CRSs/DGGSs.
7.7.1.3. DGGS geometry types
In GeoJSON - and many other common spatial data systems - a geometry’s type is something like POINT, POLYGON, LINESTRING etc. These types give an indication of the role played by the Geometry such as the Feature the geometry is a property of as well as the structure of the geometry literal. In other words, is it a single coordinate point, a list of points or a closed ring etc.
GeoJSON supports the following geometry types:
-
Point
-
MultiPoint
-
LineString
-
MultiLineString
-
Polygon
-
MultiPolygon
These geometry types do not convey the full extent of known non-DGGS spatial geometries. For instance grids, triangular irregular networks, and so on. They also do not necessarily correspond to useful or more powerful geometry types within DGGSs.
DGGS native geometries might consist of geometry types such as:
-
OrdinateList - Cell Ids representing a set of points
-
Similar to a Point or MultiPoint
-
-
DirectedOrdinateList - Cell Ids ordered by connectivity representing a sequence of points
-
Similar to a LineString
-
-
CellList - Similar to a Polygon or MultiPolygon, noting that a CellID
While these DGGS native geometries are similar to regular geometry types, there is a requirement for each to communicate quantization decisions (e.g. resolution and whether compression is used). Further many of the rules for DGGS shape creation are different to regular geometries. For example, within a DirectedTileList, connectivity is assumed to be by ‘straight’ vectors. This is unlike anything in non-DGGS concepts.
The geometry types used throughout the remainder of this chapter for DGGS literal values are implemented for maximum interoperability with regular, non-DGGS, geometry literals and spatial data models such as GeoSPARQL. Future OGC APIs might implement native geometry types or perhaps native and non-native types.
7.7.1.4. Further GeoJSON limitations
In addition to the CRS and the form of the geometry location values (coordinates in WGS84 but only ordinates in a DGGS since
DGGS Cell IDs are single items, not pairs of values), GeoJSON is not able to directly express semantic properties for features.
Properties for GeoJSON Features other than geometries are just listed as key/value pairs, such as "floors" : "2", etc. in the first
of the two examples above. A semantic representation of this property would define what floor means, what datatype 2 is and so
on. This does not present an issue for the geometry literal itself (the Cell IDs) but does prevent the use of GeoJSON to communicate with no ambiguity values for Features .
Data specifications such RDF [2] are designed to convey semantics by defining relationships, datatype and so on. RDF can be
serialized in JSON-LD [10] and thus data similar to GeoJSON can be produced. The following example
communicates that Feature 1 has a floors property with a value of 2 but, unlike the example three above, it uses JSON-LD not GeoJSON
and thus it:
-
Identifies the Feature with a universally unique and resolvable ID, an HTTP URI.
-
Defines the property floors by quoting an identity for it that leads to an ontology definition.
-
Here the dummy URI http://example.com/some-ontology/floors allows it to be contrasted with the GeoJSON example’s literal of "floors".
-
Fixes a datatype for the value "2".
-
Here it is an XML integer, as defined by http://www.w3.org/2001/XMLSchema#integer.
---
[
{
"@id": "http://example.com/feature/1",
"@type": [
"http://www.opengis.net/ont/geosparql#Feature"
],
"http://example.com/some-ontology/floors": [
{
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": "2"
}
]
}
]
---
A "downscaling" of JSON-LD to GeoJSON is possible if the client is "happy" with the ambiguities of GeoJSON.
7.7.1.5. Geometry Formats other than GeoJSON
In addition to GeoJSON representations of feature information, a Well Known Text (WKT) like format is presented by the APIs. This appears in the geometry literal values for features as communicated by the "geosp" (GeoSPARQL) view (profile) supported by the API. The following RDF data communicates the geometry of a Feature, Statistical Area 80101100105 in both normal WKT and WKT-DGGS terms:
@prefix geo: <http://www.opengis.net/ont/geosparql#> .
@prefix geox: <https://linked.data.gov.au/def/geox#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
<https://linked.data.gov.au/dataset/asgs2016/statisticalarealevel1/80101100105> a geo:Feature ;
geo:hasGeometry [
geo:asWKT "POLYGON ((
149.075478002 -35.260227984,
149.075592138 -35.260032958,
...
149.075478002 -35.260227984))"^^geo:WktLiteral ;
],
[
geo:asWKT "<https://w3id.org/dggs/tb16pix>
POLYGON (P67303515562
P67303515565
...
P67303523664)"^^geox:wktDGGSLiteral ;
]
.
In the code above, linebreaks and tabspaces have been added to make the content more readable. Ellipses indicate where coordinate values have been removed for brevity.
The WKT DGGS literal value above is indicated in the same way as a regular WKT value,
with the asWKT property of the Feature but then the WKT DGGS literal is
typed geox:wktDGGSLiteral which is a sub property of the standard geo:wktLiteral in the
GeoSPARQL standard [3].
This new literal type, geox:wktDGGSLiteral is currently defined in the GeoSPARQL Extensions
Ontology (see section DGGS Enabled Data Services) but
it is hoped that it will be absorbed into the GeoSPARQL standard with an update to it which
is currently underway [11].
7.7.1.6. Geometry validation tooling
Since the formats for DGGS geometry literals are not standardized yet, the testbed participants developed a stand-alone DGGS geometry validator tool which would be able to be used to validate DGGS literals of the sorts mentioned in the above two sections. This tool is a Python library and is based on an existing WKT validator and is called DGGS GV (Geometry Validator). The tool is listed in the section DGGS Enabled Data Services.
For the WKT DGGS format described above, the tool uses Extended Backus Naur Form (EBNF) [12] descriptions to define the format’s requirements. An incomplete example is the following set of example EBNF statements which define how a WKT DGGS polygon-type geometry must be formulated (as shown in the example in the previous section):
wkt_dggs = crs geometry ;
crs = left_angle http_uri right_angle ;
left_paren = "(" ;
right_paren = ")" ;
left_angle = "<" ;
right_angle = ">" ;
http_uri = httpaddress | httpsaddress ;
httpaddress = "http://" hostport [ / path ] ;
httpsaddress = "https://" hostport [ / path ] ;
...
geometry =
point_text_representation |
curve_text_representation |
surface_text_representation |
collection_text_representation;
surface_text_representation =
curvepolygon_text_representation ;
curvepolygon_text_representation =
"CURVEPOLYGON" [ z_m ] curvepolygon_text_body |
polygon_text_representation |
triangle_text_representation ;
polygon_text_representation =
"POLYGON" [ z_m ] polygon_text_body;
...
The completed form of the above code is being developed in the following Git repository as part of the DGGS GV library:
The above format says that a WKT DGGS polygon geometry: - must have a CRS (DGGS) identifier that is an HTTP/HTTP URI enclosed in "<" & ">", - followed by a space, - then the word "POLYGON", - then a space, - then optionally "Z" or "M" and - then the polygon’s coordinates which, for a WKT DGGS geometry are a list of DGGS Cell IDs ordered largest to smallest (in Cell area), separated by spaces and enclosed in "(" & ")".
7.7.1.7. Geometry roles
When establishing the DGGS literal values for features delivered by the OGC API - Features instances, it was clear that the role that a geometry played, as separately from its type, e.g. point, polygon etc., is something not described in the current GeoSPARQL ontology or the data formats for the literals (GeoJSON, WKT etc.). The notion of a role for a geometry is included in [4] and is proposed for inclusion in GeoSPARQL 1.1.
The suggested geometry types to be supported for DGGS literals and thus able to be validated by DGGS GV are the same as existing WKT types which are:
-
(Multi)Point
-
(Multi)LineString
-
(Multi)Polygon
-
GeometryCollection
The roles which geometries might play are not yet full formalized. Suggested roles are found in organization’s vocabularies, such as the Geological Survey of Queensland’s Geometry Role.[13] and include roles such as:
-
Boundary
-
Bounding box
-
Bounding circle
-
Concave hull
-
Convex hull
-
-
Centroid
-
Detailed geometry
From the options above, that the geometry for Statistical Area 80101100105, as per the above GeoSPARQL example, might be represented as follows:
@prefix geo: <http://www.opengis.net/ont/geosparql#> .
@prefix geox: <https://linked.data.gov.au/def/geox#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
<https://linked.data.gov.au/dataset/asgs2016/statisticalarealevel1/80101100105> a geo:Feature ;
geo:hasGeometry [
geo:asWKT "<https://w3id.org/dggs/tb16pix>
POLYGON (P67303515562
P67303515565
...
P67303523664)"^^geox:wktDGGSLiteral ;
geox:hasRole <https://linked.data.gov.au/def/geometry-roles/boundary> ;
]
.
In the above example, the type of the DGGS geometry is Polygon and the role is Boundary, using a role from the Geometry Role vocabulary.
7.7.2. API Features instances
Three instances of the OGC LD API were implemented:
-
TB16Pix Ref - TB16Pix Reference Dataset
-
Delivers the Zones and Cells of the TB16Pix dataset, i.e. each of its Grids from Grid 0 to Grid 15.
-
This dataset contains no data other than the TB16Pix reference grids.
-
-
Geofabric - Australian Hydrological Geospatial Fabric
-
A dataset containing a single Collection of hydrological catchments for Australia covering the area of the Australian Capital Territory (ACT) only.
-
~70 features
-
-
ASGS - Australian Statistical Geographies Standard
-
A dataset containing a single Collection of Australian census Statistical Area Level 1 (SA1) blocks covering the area of the Australian Capital Territory (ACT) only.
-
~1,000 features
-
These are described in DGGS Enabled Data Services.
7.7.3. API functionality
7.7.3.1. Spatial Filtering
In addition to providing information about Datasets, Collections, Feature Lists and Features, the APIs implemented in this Testbed allow for some forms of Feature filtering. This is as required by the OGC API specification and as implemented by many features APIs, such as the OGC’s Web Feature Service [WFS].
To filter the Features within a Collections' list of features, query string argument parameters may be used. In regular, non-DGGS, OGC APIs, a WGS84 bounding box filter might look like this:
{OGC_API_ENDPOINT}/collections/{COLLECTION_ID}/items?bbox={COORDINATES_OF_A_RECTANGLE}
Such filtering is possible within the API instances listed here given that they either store WGS84 data as well as DGGS data or are able to calculate feature geometries expressed in WGS84 coordinates on the fly. A working bounding box filter for Features within the ASGS API instance is:
http://asgs.surroundaustralia.com/collections/SA1s/items?bbox=149.12037037037038,-35.49268851161001,148.74999999999997,-35.10748095969024
The above URI returns Features (Statistical Area Level 1s) in approximately the northern western third of the Australian Capital Territory.
DGGS filtering is conceptually similar to the above but simpler to communicate and implement. In the conceptually simplest BBOX implementation, which is operating for the API instances given here, a Cell ID may be given and any Features that have Geometries that overlap with it are returned. The equivalent DGGS Cell ID-based filter to the above bounding box filter is:
http://asgs.surroundaustralia.com/collections/SA1s/items?bbox=P673035
Here the Cell ID P673035 covers the same area as the WGS84 quadrilateral 149.12037037037038,-35.49268851161001,148.74999999999997,-35.10748095969024 and, indeed, the APIs return the same values for either filter.
Bounding Box filters need not be square: The OGC API - Features indicates that any quadrilateral may be used. Since the rHEALPix DGGS' Cells are square, a more complex filter based on a pair of Cell IDs would need to be implemented to cater for quadrilateral but non-square overlapping areas. Additionally, since DGGS Cells are fixed in space, even if a square bounding box was required that did not align with Cells, such a filter would be required. Quite obviously, such a filter could be of the form:
{OGC_API_ENDPOINT}/collections/{COLLECTION_ID}/items?bbox={CELL_ID_1},{CELL_ID_2}
Where CELL_ID_1,CELL_ID_2 describe the upper left and bottom right corners of a quadrilateral. Refinement in the bounding box polygon’s position
can be achieved with higher resolution Cell IDs.
This is not yet implemented in these API instances and is left to future work.
Implementing non-quadrilateral DGGS filters in a manner very similar to non-DGGS polygonal filters is possible. Such filters could be
implemented just as traditional polygonal filters are, say a WFS GetFeature request using an ogc:Intersects payload to communicate the polygonal filter. If characterized in the native DGGS of a queried API a simpler form of communicating the polygon (as opposed to one that needs
conversion to the API’s native DGGS) could be implemented in a manner similar to the query string approach of bbox?=…. However polygonal description length will be a limitation, as currently with non-DGGS, systems.
7.7.3.2. Non-Spatial Filtering
Many feature APIs allow for filtering by non-spatial attributes of features. For example, the OGC API specification [OAFC] gives the following filter payload example:
---
{
"my_first_parameter": "some value",
"my_other_parameter": 42
}
---
This would be implemented as the following URI query string parguments: &my_first_parameter=some%20value&my_other_parameter=42.
This form of filtering is using context-unaware properties, as per common use of properties in GeoJSON (see the section Further GeoJSON limitations above). While this form of filtering could be implemented as readily for DGGS Features as non-DGGS features, the current OGC LD API implementations are predicated on semantic data and thus provide for filtering using context-aware properties.
For context-aware filtering of properties, the above example would need to have the property indicators defined. Such parameter definitions are a necessary part of SPARQL [14] queries used to query RDF data. An equivalent SPARQL query for the filter in the example above would be:
---
PREFIX ex1: <http://example.com/some-ontology_1/>
PREFIX ex2: <http://example.com/some-ontology_2/>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
SELECT ?f WHERE { ?f a geo:Feature ; ex1:my_first_parameter ?param_1 ; ex2:my_other_parameter ?param_2 .
FILTER (?param_1 = "some value" && ?param_2 = 42) } ---
SPARQL or other filtering of features in the APIs within this chapter have not yet been implemented.
This form of parameter defining is bypassed for spatial data due to the presence of the CRS or DGGS dataset identifiers which provide context for the spatial data supplied within the filter.
7.7.4. Supporting Assets
To support these deployments of the OGC API - Features instances accessing DGGS content, a number of semantic assets where generated that describe the data models used within the APIs' data sources. This was required for the APIs also and defined, as supersets of the core OGC API - Features data model. These assets, as well as the API Framework, test client and API instances, are described in DGGS Enabled Data Services.
7.8. OGC API - Processes for DGGS description
As per the Testbed Call for Participation (CFP), the OGC API - Processes implementation in this task supported "the geographic location to zone-ID(s) and reverse conversion", as well as other eventual additions to allow better comparison and discussion.
7.8.1. Basic ideas:
-
The same API elements are used for a DGGS RS service and a DGGS Data service.
-
In the case of a DGGS RS service, the collections are the DGGS instances themselves, and the returned features have no properties other than the geometry and resolution (e.g., in GeoJSON the properties object will be null).
-
In the case of a DGGS Data service, the collections are the sample DGGS data (hence, made available in a particular DGGS instance, too), and the returned features have actual values associated in the properties object.
7.8.2. Formats:
To cater to different use cases, three different output formats were implemented for each endpoint returning zones:
-
A classic GeoJSON output, with geometry being either the boundary or the center point of the zone (to be controlled with a request parameter), for usage in GIS tools. The longitudes will eventually be extended outside of the -180,180 range to allow visualization by tools that cannot deal properly with dateline crossing.
-
A DGGS JSON output, a small variation of GeoJSON where the geometry is replaced by an array of ZoneIds, was used in both zone-oriented and feature-oriented APIs
-
A plain array of DGGS ZoneIds. This was for cases where the attributes are not needed, and data transfer compactness is paramount.
7.8.3. Questions, discussion topics:
-
Support for multiple DGGSs: rHEALPix and H3 were used in order to offer the clients and DGGS data servers at least a DGGS they are not already supporting natively.
-
Is the API going to be sufficiently self-describing such that the clients can figure out everything they need by just walking the API, or will it need specific knowledge contained in an API profile (e.g. a profile for rHEALPix, one for H3, consider for example ZoneId and how to determine them)?
-
For parametric DGGSs (e.g, rHEALPix). are specific instances exposed as its own DGGS or somehow are the full parameters of the DGGS in each resource exposed?
-
This API follows a processes API, where most resources are a process and one needs to know valid values to hit them.
7.8.4. Endpoints
Code |
Description |
Capabilities |
|
|
landing page |
information about specifications that this API conforms to |
|
the list of supported collections |
|
DGGSAccess |
|
|
Describes a particular DGGS |
|
Access the list of zones in a given DGGS. Can list either all the zones, or a particular subset based on resolution, WGS84 bbox, or list of containing zones (e.g., polygon defined in DGGS terms) |
|
Access the definition of a particular zone |
|
Get the list of neighbouring zones, to a given zone (should it return just a list of identifiers instead of a GeoJSON collection? Could even be a list of links in the zone itself) |
|
Get the list of parent zones, to a given zone (should it return just a list of identifiers instead of a GeoJSON collection?) |
|
Get the list of zones children of a given zone (should it return just a list of identifiers instead of a GeoJSON collection?) |
|
Returns the id of the zone containing the given point, at the given resolution |
|
Lists zones contained in the polygon |
7.8.4.1. Capabilities
7.8.4.1.1. collectionsGet
GET /collections
The list of supported collections
- Description
- Parameters
- Return Type
- Content Type
-
-
application/json
-
text/html
-
- Responses
| Code | Message | Datatype |
|---|---|---|
200 |
The list of DGGS available and link to the processes. The response contains the list of DGGS objects. This information includes:
|
|
406 |
None of the requested media types is supported at the path. |
|
500 |
A server error occurred. |
- Samples
7.8.4.1.2. conformanceGet
GET /conformance
Information about what standards/specifications this API conforms to.
- Description
-
A list of all conformance classes specified in a standard that the server conforms to.
- Parameters
- Return Type
- Content Type
-
-
application/json
-
text/html
-
- Responses
Code |
Message |
Datatype |
200 |
The URIs of all conformance classes supported by the server. To support 'generic'; clients that want to access multiple OGC API - Features implementations - and not 'just'; a specific API / server, the server declares the conformance classes it implements and conforms to. |
|
406 |
None of the requested media types is supported at the path. |
|
500 |
A server error occurred. |
- Samples
7.8.4.1.3. rootGet
GET /
landing page
- Description
-
The landing page provides links to the API definition, the conformance statements and to other resources provided by the API.
- Parameters
- Return Type
- Content Type
-
-
application/json
-
text/html
-
- Responses
Code |
Message |
Datatype |
200 |
The landing page provides links to the API definition (link relations |
|
406 |
None of the requested media types is supported at the path. |
|
500 |
A server error occurred. |
- Samples
7.8.4.2. DGGSAccess
7.8.4.2.1. collectionsCollectionIdChildrenGet
GET /collections/{collectionId}/children
Get the list of child zones, to a given zone. Question for the DGGS SWG to consider: should it return just a list of identifiers instead of a GeoJSON collection?
- Description
- Parameters
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
collectionId |
local identifier of a collection |
X |
null |
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
zoneId |
X |
null |
||
levels |
Number of levels for zone parent/children extration |
- |
null |
- Return Type
- Content Type
-
-
application/geo+json
-
application/dggs+json
-
text/html
-
application/json
-
- Responses
Code |
Message |
Datatype |
200 |
A list of DGGS zones. The response contains a list of DGGS zones. The response can be a GeoJSON payload with full boundaries, for traditional clients, or a simple list of zone ids, for DGGS aware clients |
|
406 |
None of the requested media types is supported at the path. |
|
500 |
A server error occurred. |
- Samples
7.8.4.2.2. collectionsCollectionIdGet
GET /collections/{collectionId}
Describes a particular DGGS
- Description
- Parameters
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
collectionId |
local identifier of a collection |
X |
null |
- Return Type
- Content Type
-
-
application/json
-
text/html
-
- Responses
Code |
Message |
Datatype |
200 |
Describes a particular DGGS. This information includes:
|
|
406 |
None of the requested media types is supported at the path. |
|
500 |
A server error occurred. |
- Samples
7.8.4.2.3. collectionsCollectionIdNeighborsGet
GET /collections/{collectionId}/neighbors
Get the list of neighboring zones, to a given zone. Questions for the DGGS SWG to consider: Should it return just a list of identifiers instead of a GeoJSON collection? Could this even be a list of links in the zone itself?
- Description
- Parameters
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
collectionId |
local identifier of a collection |
X |
null |
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
zoneId |
X |
null |
||
radius |
Distance, in zones, from the center zone, to be walked when extracting neighbors. Also known as "k" in a k-ring extraction in some DGGSs. |
- |
null |
- Return Type
- Content Type
-
-
application/geo+json
-
application/dggs+json
-
text/html
-
application/json
-
- Responses
Code |
Message |
Datatype |
200 |
A list of DGGS zones. The response contains a list of DGGS zones. The response can be a GeoJSON payload with full boundaries, for traditional clients, or a simple list of zone ids, for DGGS aware clients. |
|
406 |
None of the requested media types is supported at the path. |
|
500 |
A server error occurred. |
- Samples
7.8.4.2.4. collectionsCollectionIdParentsGet
GET /collections/{collectionId}/parents
Get the list of parent zones, to a given zone. Question for the DGGS SWG to consider: Should it return just a list of identifiers instead of a GeoJSON collection?
- Description
- Parameters
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
collectionId |
local identifier of a collection |
X |
null |
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
zoneId |
X |
null |
||
levels |
Number of levels for zone parent/children extraction |
- |
null |
- Return Type
- Content Type
-
-
application/geo+json
-
application/dggs+json
-
text/html
-
application/json
-
- Responses
Code |
Message |
Datatype |
200 |
A list of DGGS zones. The response contains a list of DGGS zones. The response can be a GeoJSON payload with full boundaries, for traditional clients, or a simple list of zone ids, for DGGS aware clients. |
|
406 |
None of the requested media types is supported at the path. |
|
500 |
A server error occurred. |
- Samples
7.8.4.2.5. collectionsCollectionIdPointGet
GET /collections/{collectionId}/point
Returns the id of the zone containing the given point, at the given resolution
- Description
- Parameters
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
collectionId |
local identifier of a collection |
X |
null |
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
point |
Only zones that contain/touch the point are returned. The point is provided in axis order:
The CRS of the values is WGS 84 with axis order longitude/latitude (http://www.opengis.net/def/crs/OGC/1.3/CRS84). [BigDecimal] |
- |
null |
|
resolution |
X |
null |
- Return Type
- Content Type
-
-
application/geo+json
-
application/dggs+json
-
text/html
-
application/json
-
- Responses
Code |
Message |
Datatype |
200 |
A list of DGGS zones. The response contains a list of DGGS zones. The response can be a GeoJSON payload with full boundaries, for traditional clients, or a simple list of zone ids, for DGGS aware clients |
|
406 |
None of the requested media types is supported at the path. |
|
500 |
A server error occurred. |
- Samples
7.8.4.2.6. collectionsCollectionIdPolygonGet
GET /collections/{collectionId}/polygon
Lists zones contained in the polygon
- Description
- Parameters
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
collectionId |
local identifier of a collection |
X |
null |
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
bbox |
Only features that have a geometry that intersects the bounding box are selected. The bounding box is provided as four or six numbers, depending on whether the coordinate reference system includes a vertical axis (height or depth):
The CRS of the values is WGS 84 with axis order longitude/latitude (CRS84)
(http://www.opengis.net/def/crs/OGC/1.3/CRS84) unless a different coordinate reference system
is specified in the parameter For WGS 84 longitude/latitude, the values are in most cases the sequence of minimum longitude, minimum latitude, maximum longitude and maximum latitude. However, in cases where the box spans the anti-meridian the first value (west-most box edge) is larger than the third 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. If a feature has multiple spatial geometry properties, it is the decision of the server whether only a single spatial geometry property is used to determine the extent or all relevant geometries. [BigDecimal] |
- |
null |
|
polygon |
Only zones contained in the polygon are returned. The polygon is specified as WKT. The coordinate reference system of the values is WGS 84 longitude/latitude (CRS84) (http://www.opengis.net/def/crs/OGC/1.3/CRS84). |
- |
null |
|
resolution |
X |
null |
- Return Type
- Content Type
-
-
application/geo+json
-
application/dggs+json
-
text/html
-
application/json
-
- Responses
Code |
Message |
Datatype |
200 |
A list of DGGS zones. The response contains a list of DGGS zones. For traditional clients the response can be a GeoJSON payload with full boundaries, or a simple list of ZoneIds, for DGGS aware clients. |
|
406 |
None of the requested media types is supported at the path. |
|
500 |
A server error occurred. |
- Samples
7.8.4.2.7. collectionsCollectionIdZoneGet
GET /collections/{collectionId}/zone
Access the definition of a particular zone
- Description
- Parameters
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
collectionId |
local identifier of a collection |
X |
null |
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
zoneId |
X |
null |
- Return Type
- Content Type
-
-
application/geo+json
-
application/dggs+json
-
text/html
-
application/json
-
- Responses
Code |
Message |
Datatype |
200 |
A single DGGS zone The response contains the description of a single DGGS zone. |
|
406 |
None of the requested media types is supported at the path. |
|
500 |
A server error occurred. |
- Samples
7.8.4.2.8. collectionsCollectionIdZonesGet
GET /collections/{collectionId}/zones
Access the list of zones in a given DGGS. Can list either all the zones, or a particular subset based on resolution, WGS84 bbox, or list of containing zones (e.g., polygon defined in DGGS terms)
- Description
- Parameters
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
collectionId |
local identifier of a collection |
X |
null |
| Name | Description | Required | Default | Pattern |
|---|---|---|---|---|
resolution |
X |
null |
||
limit |
The optional limit parameter limits the number of items that are presented in the response document. Only items on the first level of the collection in the response document are counted. Nested objects contained within the explicitly requested items shall not be counted. Minimum = 1. Maximum = 10000. Default = 10. |
- |
10 |
- Return Type
- Content Type
-
-
application/geo+json
-
application/dggs+json
-
text/html
-
application/json
-
- Responses
Code |
Message |
Datatype |
200 |
A list of DGGS zones. The response contains a list of DGGS zones. For traditional clients the response can be a GeoJSON payload with full boundaries, or a simple list of ZoneIds, for DGGS aware clients |
|
406 |
None of the requested media types is supported at the path. |
|
500 |
A server error occurred. |
- Samples
7.8.5. Models
Figure 2 shows the OGC API - Processes class diagram for DGGS.
7.8.5.1. Collection
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
id |
X |
String |
Identifier of the collection. In case the identifier is a DGGS RS service, this will be the DGGS instance identifier, otherwise, the value is going to be the data collection id. |
|
dggs-id |
String |
Identifiers of the DGGS instance. For DGGS RS services, this will be the same as the id, for DGGS Data services, dggs-id identifies the particular DGGS instance used. |
||
title |
String |
Human readable title of the collection |
||
description |
String |
A description of the collection |
||
resolutions |
List of [number] |
|||
links |
X |
List of Link |
The list of links, e.g., to the operations provided by this DGGS collection. |
7.8.5.2. CollectionList
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
links |
X |
List of Link |
||
dggs-list |
X |
List of [string] |
7.8.5.3. ConfClasses
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
conformsTo |
X |
List of [string] |
7.8.5.4. DGGSJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
id |
X |
oneOf<string,integer> |
||
type |
X |
String |
Enum: Feature, |
|
geometry |
X |
List of [string] |
The geometry of the feature, as a list of DGGS zone ids |
|
properties |
X |
Object |
||
links |
List of Link |
7.8.5.5. Exception
Information about the exception: An error code plus an optional description.
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
code |
X |
String |
||
description |
String |
7.8.5.6. FeatureCollectionGeoJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: FeatureCollection, |
|
features |
X |
List of FeatureGeoJSON |
||
links |
List of Link |
|||
timeStamp |
Date |
This property indicates the time and date when the response was generated. |
date-time |
|
numberMatched |
Integer |
The number of features of the feature type that match the selection parameters such as |
||
numberReturned |
Integer |
The number of features in the feature collection. If the information about the number of features is not known or difficult to compute a server may omit this information in a response. If the value is provided, the value shall be identical to the number of items in the 'features' array. |
7.8.5.7. FeatureGeoJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: Feature, |
|
geometry |
X |
geometryGeoJSON |
||
properties |
X |
Object |
||
id |
oneOf<string,integer> |
|||
links |
List of Link |
7.8.5.8. GeometryGeoJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: GeometryCollection, |
|
coordinates |
X |
List of [array] |
||
geometries |
X |
List of GeometryGeoJSON |
7.8.5.9. GeometrycollectionGeoJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: GeometryCollection, |
|
geometries |
X |
List of GeometryGeoJSON |
7.8.5.10. LandingPage
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
title |
String |
|||
description |
String |
|||
links |
X |
List of Link |
7.8.5.11. LinestringGeoJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: LineString, |
|
coordinates |
X |
List of [array] |
7.8.5.12. Link
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
href |
X |
String |
||
rel |
String |
|||
type |
String |
|||
hreflang |
String |
|||
title |
String |
|||
length |
Integer |
7.8.5.13. MultilinestringGeoJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: MultiLineString, |
|
coordinates |
X |
List of [array] |
7.8.5.14. MultipointGeoJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: MultiPoint, |
|
coordinates |
X |
List of [array] |
7.8.5.15. MultipolygonGeoJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: MultiPolygon, |
|
coordinates |
X |
List of [array] |
7.8.5.16. PointGeoJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: Point, |
|
coordinates |
X |
List of [number] |
7.8.5.17. PolygonGeoJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: Polygon, |
|
coordinates |
X |
List of [array] |
7.8.5.18. ZoneCollectionDGGSJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: FeatureCollection, |
|
features |
X |
List of DGGSJSON |
||
links |
List of Link |
|||
timeStamp |
Date |
This property indicates the time and date when the response was generated. |
date-time |
|
numberMatched |
Integer |
The number of features of the feature type that match the selection parameters such as |
||
numberReturned |
Integer |
The number of features in the feature collection. If the information about the number of features is not known or difficult to compute a server may omit this information in a response. If the value is provided, the value shall be identical to the number of items in the 'features' array. |
7.8.5.19. ZoneCollectionGeoJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: FeatureCollection, |
|
features |
X |
List of ZoneGeoJSON |
||
links |
List of Link |
|||
timeStamp |
Date |
This property indicates the time and date when the response was generated. |
date-time |
|
numberMatched |
Integer |
The number of features of the feature type that match the selection parameters such |
||
numberReturned |
Integer |
The number of features in the feature collection. If the information about the number of features is not known or difficult to compute a server may omit this information in a response. If the value is provided, the value shall be identical to the number of items in the 'features' array. |
7.8.5.20. ZoneGeoJSON
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
type |
X |
String |
Enum: FeatureCollection, |
|
features |
X |
List of FeatureGeoJSON |
||
links |
List of Link |
|||
timeStamp |
Date |
This property indicates the time and date when the response was generated. |
date-time |
|
numberMatched |
Integer |
The number of features of the feature type that match the selection parameters such as |
||
numberReturned |
Integer |
The number of features in the feature collection. If the information about the number of features is not known or difficult to compute a server may omit this information in a response. If the value is provided, the value shall be identical to the number of items in the 'features' array. |
||
resolution |
X |
BigDecimal |
7.8.5.22. ZoneList
| Field Name | Required | Type | Description | Format |
|---|---|---|---|---|
zones |
X |
List of [string] |
||
links |
X |
List of Link |
||
timeStamp |
Date |
This property indicates the time and date when the response was generated. |
date-time |
|
numberMatched |
Integer |
The number of features of the feature type that match the selection parameters such as |
||
numberReturned |
Integer |
The number of features in the feature collection. If the information about the number of features is not known or difficult to compute a server may omit this information in a response. If the value is provided, the value shall be identical to the number of items in the 'features' array. |
7.9. Is there a need for an OGC API DGGS implementation standard?
The participant discussions and technology implementations conducted during this Testbed activity evaluated the question of "is there a justification, or need, to draft a separate implementation standard to codify OGC APIs for DGGS?". The work done in both D137 and D139 allowed this question to be asked from a number of perspectives.
While the "system" and "data" aspects of a DGGS can be implemented using conventional OGC API - Processes and OGC API - Features schemas, there are some subtle, but very important, differences that separates the operation/access of a DGGS resource from those of a conventional Process or Feature service.
DGGS both simplify the traditional view and add new capability.
The simplification can be summarized as:
-
Very significant reduction in geometric complexity, with a single geometry and topology data model encompassing vector, raster, point cloud, location tags, bounding-box & tiling,
-
Complete separation of geometry from file-type,
-
Extension from 2-D to 3-D & 4D geometries without any additional geometry types or topological queries, and
-
Opportunity to develop a unified spatio-temporal filtering and processing language and associated API for use across all spatial types.
New capabilities include:
-
New unified geometry language to supersede point, line, polygon, raster etc,
-
Explicit alignment of spatio-temporal geometric precision with hierarchical level in the API,
-
Explicit recording and tracking of process history through the API,
-
Leveraging ZoneClass and parent, child hierarchy to implement streaming transmission and recursive API filters and processes, over specified range of levels, and
-
Opportunity to include a desired precision or risk or uncertainty explicitly in spatio-temporal filters and processes.
7.9.1. Proposal for OGC WKT for DGGS geometries
Initial proposal for a new unified geometry language follows. This is intended as a complete list of potential internal DGGS geometry types:
- OrdinateList
-
a list of (1..*) ZoneIds representing a set of points,
-
optionally sorted in descending size order,
-
optionally compressed to recursively replace complete sets of children by their parents, if compressed a notation to indicate level depth for decompression.
-
by default the coordinate will be the representative point nominated by the DGGS, typically the centroid, but some DGGS may also define schema for assigning additional points, such as a cell corner or mid-point on one of the cells' edges. Such schema could for support Arakawa grids and other vertically and temporally staggered grids. Notations for such usage have not been discussed.
-
- DirectedOrdinateList
-
a list of (2..*) ZoneIds ordered by connectivity representing a sequence of points, ZoneIds in the sequence need not touch, connectivity is assumed to be by ‘straight’ vectors,
-
optionally sorted in groups in descending size order to facilitate streaming transmission and recursive filtering and processing. How to denote a first approximation of a directed sequence of points, and then recursively fill in the detail is not yet resolved. This is analogous to wavelet approaches.
-
optional compression may be possible, but further thinking is needed to elaborate what that means.
-
by default the coordinate will be the representative point nominated by the DGGS, typically the centroid. c.f. OrdinateList for possible alternative representative points.
-
- CellList
-
a list of (1..*) ZoneIds representing a set of nD spaces,
-
optionally sorted in descending size order to facilitate streaming transmission and recursive filtering and processing,
-
optionally compressed to recursively replace complete sets of children by their parents, if compressed a notation to indicate level depth for decompression.
-
optionally sorted in row, column order for an array or image store.
-
- DirectedCellList
-
a list of (2..*) ZoneIds ordered by connectivity representing a sequence of nD spaces, all ZoneIds in the sequence need to touch at least one other connected ZoneId in the directed sequence, to ensure there are no gaps in the directed sequence,
-
optionally sorted in groups in descending size order to facilitate streaming transmission and recursive filtering and processing. c.f. discussion under sorting for DirectedOrdinateLists
-
optionally compressed to recursively replace complete sets of children by their parents, if compressed a notation to indicate level depth for decompression.
-
- TileList
-
a list of (1..*) ZoneIds representing a set of nD bboxes,
-
optionally sorted in descending size order,
-
optionally compressed to recursively replace complete sets of children by their parents, if compressed a notation to indicate level depth for decompression.
-
optionally sorted in row, column order for a tile store.
-
- DirectedTileList
-
a list of (2..*) ZoneIds ordered by connectivity representing a sequence of nD spaces, ZoneIds in the sequence need not touch, connectivity is assumed to be by ‘straight’ vectors,
-
optionally sorted in groups in descending size order to facilitate streaming transmission and recursive filtering and processing, c.f. discussion under sorting for DirectedOrdinateLists
-
optionally compressed to recursively replace complete sets of children by their parents, if compressed a notation to indicate level depth for decompression.
-
- ZoneCollection
-
a list of (2..*) of one or more of the above types.
-
optionally sorted in groups in descending size order to facilitate streaming transmission and recursive filtering and processing,
-
optionally compressed to recursively replace complete sets of children by their parents, if compressed a notation to indicate level depth for decompression. Further work is needed to identify if compression can apply across elements of the collection, or only within elements.
-
- DirectedZoneCollection
-
a list of one or more of the above types that are connected.
-
optionally sorted in groups in descending size order to facilitate streaming transmission and recursive filtering and processing, c.f. discussion under sorting for DirectedOrdinateLists
-
optionally compressed to recursively replace complete sets of children by their parents, if compressed a notation to indicate level depth for decompression.
-
A WKT representation for these geometry type literals needs to be defined for use in GeoSPARQL amongst others.
The draft Topic 21 v2.0 Abstract Specification talks about quantization roles and the following table relates the roles with the resulting data types from the above list. In all instances the quantization role would be expected to be preserved, probably in column definition, so the DGGS knows how to interpret the zone values.
| WKT geometry object | DGGS quatization role | DGGS geometry literal | notes and examples |
|---|---|---|---|
POINT |
asCoordinates |
OrdinateList |
|
MULTIPOINT |
asCoordinates |
OrdinateList |
|
LINESTRING |
asCoordinates |
DirectedOrdinateList |
|
MULTILINESTRING |
asCoordinates |
ZoneCollection of DirectedOrdinateList |
|
POLYGON |
asCoordinates |
DirectedOrdinateList |
|
MULTIPOLYGON |
asCoordinates |
DirectedZoneCollection of DirectedCoordinateLists |
|
TRIANGLE |
asCoordinates |
DirectedOrdinateList |
|
TIN |
asCoordinates |
DirectedZoneCollection of DirectedOrdinateList |
|
POINT |
asDataCells |
CellList |
|
MULTIPOINT |
asDataCells |
CellList |
|
LINESTRING |
asDataCells |
DirectedCellList |
|
MULTILINESTRING |
asDataCells |
ZoneCollection of DirectedCellList |
|
POLYGON |
asDataCells |
CellList |
|
MULTIPOLYGON |
asDataCells |
CellList |
|
TRIANGLE |
asDataCells |
CellList |
|
TIN |
asDataCells |
ZoneCollection of CellList |
|
GEOMETRYCOLLECTION |
any |
ZoneCollection |
| Geometry object | DGGS quatization role | DGGS geometry literal | notes and examples |
|---|---|---|---|
point array |
asCoordinates |
OrdinateList |
|
point array |
asDataCells |
CellList |
|
point cloud |
asDataCells |
CellList or 3D+T ZoneIds |
|
raster image |
asCoordinates |
OrdinateList |
|
raster image |
asDataCells |
CellList |
|
raster image |
asDataTiles |
TileList |
|
trajectory |
asCoordinates |
DirectedOrdinateList of 3D+T ZoneIds |
|
trajectory |
asDataCells |
DirectedCellList of 3D+T ZoneIds |
|
time series |
asCoordinates |
DirectedOrdinateList of 2D+T or3D+T ZoneIds |
the spatial component may be static |
time series |
asDataCells |
DirectedCellList of 2D+T or3D+T ZoneIds |
the spatial component may be static |
WMS image |
asGraphicCells |
CellList |
|
WMS image collection |
asGraphicCells |
ZoneCollection of CellList |
|
WMS image collection |
asGraphicCells |
CellList |
|
WMS image collection |
asGraphicTiles |
TileList |
|
Bounding-box |
asCoordinates |
OrdinateList |
|
Bounding-box |
asDataTile |
TileList |
|
Social media stream |
asTags |
DataCellList |
|
Document text |
asTags |
DataCellList |
Therefore, the Testbed participants recommend that there is significant merit in support of future efforts to develop an OGC API DGGS Standard.
8. Use Cases
8.1. Scope of Works under the Testbed-16 CFP
The Testbed 16 Call for Participation (CFP) alluded to non-specific Use Cases that were to demonstrate two possible 'implementation scenarios' involving the following actors:
-
Server API - Essentially a reprojection engine that can convert between traditional CRS and DGGS RS and back (Optionally DGGS RS to DGGS RS).
-
Enabled Service - Can filter data based on a DGGS zone value (and for the sake of highest testbed value, return these filtered data with zone-IDs).
-
Client - Can display DGGS data based on zone-IDs and values.
Based on the CFP, three initial use cases were posed: Use Case #1 - GPS Location to DGGS Cell…Use Case #3 - Bushfire Impacts from the "Black Summer" Bushfires in Australia. Participant discussions matured the use cases and at the same time participants gained confidence in what was possible both from an API perspective. This led, from an implementation perspective for the server and client endpoints, a fourth much more ambitious use case Use Case #4 - A DGGS version of a DAPA Use Case making use of one or more Jupyter notebooks. This last use case is the one the participants fnally pursuedin the Testbed.
The fourth use case was developed by analyzing the Testbed-16 DAPA thread Use Cases [5] from a DGGS implementation perspective, identifying a set of common elements, and bringing them together as a single Use Case. This Use Case was intended to demonstrate an alternative DGGS roadmap for the Testbed-16 DAPA thread activities.
8.1.1. Use Case #1 - GPS Location to DGGS Cell
-
Client Receives a GPS Location - Can be via a direct feed from a GPS Receiver and/or some other data feed containing structured GPS location data.
-
Client Uses GPS Error Ellipse Information to Query the DGGS Server - GPS Error Ellipse can be used to determine the appropriate DGGS resolution to query.
-
DGGS Server Returns the DGGS Cell ID(s) at the Requested Resolution - DGGS Server returns the DGGS Cell ID (or set of Cell IDs) that best represents the point location plus its horizontal uncertainty.
8.1.2. Use Case #2 - COVID-19 Active Cases Near Me
-
Official COVID-19 Case Dataset(s) are DGGS Enabled - Point datasets of COVID-19 cases and their reported location are DGGS Enabled.
-
Client Includes a Simple Search Facility to Search for Nearby Reported Cases - Client uses either its' own location (if as a mobile app) or a selected location plus a range distance to search for nearby reported cases of COVID-19.
-
DGGS Server Returns the DGGS ZoneID(s) for the requested range query - DGGS Server is queried via a range-type search for DGGS Cell ID’s and returns ZoneID’s within the search area.
-
DGGS Enabled Dataset(s) are queried for matching DGGS ZoneID’s - The DGGS Enabled data sources are queried (via conventional Database type of select query) for records "tagged" with the Search Area DGGS ZoneID’s.
-
Client Displays the returned data
8.1.3. Use Case #3 - Bushfire Impacts from the "Black Summer" Bushfires in Australia
-
Key Datasets are DGGS Enabled - Key datasets (e.g. Bushfire affected coverage, road networks, population demographics) are DGGS Enabled.
-
Client Includes a Simple Search Facility to Search for Nearby Reported Cases - Client uses a search mechanism (e.g. bbox, range search, etc.) to define a search area for DGGS ZoneID’s.
-
DGGS Server Returns the DGGS ZoneID(s) for the requested range query - DGGS Server is queried via a range-type search for DGGS ZoneID’s and returns ZoneID’s within the search area.
-
DGGS Enabled Dataset(s) are queried for matching DGGS ZoneID’s - The DGGS Enabled data sources are queried (via conventional Database type of select query) for records "tagged" with the Search Area DGGS ZoneID’s.
-
Client Displays the returned data
8.1.4. Use Case #4 - A DGGS version of a DAPA Use Case making use of one or more Jupyter notebooks
-
Key Datasets are DGGS Enabled - Selected EO DAPA data sources are converted to DGGS form, potentially using Jupyter notebook to 'read' the DAPA data.
-
Question arises as to which derived DAPA EO data is available globally rather than only in the specific region of the DAPA use case.
-
Fundamental difference between the DAPA pre-processing and pre-processing for DGGS is that the DGGS quantization process will populate a DGGS resolution that is similar to the EO resolution, and then recursively aggregate it to n coarser resolutions with a suite of summary statistics, to be stored in the DGGS Process Server,
-
Australian statistical mesh-block polygons are converted to DGGS form, to be stored in the DGGS Feature Server,
-
Australian catchments are converted to DGGS form, to be stored in the DGGS Feature Server,
-
-
-
Client Performs a Feature Query using a polygon selection from the Australian mesh-blocks or catchments as AOI - Client uses a DGGS Feature search mechanism (e.g. bbox, range search, etc…) to define a AOI which is returned as DGGS ZoneID’s. Stretch goal, AOI filter includes time.
-
Client displays the AOI and underlying DGGS polygon data on a map display - Part of the Jupyter notebook.
-
Client Sends a Process Query using the returned DGGS ZoneID list to construct a low resolution AOI query - Using the Jupyter notebook the user selects the process to be performed and the desired resolution, and the Client issues the Process Request to the DGGS Process Server.
-
DGGS Process Server returns EO summary statistics for the chosen AOI at the chosen resolution - DGGS Process Server computes the chosen process over the query AOI and returns the requested processing.
-
Client Displays the returned data
-
Repeat steps (4) to (6) as required until they are satisfied with the chosen process, and have achieved the desired precision (resolution)
- NOTE
-
There is a potential for precision hints, and incorporating DAPA style EO analysis, because GeoServer already has the processing engine.
- Major caveat
-
Knowing when to stop work in this Testbed thread and what to hand over to the next DGGS Testbed activity. This is because there is a very clear understanding that there are many aspects to compare and contrast and explore. Also remembering that at the start of the TB-16 DGGS thread, the idea of 'DGGS data' had not been fully anticipated, and so there was no sponsor expectation of having 'DGGS data'. At this point, the use and creation of DGGS Data is fundamental to the TB-16 DGGS thread and both the APIs.
9. DGGS Server and API
GeoSolutions delivered the D137 DGGS Server Implementation: Open-source server implementation with support for DGGS API.
In particular, the delivery was comprised of four GeoServer community modules and made available:
-
As source code, licensed under the GPL license, in the GeoServer GIT repository, under the umbrella of OGC API modules.
-
As binary extensions, ready to be dropped into a GeoServer installation, as part of the larger OGC API family test packages. The zip files enable, among others, support for OGC API - Features, Tiles, Styles and DGGS.
-
As a live server for tests, covering all for live tests on the GeoSolutions Testbed-16 activities.
In particular, the Java modules are:
-
dggs-core: Provides the basic Java API for DGGSs, implementations of said interfaces for H3 and rHEALPix. Also, a basic GeoToolsDataStoreimplementation exposing the DGGS zones as collections of OGC features, for publication on all classic OGC protocols, as well as the DGGS API was provided. -
dggs-clickhouse: Exposes the contents of suitably set-up ClickHouse database as OGC features, for publication on all classic OGC protocols, as well as the DGGS API. -
ogcapi-dggs: Implementation of the DGGS API exposing all available DGGS enabled layers. -
web-dggs: Provides the user interface for configuring the aboveDataStoreimplementations in the GeoServer administration console.
The following sections provide details on every component.
9.1. DGGS library comparisons and choices
The GeoTools library and GeoServer web application had no support for DGGS at the beginning of the testbed. Three DGGS libraries have been evaluated in order to establish a baseline for a generic DGGS Java API.
In particular the following libraries were evaluated:
-
H3: Provides support for the same named DGGS, is a library implemented entirely in C, but providing bindings for a variety of other languages, including, among others, Java, Python, JavaScript and Go.
-
rhealpixdggs-py: The reference implementation of rHEALPix in Python.
-
open-eaggr: Provides support for the OpenEAGGR DGGS, is a library implemented in C, but also providing bindings for Java and Python.
Table 34 compares how the three libraries represent the basic DGGS concepts and the integration with geographic coordinates and basic geometries is interesting.
| Class/Concept | H3 | OpenEAGGR | rHEALPix |
|---|---|---|---|
Main Class |
|||
DGGS Zone |
A long or hex string (no dedicated object, all functionality is provided via |
DggsCell class (wraps the zone identifier, a string) |
Cell class. Fields include zone identifier |
Geographic point |
GeoCoord class, as |
LatLongPoint as |
Python tuple with |
Geographic line |
Array of |
LatLongLineString, containing a list of |
Array of Python tuples, each representing a single point. |
Geographic polygon |
Array of arrays of |
LatLongPolygon, able to represent a polygon with holes. |
Array of point tuples (no support for polygons with holes) |
Table 35 compares the libraries in terms of functionality provided. The following table provides a set of links to tagged versions of the respective software, with eventual comments when the method in question has unusual behavior.
| Function | H3 | OpenEAGGR | rHEALPix |
|---|---|---|---|
Lat/Lon/Resolution to zone identifeir |
|||
Zone to its center (geographic point) |
|||
Zone to polygon boundary |
convertDggsCellOutlineToShapeString(DggsCell cell, ShapeStringFormat format): String. Returns either KML, GeoJSON, or WKT. |
Cell.boundary(n, plane, interior), or RHEALPixDGGS.vertices(). Returns an array of tuples representing points. |
|
Zone resolution |
No direct API, |
||
Zone to parent |
h3ToParent(long, parentRes): long, returns the parent at the given resolution. |
getCellParents: DggsCell[] returns the direct parents of the zone (in this DGGS, they may be more than one) |
No direct API, just eliminate the last char in the zone identifier. |
Zone to children |
h3ToChildren(long, childResolution): long[] returns all the children at the given target resolution. |
getCellChildren: DggsCell[] returns the direct children of a cell |
Cell.subcells(resolution) returns all the children at the given target resolution |
Neighboring zone |
kRing(long, numRings) → long[[]] Returns all the zones within K zones from the given center, organized by rings. |
Cell.neighbors full direct neighbors of the zone (zones sharing a side with the center one) |
|
Polygon to set of zones |
polyfill(GeoCoord[ shell, GeoCoord[][] holes, res)], all the cells contained in the given polygon shell, at the given resolution. |
convertShapesToDggsShapes(LatLonShape[): DggsShape[]] |
|
Compaction (given a set of zone identifiers, return the minimal set of zones representing the same area, using zones at lower resolution) |
compact(long[): long[]] |
Not supported |
Not supported |
Finally, given the target of integration with GeoServer, evaluating the suitability of integration with a Java Web Server was important.
-
H3 provides the most natural integration with Java among the libraries explored. The Java bindings contain, in the 700kb library JAR, native binary implementations for Windows, Linux, OSX and Android on a variety of CPU architectures. On most platforms using the library is simply a matter of setting the library as a dependency, and using the library as if it was a pure Java one. No external setups or native builds were required. A session of load testing proved the library to be very stable. No crashes were detected.
-
OpenEAGGR provides a Java binding for the C library. However, the latter has to be custom built for the target platform, from the sources. Load tests on a Linux Ubuntu 64bit derivative showed a tendency to throw segmentation faults, which as a consequence crashed the entire virtual machine.
-
rHEALPix is a Python 3 library, with scipy dependencies and integration with a small C library implementing the rHEALPix projection calculations. As a result, this library can be used solely in a native Python environment. This is also due to the fact that as alternatives for the Java Virtual Machine (JVM) such as Jython cannot be used. The JEP library was chosen for the integration, as it provides the ability to call onto a native Python interpreter from Java code.
As a result of the above tests, and considering the time limits of a Testbed, the OpenEaggr library was dropped from the actual DGGS integration experiments.
The rHEALPix integration development produced functional code, with a couple of significant limitations:
-
The integration proved to be slow. In particular, computing the boundary and center of rHEALPix zones is too slow for significant production usage.
-
The integration did not scale up with concurrent requests due to an incompatibility between the Java web server runtime operations (based on threads) and the Python Global Interpreter Lock (GIL), disallowing concurrent operations among Python interpreters running in the same process.
The H3 integration has showed no issues so far, being stable, fast and linearly scalable.
9.2. DGGS Java API
The DGGS subsytem in GeoServer is based on a pluggable extension point called DGGSInstance. The interface exposes the basic operations of a DGGS, allowing upstream code to operate against a DGGS without relying on its implementation details:
-
List of resolution levels, as integer numbers.
-
Getting a zone from a string identifier.
-
Getting all the zones intersecting a given envelope, at a given target resolution, with eventual compaction.
-
Getting the neighbors of a zone, with a given radius, expressed as number of zones
-
Getting the children of a zone, at a given target resolution.
-
Getting all the parents of a given zone, recursively (the number of resolution is usually small, implying a small number of potential parents as well).
-
Mapping a point to the zone containing it, at a given resolution.
-
Mapping a polygon to a list of zones at a given resolution, with eventual compaction.
The DGGSInstance implementations can be discovered at runtime using the Java Service Provider Interfaces (SPI) mechanism. This allows creating new DGGS integrations, packaging them as JAR files, and having GeoServer discover their presence.
9.3. The DGGS geometry store
In GeoTools and GeoServer a DataStore is a Java interface " used to access and store geospatial data in a range of vector formats".
A DataStore provides access to a set of feature collections,
enabling exploration of their structure (list of attributes and type),
as well as to query them, and optionally, to modify their contents.
The operation model of the DataStore is heavily influenced by the original WFS 1.0 design,
and is still a good match for the existing OGC API - Features.
In GeoServer DataStore instances can be plugged in, discovered and configured at runtime using the SPI mechanism.
This allows publishing data over various OGC protocols, such as WFS, WMS, WMTS and the OGC API equivalents.
The first DGGS integration with GeoServer was thus the DGGSGeometryStore, exposing the DGGS zones as features, with an identifier (the ZoneId), a resolution, and a geometry (the boundary).
The store currently takes as a parameter the DGGS to be used. In the future configuration parameters for DGGSs like rHEALPix will be exposed as well. The current rHEALPix implementation exposes the configuration for the TB16Pix RS.
The store then exposes a single feature collection, with the same name as the DGGS, that can be configured as a layer in GeoServer, and then consumed from services such as WMS and WFS.
An example WMS request could be:
The following images show maps of both H3 and TB16-Pix from the WMS server:
A WFS request can be used instead:
Which results in:
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"id": "TB16-Pix.S",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-180, -90],
[-180, -41.9379],
[180, -41.9379],
[180, -90],
[-180, -90]
]
]
},
"geometry_name": "geometry",
"properties": {
"zoneId": "S",
"resolution": 0,
"shape": "cap",
"color": "#FF80FF"
},
"bbox": [-180, -90, 180, -41.9379]
}],
"totalFeatures": 6,
"numberMatched": 6,
"numberReturned": 1,
"timeStamp": "2020-10-14T13:53:11.554Z",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::4326"
}
},
"bbox": [-180, -90, 180, 90]
}
When using a WMS endpoint, the geometry store dynamically chooses which resolution level to return based on the current scale denominator.
The resolution level can be controlled via the viewparams vendor parameter.
This allows passing key values to the data sources.
Originally conceived to expand variables in layers sourced from SQL statements,
the viewparams mechanism is now available to every store.
In particular, the resOffset view parameter can be used to offset the target resolution.
This can be used, for example, to display the DGGS layer multiple times,
and viewing the parent/child relationship in a WMS display:
-
H3 live link displaying zones, their parent and grand-parent (zoom in a few times in order for the three levels to display)
-
TB16-Pix live link displaying zones, their parent and grand-parent.
A sample URL is URL-decoded and dissected below:
| URL component | Description |
|---|---|
|
Host and path |
|
|
|
|
|
|
|
|
|
Whole world map |
|
In plate carree. |
|
|
|
|
|
|
|
Returns a working OpenLayers client displaying the same map |
|
Superimposes three times the TB16-Pix layer, overlays a transparent world continents layer |
|
Changes the style of the second and third TB16-Pix layers, displaying the direct parent border as thick orange, and the grandparent as thick red. |
|
The first TB16-Pix layer uses the "natural" resolution, as decided by the |
Static displays of the parent/child geometric relationships in H3 and TB16-Pix follow.
9.4. The ClickHouse storage choice
To align with the DAPA tasks, testbed participants decided to expose Sentinel 2 data over the Australian Capital Territory (ACT), resampled over the H3 and TB16-Pix zones, at resolution 11 and higher. For each zone, the following information is available:
-
All 13 bands, from B01 up to B13, along with B8A.
-
The Normalized Difference Vegetation Index (NDVI), computed as
(B08 - B04) / (B04 + B04) -
The Normalized Difference Built-Up Index, computed as
(B11 - B08) / (B11 + B08) -
The Normalized Difference Water Index, computed as
(B03 - B08) / (B03 + B08)
To ensure enough data coverage, a bounding box slightly larger than the ACT has been used, in order to ensure enough coverage for the higher level parent zones. Figure 8 shows a reference display of the area.
Even with such a small area, and reduced set of resolutions, the number of records to be stored is significant. In addition to that, to exercise the DGGS and DAPA API at multiple times, snapshots of the area have been taken in 2019 and 2020.
Table 36 & Table 37 report the number of actual zones imported per level (data import is discussed later):
| Resolution | Zone count |
|---|---|
5 |
44 |
6 |
450 |
7 |
3.494 |
8 |
25.462 |
9 |
180.772 |
10 |
1.272.272 |
11 |
8.923.852 |
| Resolution | Zone count |
|---|---|
5 |
8 |
6 |
112 |
7 |
1.188 |
8 |
11.152 |
9 |
104.000 |
10 |
940.252 |
11 |
8.470.532 |
This clarifies the requirements on the data storage, in particular:
-
Ability to efficiently store in excess of 20 million records, each having 16 numerical attributes.
-
Compact storage.
-
Ability to efficiently locate records by zone identifiers, or by n-th parent zone id.
-
Ability to quickly perform aggregations over columns values, such as extracting the maximum, minimum, average and sum of values in a given polygon (expressed as sets of zoneIds to retrieve).
A classic relational database can still handle 20 million records at ease. However, with larger areas or deeper resolution sampling, the number would grow very large. The whole world sampled at the highest resolution level of H3 would require storing 597 trillion records.
For the use case, a dedicated On-Line Analytical Processing (OLAP) database is probably a better choice. ClickHouse was the choice to demonstrate this option. The following characteristics make ClickHouse a good match for the use case:
-
Tables are natively partitioned in sub-sets by a given partitioning key, supporting splitting a large dataset in smaller, more manageable parts.
-
Compressed column oriented storage, saving data by column instead of by row, indexing it by the given table key, and compressing the data for efficient storage.
-
Partitioning can be extended to multiple nodes.
-
Designed as an OLAP database, can perform aggregation quickly, distributing the calculation over the different nodes, and for each node, using all available CPUs
Unlike other recent OLAP database, such as QuestDB, the partitioning key is free to use any column designed, thus supporting splitting the data over both space and time. The following is an example of table creation, using the simplest partitioning engine available in ClickHouse:
CREATE TABLE IF NOT EXISTS s2
(
`zoneId` String,
`resolution` UInt8,
`date` DateTime,
`B01` UInt16,
`B02` UInt16,
`B03` UInt16,
`B04` UInt16,
`B05` UInt16,
`B06` UInt16,
`B07` UInt16,
`B08` UInt16,
`B09` UInt16,
`B10` UInt16,
`B11` UInt16,
`B12` UInt16,
`B8A` UInt16,
`NDVI` Float64,
`NDBI` Float64,
`NDWI` Float64
)
ENGINE = MergeTree()
PARTITION BY (substring(zoneId, 1, 6), date)
ORDER BY (resolution, date, zoneId)
Highlights:
-
The partitioning engine is mandatory in ClickHouse, all tables have to be partitioned.
-
The partitions are constructed using the first six characters of the zoneId, and the date.
-
Each partition’s contents are sorted by resolution, date and zoneId.
This setup allows to quickly resolve queries like the following, extracting all the children
of zone P57624 at resolution 10.
SELECT *
FROM s2
WHERE zoneId like 'P57624%'
AND resolution = 10
For reference, the above structure supported storing all zones in the test area — around 10 million per DGGS type — in roughly 500MB per table. This is a couple of times larger than an equivalent compressed raster storage covering the same area [15], at the same resolution. However, there is advantage of a fast SQL aggregation engine built-in, and the freedom to mix columns of different data types.
The following query, computing the maximum value of the B01 over
the 8 million zones covering the test area at zoom level 11, ran in 0.015 seconds
[16]:
SELECT avg(B01)
FROM act_h3.s2
WHERE resolution = 11
9.5. Importing data in ClickHouse
As part of the Testbed activities, GeoSolutions imported Sentinel 2 data covering the test area over two time slices, once for H3, and once for TB16-Pix.
The data import was performed using the following steps:
-
Using GDAL to translate the Sentinel 2 JPEG 2000, split band rasters into 13 bands TIFFs
-
Using Java and GeoTools for mosaicking and reading the Sentinel 2 data, sampling it at the center of each resolution 11 zone intersecting the test area, computing the NDVI/NDBI/NDWI indexes, and inserting the result in ClickHouse
-
Performing simple aggregation queries to compute the average value of each band and index in parent cells, based on the values of the children cells.
In particular, the Java program for H3 used 16 parallel threads to perform the sampling, loading the 9 million zones in the database in 25 seconds. The generation of all upper levels, by aggregation query in ClickHouse, completed in 1.5 seconds.
The following sample query created all resolution 10 H3 zones, aggregating the values of their direct children at resolution 11, but only when all the children of a given parent zone were available. The query leverages ClickHouse native H3 support functions:
INSERT INTO s2
SELECT h3ToString(h3ToParent(stringToH3(zoneId), toUInt8(resolution - 1))),
resolution - 1,
max(date),
round(avg(B01)),
round(avg(B02)),
round(avg(B03)),
round(avg(B04)),
round(avg(B05)),
round(avg(B06)),
round(avg(B07)),
round(avg(B08)),
round(avg(B09)),
round(avg(B10)),
round(avg(B11)),
round(avg(B12)),
round(avg(B8A)),
(avg(B08) - avg(B04)) / (avg(B08) + avg(B04)),
(avg(B11) - avg(B08)) / (avg(B11) + avg(B08)),
(avg(B03) - avg(B08)) / (avg(B03) + avg(B08))
FROM s2
where resolution = 11
and date = '2020-09-06 00:00:00'
group by h3ToParent(stringToH3(zoneId), toUInt8(resolution - 1)), resolution
having count(*) = length(h3ToChildren(h3ToParent(stringToH3(zoneId), toUInt8(resolution - 1)), resolution))
The equivalent rHEALPix query can be built using simple string manipulations (the parent of a zone can be obtained by removing the last character from the zone id) and has a simpler "having" condition, considering a rHEALPix zone always has 9 children:
INSERT INTO s2
SELECT substring(zoneId, 1, length(zoneId) - 1),
resolution - 1,
max(date),
round(avg(B01)),
round(avg(B02)),
round(avg(B03)),
round(avg(B04)),
round(avg(B05)),
round(avg(B06)),
round(avg(B07)),
round(avg(B08)),
round(avg(B09)),
round(avg(B10)),
round(avg(B11)),
round(avg(B12)),
round(avg(B8A)),
(avg(B08) - avg(B04)) / (avg(B08) + avg(B04)),
(avg(B11) - avg(B08)) / (avg(B11) + avg(B08)),
(avg(B03) - avg(B08)) / (avg(B03) + avg(B08))
FROM s2
where resolution = 11
and date = '2020-09-06 00:00:00'
group by substring(zoneId, 1, length(zoneId) - 1), resolution
having count(*) = 9
9.6. The ClickHouse DGGS data store
A second data store was written in GeoServer, reading data from ClickHouse tables satisfying the following structure:
-
An string column named
zoneId -
An integer column named
resolution -
Any other attribute column
Similar to the geometry DGGS store, this store has no ties to a particular DGGS implementation, and requires the administration to declare which one to use when connecting to a database, in addition to common parameters such as database server host, port, database name, username and password.
The store then makes available to GeoServer all tables matching the above conditions as feature collections, which can be configured as layers and consumed via the classic OGC services.
The figures in Table 38 visually compares H3 and TB16-Pix maps of the NDVI index over the test area, gently zooming in first, and then displaying a lake at the highest resolution. One of the two systems looks more fine-grained than the other. This is actually just an illusion, the issue being that the size of the zones in the two systems are not aligned.
| H3 | TB16-Pix |
|---|---|
An interesting observation is to see how the store translates the bounding box request from a WMS endpoint into an efficient ClickHouse query. Here is a reference WMS request:
Table 39 shows the resulting rendering, and on the side, a map with the zone identifiers:
| NDVI map | Zone identifiers |
|---|---|
The resulting database query looks as follows:
SELECT "zoneId","date","NDVI"
FROM "act_rpix"."s2" WHERE
("date" = '2020-09-06 02:00:00.0' AND
"zoneId" LIKE 'P67307%' AND "resolution" = 6) OR
"zoneId" LIKE 'P67306%' AND "resolution" = 6) OR
"zoneId" LIKE 'P67304%' AND "resolution" = 6) OR
"zoneId" LIKE 'P67303%' AND "resolution" = 6) OR
"zoneId" IN ('P673320', 'P673312', 'P673311', 'P673310', 'P673302',
'P673301', 'P673300', 'P673086', 'P673083', 'P673080', 'P673056',
'P673053', 'P673050', 'P673026', 'P673018', 'P673017', 'P673016',
'P673008', 'P673007', 'P673006', 'P665522', 'P665288', 'P665285',
'P665282', 'P665258', 'P665255', 'P665252', 'P665228')
)
In other words, the system recognizes some of the zones are fully covered by their parent, and as a result, a query against the parent prefix identifier is done, selecting only the zones at the desired resolution.
Using the viewparams=resoffset:1 vendor parameter to retrieve zones at resolution level 7 in the
same area does not change the structure of the generated query,
the system still recognizes P67307, P67307, P67304 and P67303 are covering most of the map.
Therefore the "like" portion of the query is unchanged.
However, the "in" portion of it has a different (and longer) list of zones partially intersecting the bounding box.
This approach helps keeping the queries small, which is particularly important when trying to render a large number of zones using the resolution offset vendor parameter.