diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d0c0c4c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +* text eol=lf +*.png binary diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1b5d3c4..090c9c4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: check: needs: build name: Check - uses: Logius-standaarden/Automatisering/.github/workflows/check.yml@main + uses: Logius-standaarden/Automatisering/.github/workflows/check.yml@main publish: needs: build name: Publish (Logius) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4ea99c2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,395 @@ +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/README.md b/README.md index fffa1f0..68d6879 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,23 @@ # API Design Rules Module: Geospatial -## Deze handreiking - -### Publicatieversie - -https://gitdocumentatie.logius.nl/publicatie/api/mod-geo - -### Werkversie - -https://logius-standaarden.github.io/API-mod-geospatial/ - -## Issues - -Issues mogen bij het Kennisplatform API's worden ingediend. - -https://github.com/Geonovum/KP-APIs/issues +### Links + +- NLgov REST API Design Rules (ADR) + - [Formele standaard](https://forumstandaardisatie.nl/open-standaarden/rest-api-design-rules) + - [Gepubliceerde versie](https://gitdocumentatie.logius.nl/publicatie/api/adr/) + - [Werkversie](https://logius-standaarden.github.io/API-Design-Rules/) + - [Repository](https://github.com/Logius-standaarden/API-Design-Rules) + +- NLgov Assurance profile for OAuth 2.0 (OAuth) + - [Formele standaard](https://forumstandaardisatie.nl/open-standaarden/nl-gov-assurance-profile-oauth-20) + - [Gepubliceerde versie](https://gitdocumentatie.logius.nl/publicatie/api/oauth/) + - [Werkversie](https://logius-standaarden.github.io/OAuth-NL-profiel/) + - [Repository](https://github.com/Logius-standaarden/OAuth-NL-profiel) + +- NLgov Assurance profile for OpenID Connect 1.0 (OIDC) + - [Formele standaard](https://forumstandaardisatie.nl/open-standaarden/nl-gov-assurance-profile-oidc) + - [Gepubliceerde versie](https://gitdocumentatie.logius.nl/publicatie/api/oidc/) + - [Werkversie](https://logius-standaarden.github.io/OIDC-NLGOV/) + - [Repository](https://github.com/Logius-standaarden/OIDC-NLGOV) + +Het **Beheermodel** voor deze standaarden is gepubliceerd op: https://gitdocumentatie.logius.nl/publicatie/api/beheermodel/ diff --git a/appendix.md b/appendix.md deleted file mode 100644 index 4a4c93f..0000000 --- a/appendix.md +++ /dev/null @@ -1,85 +0,0 @@ -# Deprecated rules -This appendix contains some of the rules that were described in the [first version](https://docs.geostandaarden.nl/api/API-Strategie-ext/#geospatial) of the "Geospatial Extension", which was never officially adopted as a standard. Only those rules that are still relevant in some situations or do not have a good replacement in the current Geospatial model are retained here. They are shown here only as information. - -## POST endpoint for geospatial queries - - - -A spatial filter can be complex and large. It is best practice to supply complex queries in the body, not in the request URI. Since `GET` may not have a payload (although supported by some clients) use a `POST` request to a separate endpoint. For example, a GEO query to all *panden* where the geometry in the field `_geo` (there may be multiple geometry fields) contains a GeoJSON object (in this case a `Point`, so one coordinate pair): - - -

Deprecated rule (was: API-36): Provide a POST endpoint for geo queries

- -Spatial queries are sent in a `POST` to a dedicated endpoint. -
-  // POST /api/v1/panden/_zoek with request body:
-  {
-    "_geo": {
-      "contains": {
-        "type": "Point",
-        "coordinates": [5.9623762, 52.2118093]
-      }
-    }
-  }
-  
- -Other geospatial operators like `intersects` or `within` can be used as well. - - -

Deprecated rule (was: API-37): Support mixed queries at POST endpoints

- -The `POST` endpoint is preferably set up as a generic query endpoint to support combined queries: - -
-  // POST /api/v1/panden/_zoek with request body:
-  {
-    "_geo": {
-      "contains": {
-        "type": "Point",
-        "coordinates": [5.9623762, 52.2118093]
-      }
-    },
-    "status": "Actief"
-  }
-  
- -## Old CRS negotiation method - - - - -

Deprecated rule (was: API-40): Pass the coordinate reference system (CRS) of the request and the response in the headers

- -The coordinate reference system (CRS) for both the request and the response are passed as part of the request headers and response headers. In case this header is missing, send the HTTP status code `412 Precondition Failed`. - -The following headers are purely meant for negotiation between the client and the server. Depending on the application, the request not only contains geometries but also specific meta data, e.g. the original realization including the collection date. - -Request and response may be based on another coordinate reference system. This applies the HTTP-mechanism for content negotiation. The CRS of the geometry in the request (request body) is specified using the header `Content-Crs`. - -|HTTP header|Value|Explanation| -|-|-|-| -|`Content-Crs`|EPSG:4326|CRS84, global| -|`Content-Crs`|EPSG:3857|WGS 84 Pseudo Mercator, global| -|`Content-Crs`|EPSG:4258|ETRS89, European| -|`Content-Crs`|EPSG:28992|RD, Dutch| - -The preferred CRS for the geometry in the response (response body) is specified using the header `Accept-Crs`. - -|HTTP header|Value|Explanation| -|-|-|-| -|`Accept-Crs`|EPSG:4326|CRS84, global| -|`Accept-Crs`|EPSG:3857|WGS 84 Pseudo Mercator, global| -|`Accept-Crs`|EPSG:4258|ETRS89, European| -|`Accept-Crs`|EPSG:28992|RD, Dutch| - -

Deprecated rule (was: API-41): Use content negotiation to serve different CRSs

- -The CRS for the geometry in the response body is defined using the `Accept-Crs` header. In case the API does not support the requested CRS, send the HTTP status code `406 Not Acceptable`. diff --git a/crs.md b/crs.md deleted file mode 100644 index a31094a..0000000 --- a/crs.md +++ /dev/null @@ -1,244 +0,0 @@ -# Coordinate Reference System (CRS) - -A Coordinate Reference System (CRS) or Spatial Reference System (SRS) is a framework to measure locations on the earth surface as coordinates. Geometries consist of coordinates. To be able to measure the geometry's coordinates on the earth surface a CRS is required in conjunction with the coordinates. - -CRSs are uniquely identified by means of a Spatial Reference System Identifier (SRID). -SRIDs may refer to different standards, for example EPSG Geodetic Parameter Dataset or Open Geospatial Consortium (OGC). - -CRSs may be grouped into ensemble CRSs, e.g. ETRS89 (EPSG:4258). The CRSs that are part of an ensemble CRS are called ensemble member CRSs or member CRSs that realize a ensemble CRS, e.g ETRF2000 (EPSG:9067) is a member of and realizes the ETRS89 (EPSG:4258) ensemble. When exchanging geometry an ensemble member CRS shall be used instead of an ensemble CRS when known and if accurate data is required. When transforming geometry from one CRS to another, use an ensemble member CRS (instead of an ensemble CRS) as input and output of coordinate transformation, when known and if accurate data is required. - -For a detailed description of CRSs see [[hr-crs]]. - - - -## CRS discovery - -A client shall be able to determine a list of CRSs supported by an API. - -
-

/geo/crs-list: Provide a list of all CRSs that are supported by the API

-

If a REST API shall comply to the OGC API Features specification then the API must provide an endpoint to determine a list of supported CRSs.

-
-  // GET /api/v1/collections:
-

How to test

- - -

If a REST API does not have to comply to the OGC API Features specification, e.g. when the API is used for administrative purposes, then the API shall also provide an endpoint to determine the supported CRSs.

-
-  // GET /api/v1/crss:
-

How to test

- -
- -According to [OGC API Features - part 1 - 7.13. Feature collections](https://docs.opengeospatial.org/is/17-069r3/17-069r3.html#_collections_) an OGC API Features API shall provide a GET operation on the `/collections` endpoint which returns a collections object. - -OGC API Features - part 2 - Coordinate Reference Systems by Reference [[ogcapi-features-2]] describes how to support different CRSs in your geospatial API. According to [OGC API Features - part 2 - 6.2 Discovery](https://docs.ogc.org/is/18-058/18-058.html#crs-discovery) and in particular [Global list of CRS identifiers](https://docs.ogc.org/is/18-058/18-058.html#_global_list_of_crs_identifiers), a collections object provided by the API's `/collections` endpoint may contain a global list of supported CRSs by means of the `crs` property. This global CRS list applies to all feature collections delivered by the API, unless otherwise stated at a feature collection. - -Each feature collection mentioned within the `collections` list may also contain a `crs` property if the set of supported CRSs differs from the global CRS list. -If a feature collection supports exactly the same CRSs as mentioned in the global CRS list, then the `crs` property may be omitted. - -If a feature collection supports additional CRSs compared to the global CRS list in the collections object, then a reference to the global CRS list `#/crs` may be added in the feature collection object and the URIs of the additional CRSs are added to the CRS list in the `crs` property of the feature collection. - -If a feature collection supports a different set of CRSs than the set defined in the global CRS list, then a reference to the global CRS list is omitted and only the URIs of the supported CRSs are added to the CRS list in the `crs` property of the feature collection. - -For clients, it may be helpful to know the CRS identifier that may be used to retrieve features from that collection without the need to apply a CRS transformation. If all features in a feature collection are stored using a particular CRS, the property `storageCRS` shall be used to specify this CRS, in accordance with [OGC API Features - part 2 - 6.2.2 Storage CRS](https://docs.ogc.org/is/18-058/18-058.html#_storage_crs). The value of this property shall be one of the CRSs supported by the API and advertised in the CRS list as stated in requirement 4 of [OGC API Features - part 2 - 6.2.2 Storage CRS](https://docs.ogc.org/is/18-058/18-058.html#_storage_crs). If relevant, the epoch should also be specified, using the `storageCRSCoordinateEpoch` property. For an explanation of the use of epochs with CRS, see the CRS Guidelines [[hr-crs]]. - -
-

/geo/storage-crs: Make known in which CRS the geospatial data is stored by specifying the property storageCrs in the collection object.

-

The value of this property shall be one of the CRSs the API supports.

-

How to test

- -
- -## CRS negotiation - -The default CRS for GeoJSON and for OGC API Features is CRS84 (OGC:CRS84), this CRS uses the WGS 84 datum with an ellipsoidal coordinate system in the order longitude-latitude. This refers to an ensemble of global CRSs that can be applied world-wide. For accurate applications the use of the CRS84 ensemble is not suitable. For more information about coordinate reference systems, read the Geonovum guidelines on CRS [[hr-crs]]. - - - -Since most client-side mapping libraries use WGS 84 longitude-latitude (CRS84), the W3C/OGC [Spatial Data on the Web](https://www.w3.org/2021/sdw/) working group recommends to use this as the default coordinate reference system. The API strategy caters for this supporting not only ETRS89 and RD, but also CRS84. - -The *default* CRS, i.e. the CRS which is assumed when not specified by either the API or the client, is CRS84, in line with GeoJSON and OGC API Features. - -
-

/geo/default-crs: Use CRS84 as the default coordinate reference system (CRS). Support CRS84 in line with OGC API Features Requirement 10.

-

The implication of this is, that if no CRS is explicitly included in the request, CRS84 is assumed. This rule also applies if the request uses POST.

-

How to test

- -
- -In addition, support for ETRS89 and/or RD is required. - - -
-

/geo/preferred-crs: Use ETRS89 and/or RD when required, as these are the preferred coordinate reference systems (CRS) for Dutch geospatial data. Follow the Dutch Guideline for the use of CRSs [[hr-crs]].

-

General usage of the European ETRS89 coordinate reference system (CRS) or RDNAP is preferred, but is not the default CRS. Hence, one of these CRSs has to be explicitly included in each request when one of these CRSs is desired in the response or used in a request.

-

How to test

- -
- -The guiding principles for CRS support: - -- Source systems record coordinates as they enter the system; -- The default CRS, CRS84, is listed first in the list of supported CRSs in the API; if the consumer does not specify the CRS it is assumed it uses the default. -- Coordinate reference systems API strategy: request/response in RD; ETRS89; CRS84; -- Use the latest version of [RDNAPTRANS™](https://docs.geostandaarden.nl/crs/crs/#transformatie-en-conversie-tussen-rdnap-en-etrs89) to transform RD to ETRS89 (correction grid); -- Which CRSs are supported in an API depends on context (e.g. user requirements) - see [Spatial Data on the Web Best Practice 7: Choose coordinate reference systems to suit your user's applications](https://www.w3.org/TR/sdw-bp/#bp-crs-choice) [[sdw-bp]]; -- Exchange format (notation) for ETRS89 and CRS84 (longitude, latitude) in decimal degrees, for example: (`5.96237626, 52.25502345`). The longitude and latitude are decimal numbers. The number of decimals in the fractional part may vary depending on the required accuracy. For an accuracy of 1 mm, 8 decimals in the fractional part are sufficient. See [Nauwkeurigheid van coördinaten](https://docs.geostandaarden.nl/crs/crs/#nauwkeurigheid-van-coordinaten) in [[hr-crs]]. -- Exchange format (notation) for RD (X, Y) in meters, for example: (`195427.520, 311611.840`). The X and Y coordinates are decimal numbers. The number of decimals in the fractional part may vary depending on the required accuracy. For an accuracy of 1 mm, 3 decimal places in the fractional part are sufficient. See [Nauwkeurigheid van coördinaten](https://docs.geostandaarden.nl/crs/crs/#nauwkeurigheid-van-coordinaten) in [[hr-crs]]. -- WGS 84 Pseudo Mercator (EPSG:3857) is rather inaccurate, but suitable for simple visualization of inprecise spatial data on the web, e.g. when it suffices if the data is recognizable on a map. WGS 84 Pseudo Mercator shall not be used for precise data that is meant for accurate spatial analysis. -- Use the CRS Guidelines [[hr-crs]] for coordinate transformations. -- Use an ensemble member CRS (instead of an ensemble CRS) for exchanging geometry, when known. -- Use an ensemble member CRS (instead of an ensemble CRS) as output of coordinate transformation, when known. -- APIs shall support and advertise both ensemble CRSs and ensemble member CRSs if geometry is exchanged and the CRS for the geometry is an ensemble member CRS. -- Under certain conditions WGS 84 can be made equal to e.g. ETRS89, this is called a 'null transformation', see [[hr-crs]]. If a null transformation is used to realize WGS 84, then the CRS (e.g. ETRS89) that is used to realize WGS 84 and the CRS for WGS 84 itself shall both be supported and advertised by an API. - -
-

/geo/ensemble-member-crs: When the API provides data in an ensemble CRS like WGS 84 or ETRS89 while it is known to what ensemble member CRS the data actually refers, this ensemble member should also be one of the CRSs supported by the API and advertised in the CRS list.

-

For example when 2D data is transformed from RD with RDNAPTRANS not only ETRS89 (EPSG:4258) should be supported but also ETRF2000 (EPSG::9067).

-

How to test

- -
- -The CRS can be specified for request and response individually using parameters or headers. - -
-

/geo/bbox-crs-query-parameter: Support passing the coordinate reference system (CRS) of the bounding box in the request as a query parameter

-

Support the OGC API Features part 2 bbox-crs parameter in conformance to the standard. -

-

If a bounding box is sent to the server without these parameters, the default CRS, CRS84, is assumed as specified in /geo/default-crs.

-

If an invalid value, i.e. a CRS which is not in the list of supported CRSs, is given for one of these parameters, the server responds with an HTTP status code `400`.

-

How to test

- -
- -
-

/geo/filter-crs-query-parameter: Support passing the coordinate reference system (CRS) of the geospatial filter in the request as a query parameter

-

Support the OGC API Features part 3 filter-crs parameter in conformance to the standard. -

-

If a geospatial filter is sent to the server without these parameters, the default CRS, CRS84, is assumed as specified in /geo/default-crs.

-

If an invalid value, i.e. a CRS which is not in the list of supported CRSs, is given for one of these parameters, the server responds with an HTTP status code `400`.

-

How to test

- -
- -In an API that supports the creation and/or updating of items, POST, PUT or PATCH requests with geospatial content in the body may be sent by a client to the server. In that case, it is necessary to indicate the CRS used, unless CRS84 (OGC:CRS84), the default CRS, is used. - -
-

/geo/content-crs-request-header: When HTTP POST, PUT and/or PATCH requests are supported, pass the coordinate reference system (CRS) of geometry in the request body as a header

-

Support the OGC API Features part 4 Content-Crs header in conformance to the standard.

-

Alternatively, if the feature representation supports expressing CRS information for each feature / geometry, the information can also be included in the feature representation. If no CRS is asserted, the default CRS, CRS84, is assumed, as stated in /geo/default-crs.

-

How to test

-

In a request (i.e. when creating or updating an item on the server):

- -

Repeat with a similar test voor PUT and/or PATCH if the server supports these.

-
- -
-

/geo/crs-query-parameter: Support passing the desired coordinate reference system (CRS) of the geometry in the response as a query parameter

-

Support the OGC API Features part 2 crs parameter in conformance to the standard. -

-

How to test

- -
- -
-

/geo/content-crs-response-header: Assert the coordinate reference system (CRS) used in the response using a header

-

Support the OGC API Features part 2 Content-Crs header in conformance to the standard. -

-

How to test

- -
- -The API should be able to handle the following scenarios based on the rules stated above: - -| Scenario | Explanation | -| ----------------------------------------------- | ----------- | -| No geometry in request, no geometry in response | No CRS negotiation necessary | -| No geometry in request, geometry in response | The client can request a specific CRS for the geometries in the response using the `crs` parameter. The server indicates the geometry CRS in the response using the `Content-Crs` header. | -| Geometry in request body, no geometry in response | The client indicates the CRS of the geometry in the request body using the `Content-Crs` header. | -| Geometry in request body, geometry in response | The client indicates the CRS of the geometry in the request body using the `Content-Crs` header, and can request a specific CRS for the geometries in the response using the `crs` parameter. The server indicates the geometry CRS in the response using the `Content-Crs` header. | -| Geometry filter in request, no geometry in response | The client indicates the CRS of the geometry filter in the request using the `bbox-crs` parameter if a bounding box is used to filter geospatially, or the `filter-crs` parameter if another way of geospatial filtering is used.| -| Geometry filter in request, geometry in response | The client indicates the CRS of the geometry filter in the request using `bbox-crs` or `filter-crs` as in the previous scenario, and requests a specific CRS for the geometries in the response using the `crs` parameter. The server indicates the geometry CRS in response using the `Content-Crs` header.| - -Below is a list of the most commonly used CRSs in the Netherlands: - -| Name | Code | Type | Dimension | Scope | URI | -|-|-|-|-|-|-| -| Amersfoort / RD New | 28992 | easting, northing (x, y) | 2D | Dutch | http://www.opengis.net/def/crs/EPSG/9.9.1/28992 | -| Amersfoort / RD New + NAP height | 7415 | easting, northing, height (x, y, h) | 3D | Dutch | http://www.opengis.net/def/crs/EPSG/9.9.1/7415 | -| ETRS89 | 4258 | latitude, longitude (φ, λ) |2D | European | http://www.opengis.net/def/crs/EPSG/9.9.1/4258 | -| ETRS89 | 4937 | latitude, longitude, height (φ, λ, h) | 3D | European | http://www.opengis.net/def/crs/EPSG/9.9.1/4937 | -| ETRF2000 | 7931 | latitude, longitude, height (φ, λ, h) | 3D | European | http://www.opengis.net/def/crs/EPSG/9.9.1/7931 | -| ETRF2000 | 9067 | latitude, longitude (φ, λ) | 2D | European | http://www.opengis.net/def/crs/EPSG/9.9.1/9067 | -| ITRF2014 | 7912 | latitude, longitude, height (φ, λ, h) | 3D | Global | http://www.opengis.net/def/crs/EPSG/9.9.1/7912 | -| ITRF2014 | 9000 | latitude, longitude (φ, λ) | 2D | Global | http://www.opengis.net/def/crs/EPSG/9.9.1/9000 | -| WGS 84 longitude-latitude | CRS84 | longitude, latitude (λ, φ) | 2D | Global | http://www.opengis.net/def/crs/OGC/1.3/CRS84 | -| WGS 84 longitude-latitude-height | CRS84h | longitude, latitude, height (λ, φ, h) | 3D | Global | http://www.opengis.net/def/crs/OGC/0/CRS84h | -| WGS 84 / Pseudo-Mercator | 3857 | easting, northing (x, y) | 2D | Global | http://www.opengis.net/def/crs/EPSG/9.9.1/3857 | - -For a more extensive overview of CRSs see: https://docs.geostandaarden.nl/crs/crs/#bijlage-a-crs-overzicht-tabel. -Note that the URI of each CRS contains a version number and that new versions may be released in future. -Before using a URI verify if newer versions are available and use the latest version. - - - - - -## CRS transformation - -If the requested CRS is not the same as the storage CRS, a coordinate transformation is needed. Performance is increased when the dataset is transformed in multiple CRSs and stored in advance, and not transformed at the moment the request has arrived. In case of a transformation between RD and ETRS89, it is required that this transformation uses the latest version of the procedure of [RDNAPTRANS™](https://docs.geostandaarden.nl/crs/crs/#transformatie-en-conversie-tussen-rdnap-en-etrs89). \ No newline at end of file diff --git a/index.html b/index.html index 43a7fe1..d9667df 100644 --- a/index.html +++ b/index.html @@ -1,37 +1,36 @@ - - - + + + + + - API Design Rules Module: Geospatial + API Design Rules Module: Geospatial - - - - - - - -
+ + + +
-
-
-
+
-
+
-
+
-
+
- - + + + \ No newline at end of file diff --git a/js/config.js b/js/config.js deleted file mode 100644 index e659699..0000000 --- a/js/config.js +++ /dev/null @@ -1,85 +0,0 @@ -globalThis.respecConfig = { - pubDomain: "api", - shortName: "mod-geo", - specType: "HR", - specStatus: "DEF", - publishDate: "2025-05-22", - publishVersion: "1.0.3", - previousPublishDate: "2024-03-07", - previousPublishVersion: "1.0.2", - previousMaturity: "DEF", - editors: [{ - name: "Linda van den Brink", - company: "Geonovum", - companyURL: "https://www.geonovum.nl", - }, ], - authors: [{ - name: "Pieter Bresters", - company: "Geonovum", - companyURL: "https://www.geonovum.nl", - }, { - name: "Linda van den Brink", - company: "Geonovum", - companyURL: "https://www.geonovum.nl", - }, { - name: "Paul van Genuchten", - company: "ISRIC", - companyURL: "https://www.isric.org", - }, { - name: "George Mathijssen", - company: "Sweco Nederland B.V.", - companyURL: "https://www.sweco.nl", - }, { - name: "Mark Strijker", - company: "Het Kadaster", - companyURL: "https://www.kadaster.nl", - }, ], - github: "https://github.com/Logius-standaarden/API-mod-geospatial/", - localBiblio: { - "hr-crs": { - href: "https://docs.geostandaarden.nl/crs/crs/", - title: "Handreiking Gebruik coördinaatreferentiesystemen bij uitwisseling en visualisatie van geo-informatie", - authors: ["Lennard Huisman", "Friso Penninga"], - status: "Vastgesteld", - publisher: "Geonovum", - }, - "ogcapi-features-1": { - href: "http://docs.ogc.org/is/17-069r3/17-069r3.html", - title: "OGC API - Features - Part 1: Core", - editors: ["Clemens Portele", "Panagiotis (Peter) A. Vretanos", "Charles Heazel"], - status: "Approved", - publisher: "Open Geospatial Consortium", - version: "1.0" - }, - "ogcapi-features-2": { - href: "https://docs.ogc.org/is/18-058/18-058.html", - title: "OGC API - Features - Part 2: Coordinate Reference Systems by Reference", - editors: ["Clemens Portele", "Panagiotis (Peter) A. Vretanos"], - status: "Approved", - publisher: "Open Geospatial Consortium", - version: "1.0" - }, - "ogcapi-features-3": { - href: "https://docs.ogc.org/is/19-079r2/19-079r2.html", - title: "OGC API - Features - Part 3: Filtering", - editors: ["Panagiotis (Peter) A. Vretanos", "Clemens Portele"], - status: "Draft", - publisher: "Open Geospatial Consortium", - version: "1.0.0-rc.1" - }, - "JSON-FG": { - href: "https://docs.ogc.org/DRAFTS/21-045.html", - title: "OGC Features and Geometries JSON - Part 1: Core", - editors: ["Clemens Portele", "Panagiotis (Peter) A. Vretanos"], - status: "Editor's Draft", - publisher: "Open Geospatial Consortium", - version: "0.1" - }, - "HAL": { - href: "http://stateless.co/hal_specification.html", - title: "HAL - Hypertext Application Language", - authors: ["Mike Kelly"], - date: " 2013-09-18", - }, - }, -}; diff --git a/js/config.mjs b/js/config.mjs new file mode 100644 index 0000000..60b6f43 --- /dev/null +++ b/js/config.mjs @@ -0,0 +1,89 @@ +import { processRuleBlocks } from "https://logius-standaarden.github.io/publicatie/respec/plugins/adr.mjs"; +import { loadRespecWithConfiguration } from "https://logius-standaarden.github.io/publicatie/respec/organisation-config.mjs"; + +loadRespecWithConfiguration({ + pubDomain: "api", + shortName: "mod-geo", + specType: "HR", + specStatus: "DEF", + publishDate: "2025-06-04", + publishVersion: "1.0.4", + previousPublishDate: "2025-05-22", + previousPublishVersion: "1.0.3", + previousMaturity: "DEF", + editors: [{ + name: "Linda van den Brink", + company: "Geonovum", + companyURL: "https://www.geonovum.nl", + },], + authors: [{ + name: "Pieter Bresters", + company: "Geonovum", + companyURL: "https://www.geonovum.nl", + }, { + name: "Linda van den Brink", + company: "Geonovum", + companyURL: "https://www.geonovum.nl", + }, { + name: "Paul van Genuchten", + company: "ISRIC", + companyURL: "https://www.isric.org", + }, { + name: "George Mathijssen", + company: "Sweco Nederland B.V.", + companyURL: "https://www.sweco.nl", + }, { + name: "Mark Strijker", + company: "Het Kadaster", + companyURL: "https://www.kadaster.nl", + },], + github: "https://github.com/Logius-standaarden/API-mod-geospatial/", + localBiblio: { + "hr-crs": { + href: "https://docs.geostandaarden.nl/crs/crs/", + title: "Handreiking Gebruik coördinaatreferentiesystemen bij uitwisseling en visualisatie van geo-informatie", + authors: ["Lennard Huisman", "Friso Penninga"], + status: "Vastgesteld", + publisher: "Geonovum", + }, + "ogcapi-features-1": { + href: "http://docs.ogc.org/is/17-069r3/17-069r3.html", + title: "OGC API - Features - Part 1: Core", + editors: ["Clemens Portele", "Panagiotis (Peter) A. Vretanos", "Charles Heazel"], + status: "Approved", + publisher: "Open Geospatial Consortium", + version: "1.0" + }, + "ogcapi-features-2": { + href: "https://docs.ogc.org/is/18-058/18-058.html", + title: "OGC API - Features - Part 2: Coordinate Reference Systems by Reference", + editors: ["Clemens Portele", "Panagiotis (Peter) A. Vretanos"], + status: "Approved", + publisher: "Open Geospatial Consortium", + version: "1.0" + }, + "ogcapi-features-3": { + href: "https://docs.ogc.org/is/19-079r2/19-079r2.html", + title: "OGC API - Features - Part 3: Filtering", + editors: ["Panagiotis (Peter) A. Vretanos", "Clemens Portele"], + status: "Draft", + publisher: "Open Geospatial Consortium", + version: "1.0.0-rc.1" + }, + "JSON-FG": { + href: "https://docs.ogc.org/DRAFTS/21-045.html", + title: "OGC Features and Geometries JSON - Part 1: Core", + editors: ["Clemens Portele", "Panagiotis (Peter) A. Vretanos"], + status: "Editor's Draft", + publisher: "Open Geospatial Consortium", + version: "0.1" + }, + "HAL": { + href: "http://stateless.co/hal_specification.html", + title: "HAL - Hypertext Application Language", + authors: ["Mike Kelly"], + date: " 2013-09-18", + }, + }, + postProcess: [processRuleBlocks], +}); diff --git a/request-response.md b/request-response.md deleted file mode 100644 index e512503..0000000 --- a/request-response.md +++ /dev/null @@ -1,519 +0,0 @@ -# Request and response - -Providing requested resources is the essence of any API. This also applies to REST APIs that handle geospatial data. There are, however, some specific aspects when dealing with geospatial data in REST APIs. The most important aspects are described in this chapter: -- how to encode geometries in APIs -- how to supply a spatial filter in the call (request) -- how to return results of a spatial search - -When requesting information, for example about cadastral parcels, users do not necessarily require the geometry, even if they used a spatial filter. A name or parcel ID may be sufficient. - - - -## GeoJSON - -[[rfc7946]] describes the GeoJSON format, including a convention for describing 2D geometric objects in CRS84 (OGC:CRS84). In the Geospatial module of the API strategy we adopt the GeoJSON conventions for describing geometry objects. The convention is extended to allow alternative projections. -The GeoJSON conventions and extensions described in this module apply to both geometry passed in input parameters and responses. - - - - -

Example of embedding WKT in a JSON object using the following definition for a JSON object:

-
-  building:
-    type: object
-    required:
-      - geometry
-    properties:
-      geometry:
-        type: string
-        format: wkt
-  
-

Sample response:

-
-  {
-    "building": {
-      "geometry": "POLYGON Z((194174.445 465873.676 0, 194174.452 465872.291 0, 194158.154 465872.213 0, 194158.226 465856.695 0, 194223.89 465856.969 0, 194223.821 465872.48 0, 194207.529 465872.415 0, 194207.505 465882.528 0, 194207.498 465883.902 0, 194223.799 465883.967 0, 194223.732 465899.48 0, 194216.55 465899.45 0, 194215.15 465899.445 0, 194213.85 465899.439 0, 194158.068 465899.211 0, 194158.148 465883.685 0, 194174.42 465883.767 0, 194174.445 465873.676 0))"
-    }
-  }
-  
- -

Example of embedding WKB in a JSON object using the following definition for a JSON object:

-
-  building:
-    type: object
-    required:
-      - geometry
-    properties:
-      geometry:
-        type: string
-        format: wkb
-  
-

Sample response:

-
-  {
-    "building": {
-      "geometry": "01030000A0F71C00000100000012000000F6285C8FF3B30741105839B4466F1C4100000000000000000E2DB29DF3B307416DE7FB29416F1C4100000000000000001D5A643B71B3074108AC1CDA406F1C4100000000000000008716D9CE71B307417B14AEC7026F1C410000000000000000EC51B81E7FB50741378941E0036F1C410000000000000000B07268917EB50741B81E85EB416F1C4100000000000000001D5A643BFCB407418FC2F5A8416F1C410000000000000000A4703D0AFCB407413108AC1C6A6F1C4100000000000000008B6CE7FBFBB4074154E3A59B6F6F1C410000000000000000AC1C5A647EB507417D3F35DE6F6F1C410000000000000000E5D022DB7DB50741B81E85EBAD6F1C4100000000000000006666666644B50741CDCCCCCCAD6F1C4100000000000000003333333339B507417B14AEC7AD6F1C410000000000000000CDCCCCCC2EB507414C3789C1AD6F1C4100000000000000008195438B70B307414E6210D8AC6F1C410000000000000000BE9F1A2F71B30741D7A370BD6E6F1C410000000000000000C3F5285CF3B30741B07268116F6F1C410000000000000000F6285C8FF3B30741105839B4466F1C410000000000000000"
-    }
-  }
-  
- -## Call (requests) - -A simple spatial filter can be supplied as a bounding box. This is a common way of filtering spatial data and can be supplied as a parameter. We adopt the OGC API Features [[ogcapi-features-1]] bounding box parameter: - -
-

/geo/bbox-query-parameter: Supply a simple spatial filter as a bounding box parameter

-

Support the OGC API Features part 1 bbox query parameter in conformance to the standard.

-
-    GET /api/v1/buildings?bbox=5.4,52.1,5.5,53.2
-

Note that if a resource contains multiple geometries, it is up to the provider to decide if geometries of type single geometry or type multiple geometry are returned and that the provider shall clearly document this behavior. -

-

The default spatial operator intersects is used to determine which resources are returned. -

-

Due to possible performance issue, especially when a combination of filters is used, a provider may decide to limit the size of the bounding box or the number of results. It is also up to the provider to decide if an error is returned in such cases. - The provider shall clearly document this behavior. -

-

- The provider shall be able to provide resources that do not have a geometry property and are related to resources that match the bounding box filter. -

-

An error shall be given if the provided coordinates are outside the specified coordinate reference system. -

-

How to test

-
    -
  • Issue an HTTP GET request to the API, including the bbox query parameter and using CRS Negotiation.
  • -
  • Validate that a response with status code 200 is returned.
  • -
  • Verify that only features that have a spatial geometry that intersects the bounding box are returned as part of the result set.
  • -
-
- - - - - - -
-

/geo/geometric-context: Place results of a global spatial query in the relevant geometric context

-

In case of a global query /api/v1/_search, results should be placed in the relevant geometric context, because results from different collections, i.e. different sets of resources of the same type, are retrieved. Express the name of the collection to which the results belong in the singular form using the property type. For example:

-
-  // POST /api/v1/_search:
-  {
-    "currentPage": 1,
-    "nextPage": 2,
-    "pageSize": 10,
-    "_embedded": {
-      "items": [
-        {
-          "type": "enkelbestemming",
-          "_links": {
-            "self": {
-              "href": "https://api.example.org/v1/enkelbestemmingen/1234"
-            }
-          }
-        },
-        {
-          "type": "dubbelbestemming",
-          "_links": {
-            "self": {
-              "href": "https://api.example.org/v1/dubbelbestemmingen/8765"
-            }
-          }
-        }
-      ]
-    }
-  }
-  
-

How to test

-
    -
  • Issue an HTTP GET request to the API.
  • -
  • Validate that the returned document contains the expected type property for each member.
  • -
-
- -In case a REST API shall comply to the OGC API Features specification for creating, updating and deleting a resource, the following applies. - - -
-

/geo/geojson-request: Support GeoJSON in geospatial API requests

-

For representing geometric information in an API, use the convention for describing geometry as defined in the GeoJSON format [[rfc7946]]. Support GeoJSON as described in OGC API Features part 4, but note that this standard is still in development.

- Example: POST feature -
-  // POST /collections/gebouwen/items   HTTP/1.1
-  // Content-Type: application/geo+json
-  {
-    "type": "Feature",
-    "geometry":  {
-      "type": "Point",
-      "coordinates": [5.2795,52.1933]
-    },
-    "properties": {
-      "naam": "Paleis Soestdijk",
-      ...
-    }
-  }
-  
- Example: POST feature collection -
-  // POST /collections   HTTP/1.1
-  // Content-Type: application/geo+json
-  {
-    "type": "FeatureCollection",
-    "features": [
-    {
-      "type": "Feature",
-      "geometry":  {
-        "type": "Point",
-        "coordinates": [5.2795,52.1933]
-      },
-      "properties": {
-        "naam": "Paleis Soestdijk",
-        ...
-      }
-    }]
-  }  
-  
-

How to test

-
    -
  • Create a new resource that includes feature content (i.e. coordinates) using the HTTP POST method with request media type application/geo+json in the Content-Type header.
  • -
  • Validate that a response with status code 201 (Created) is returned.
  • -
  • Validate that the response includes the Location header with the URI of the newly added resource. -
-
- -In case a REST API does not have to comply to the OGC API Features specification, e.g. for usage in administrative applications, the REST API shall use the JSON data format. If a resource contains geometry, that geometry shall be embedded as a GeoJSON Geometry object within the resource. The media type application/json must be supported. This may also apply to other media types application/*+json, however this depends on the media type specification. If the media type specification prescribes that resource information must be embedded in a JSON structure defined in the media specification, then the media type should not be supported while it is impossible to comply to that specification with the method described below. The media type application/geo+json should not be supported while the resource does not comply to the GeoJSON specification, i.e. the request resource does not embed a feature or feature collection. -A template for the definition of the schemas for the GeoJSON Geometry object in the requests in OpenAPI definitions is available: [geometryGeoJSON.yaml](https://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/schemas/geometryGeoJSON.yaml). -In case a collection of resources is embedded in the request resource, the name of the array containing the resources should be the plural of the resource name. - -
-

/geo/embed-geojson-geometry-request: Embed GeoJSON Geometry object as part of the JSON resource in API requests

-

When a JSON (application/json) request contains a geometry, represent it in the same way as the Geometry object of GeoJSON.

- Example: POST resource containing geometry -
-  // POST /collections/gebouwen/items   HTTP/1.1
-  // Content-Type: application/json
-  {
-    "naam": "Paleis Soestdijk",
-    "geometrie": {
-      "type": "Point",
-      "coordinates": [5.2795,52.1933]
-    }
-  }
-  
- Example: POST resource containing geometry collection -
-  // POST /collections/gebouwen/items   HTTP/1.1
-  // Content-Type: application/json
-  {
-    "naam": "Paleis Soestdijk",
-    "geometrie": {
-      "type": "GeometryCollection",
-      "geometries": [
-        {
-          "type": "Point",
-          "coordinates": [5.2795,52.1933]
-        }
-      ]
-    }
-  }
-  
- -

How to test

-
    -
  • Create a new resource that includes geometry of GeoJSON Geometry object type using the HTTP POST method with request media type application/json in the Content-Type header.
  • -
  • Validate that a response with status code 201 (Created) is returned.
  • -
  • Validate that the response includes the Location header with the URI of the newly added resource. -
-
- -## Result (response) - -In case a REST API shall comply to the OGC API Features specification, e.g. for usage in GIS applications, the following applies. - -
-

/geo/geojson-response: Support GeoJSON in geospatial API responsess

-

For representing 2D geometric information in an API response, use the convention for describing geometry as defined in the GeoJSON format [[rfc7946]]. Support GeoJSON as described in OGC API Features Requirements class 8.3 [[ogcapi-features-1]].

- Example: feature -
-  Request:
-  // GET /collections/gebouwen/items/0308100000022041   HTTP 1.1
-  // Content-type: application/geo+json
-
-  Response:
-  {
-    "type": "Feature",
-    "id": "0308100000022041",
-    "geometry":  {
-      "type": "Point",
-      "coordinates": [5.2795,52.1933]
-    },
-    "properties": {
-      "naam": "Paleis Soestdijk",
-      ...
-    },
-    "links": [
-      {
-        "self": "/collections/gebouwen/items/0308100000022041"
-      } 
-    ]
-  }
- - Example: feature collection -
-  Request:
-  // GET /collections/gebouwen   HTTP 1.1
-  // Content-type: application/geo+json
-
-  Response:
-  {
-    "type": "FeatureCollection",
-    "features": [
-      {
-        "type": "Feature",
-        "id": "0308100000022041",
-        "geometry":  {
-          "type": "Point",
-          "coordinates": [5.2795,52.1933]
-        },
-        "properties": {
-          "naam": "Paleis Soestdijk",
-          ...
-        },
-        "links": [
-          {
-            "self": "/collections/gebouwen/0308100000022041"
-          } 
-        ]
-      },
-      {
-      }
-    ],
-    "timeStamp" : "2023-02-22T10:32:23Z",
-    "numberMatched" : "0308100000022041",
-    "numberReturned" : "1",
-    "links": [
-      {
-        "self": "/collections/gebouwen"
-      },
-      {
-        "next": ""
-      }
-    ]
-  }
-

- Note that: - - - The resources' properties (e.g. naam) are passed in the properties object. Depending on the implemented filter capabilities the properties object may contain all or a selection of the resources' properties. - - The OGC API Features specification provides the possibility to add an array of links to a feature and feature collection, which may contain a self link and in case of a feature collection may contain navigation links. -

-

How to test

-

- Test case 1: -

-
    -
  • Request a single resource that includes feature content (i.e. coordinates) with response media type application/geo+json in the Accept header.
  • -
  • Validate that a response with status code 200 is returned.
  • -
  • Validate that Content-Type header contains application/geo+json
  • -
  • Validate that the returned document is a GeoJSON Feature document.
  • -
-

- Test case 2: -

-
    -
  • Request a collection of resources that includes feature content (i.e. coordinates) with response media type application/geo+json in the Accept header.
  • -
  • Validate that a response with status code 200 is returned.
  • -
  • Validate that Content-Type header contains application/geo+json
  • -
  • Validate that the returned document is a GeoJSON FeatureCollection document.
  • -
-

- Test case 3: -

-
    -
  • Request a single resource that does not include feature content (i.e. coordinates) with response media type application/geo+json or application/json in the Accept header.
  • -
  • Validate that a response with status code 200 is returned.
  • -
  • Validate that Content-Type header contains application/json
  • -
  • Validate that the returned document is a JSON document.
  • -
-

- Test case 4: -

-
    -
  • Request a collection of resources that do not include feature content (i.e. coordinates) with response media type application/geo+json or application/json in the Accept header.
  • -
  • Validate that a response with status code 200 is returned.
  • -
  • Validate that Content-Type header contains application/json
  • -
  • Validate that the returned document is a JSON document.
  • -
-
- -In case a REST API does not have to comply to the OGC API Features specification, e.g. for usage in administrative applications, the REST API shall use the JSON data format. If resources contain geometry, the geometry shall be returned as a GeoJSON Geometry object embedded in the resource. The media type application/json must be supported. This may also apply to other media types application/\*+json, however this depends on the media type specification. If the media type specification prescribes that resource information must be embedded in a JSON structure defined in the media type specification, then the media type should not be supported while it is impossible to comply to that specification with the method described below. The media type application/geo+json should not be supported while the resource does not comply to the GeoJSON specification, i.e. the response does not return a feature or feature collection. -A template for the definition of the schemas for the GeoJSON Geometry object in the responses in OpenAPI definitions is available: [geometryGeoJSON.yaml](https://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/schemas/geometryGeoJSON.yaml). -In case a collection of resources is returned, the name of the array containing the resources should be the plural of the resource name. - - -
-

/geo/embed-geojson-geometry-response: Embed GeoJSON Geometry object as part of the JSON resource in API responses

-

When a JSON (application/json) response contains a geometry, represent it in the same way as the Geometry object of GeoJSON.

- - Example: resource containing geometry -
-  Request:
-  // GET /gebouwen/0308100000022041   HTTP 1.1
-  // Content-type: application/hal+json
-
-  Response:
-  {
-    "identificatie": "0308100000022041",
-    "naam": "Paleis Soestdijk",
-    "geometrie":  {
-      "type": "Point",
-      "coordinates": [5.2795,52.1933]
-    },
-    ...,
-    "_links": {
-      {
-        "self": "/gebouwen/0308100000022041"
-      }
-    }
-  }
- - Example: resource containing geometry collection -
-  Request:
-  // GET /gebouwen/0308100000022041   HTTP 1.1
-  // Content-type: application/hal+json
-
-  Response:
-  {
-    "identificatie": "0308100000022041",
-    "naam": "Paleis Soestdijk",
-    "geometrie": {
-      "type": "GeometryCollection",
-      "geometries": [
-        {
-          "type": "Point"
-          "coordinates": [5.2795,52.1933]
-        },
-        {
-          "type": "Polygon"
-          "coordinates" : [...]
-        }
-      ]
-    },
-    ...,
-    "_links": {
-      {
-        "self": "/gebouwen/0308100000022041"
-      }
-    }
-  }
- - Example: collection of resources containing geometry -
-  Request:
-  // GET /gebouwen   HTTP 1.1
-  // Content-type: application/hal+json
-
-  Response:
-  {
-    "gebouwen": [
-      {
-        "identificatie": "0308100000022041",
-        "naam": "Paleis Soestdijk",
-        "geometrie":  {
-          "type": "Point",
-          "coordinates": [5.2795,52.1933]
-        }
-        ...
-        "_links": {
-          {
-            "self": "/gebouwen/0308100000022041"
-          }
-        }
-      }
-    ],
-    "_links": {
-      {
-        "self": "/gebouwen"
-      },
-      {
-        "next": ""
-      }
-    }
-  }
-

- Note that: - - - The resource and resource collection may be [[HAL]] resources and therefore may contain a `_links` object. The `_links` object should contain a self link and in case of a collection also navigation links (e.g. first, next prev, last). In such cases the application/hal+json media type may be used. -

-

How to test

-

- Test case 1: -

-
    -
  • Request a single resource that contains geometry of GeoJSON Geometry object type: Point, MultiPoint, LineString, MultiLineString, Polygon or MultiPolygon and with response media type application/json in the Accept header.
  • -
  • Validate that a response with status code 200 is returned.
  • -
  • Validate that Content-Type header contains application/json
  • -
  • Validate that the returned document is a JSON document.
  • -
  • Validate that the returned document contains a property that complies to one of the GeoJSON Geometry objects mentioned above and contains: -
      -
    • a property type containing the name of one of the GeoJSON Geometry object types mentioned above, and
    • -
    • a property coordinates containing an array with the coordinates. Depending on the type of geometry object, the content of the array differs.
    • -
  • -
-

- Test case 2: -

-
    -
  • Request a collection of resources that contain geometry of GeoJSON Geometry object type: Point, MultiPoint, LineString, MultiLineString, Polygon or MultiPolygon and with response media type application/json in the Accept header.
  • -
  • Validate that a response with status code 200 is returned.
  • -
  • Validate that Content-Type header contains application/json
  • -
  • Validate that the returned document is a JSON document.
  • -
  • Validate that the returned document contains an array of resources and that each resource contains a property that complies to one of the GeoJSON Geometry objects mentioned above and contains: -
      -
    • a property type containing the name of one of the GeoJSON Geometry object types mentioned above, and
    • -
    • a property coordinates containing an array with the coordinates. Depending on the type of geometry object, the content of the array differs.
    • -
  • -
-

- Test case 3: -

-
    -
  • Request a single resource that contains geometry of GeoJSON Geometry object type: GeometryCollection and with response media type application/json in the Accept header.
  • -
  • Validate that a response with status code 200 is returned.
  • -
  • Validate that Content-Type header contains application/json
  • -
  • Validate that the returned document is a JSON document.
  • -
  • Validate that the returned document contains a property that complies to the GeoJSON Geometry object mentioned above and contains: -
      -
    • a property type containing the name of the GeoJSON Geometry object type: GeometryCollection, and
    • -
    • a property geometries containing an array of GeoJSON Geometry objects.
    • -
  • -
-

- Test case 4: -

-
    -
  • Request a collection of resources that contain geometry of GeoJSON Geometry object type: GeometryCollection and with response media type application/json in the Accept header.
  • -
  • Validate that a response with status code 200 is returned.
  • -
  • Validate that Content-Type header contains application/json
  • -
  • Validate that the returned document is a JSON document.
  • -
  • Validate that the returned document contains an array of resources and that each resource contains a property that complies to the GeoJSON Geometry object mentioned above and contains: -
      -
    • a property type containing the name of the GeoJSON Geometry object type: GeometryCollection, and
    • -
    • a property geometries containing an array of GeoJSON Geometry objects.
    • -
  • -
-
diff --git a/abstract.md b/sections/abstract.md similarity index 52% rename from abstract.md rename to sections/abstract.md index 8bbb2f9..03c650a 100644 --- a/abstract.md +++ b/sections/abstract.md @@ -1,19 +1,19 @@ This document is part of the *Nederlandse API Strategie*. -The Nederlandse API Strategie consists of [a set of distinct documents](https://www.geonovum.nl/themas/kennisplatform-apis#APIStrategie). +The Nederlandse API Strategie consists of [a set of distinct documents](https://developer.overheid.nl/communities/kennisplatform-apis/#api-strategie). -| Status | Description & Link | -| ---------------- | ------------------------------------------------------------ | -| Informative | [Inleiding NL API Strategie](https://geonovum.github.io/KP-APIs/API-strategie-algemeen/Inleiding/) | -| Informative | [Architectuur NL API Strategie](https://geonovum.github.io/KP-APIs/API-strategie-algemeen/Architectuur/) | +| Status | Description & Link | +|------------------|------------------------------------------------------------------------------------------------------------------| +| Informative | [Inleiding NL API Strategie](https://geonovum.github.io/KP-APIs/API-strategie-algemeen/Inleiding/) | +| Informative | [Architectuur NL API Strategie](https://geonovum.github.io/KP-APIs/API-strategie-algemeen/Architectuur/) | | Informative | [Gebruikerswensen NL API Strategie](https://geonovum.github.io/KP-APIs/API-strategie-algemeen/Gebruikerswensen/) | -| Normative | [API Design Rules (ADR v2.0)](https://gitdocumentatie.logius.nl/publicatie/api/adr/2.0/) | -| Normative | [Open API Specification (OAS 3.0)](https://spec.openapis.org/oas/v3.0.1.html) | -| Normative | [NL GOV OAuth profiel](https://gitdocumentatie.logius.nl/publicatie/api/oauth/) | -| Normative | [Digikoppeling REST API koppelvlak specificatie](https://gitdocumentatie.logius.nl/publicatie/dk/restapi/) | -| Normative module | [GEO module v1.0](https://gitdocumentatie.logius.nl/publicatie/api/mod-geo/1.0.2/) | +| Normative | [NLgov REST API Design Rules (ADR v2.2)](https://gitdocumentatie.logius.nl/publicatie/api/adr/2.2/) | +| Normative | [Open API Specification (OAS 3.0)](https://spec.openapis.org/oas/v3.0.1.html) | +| Normative | [NLgov Assurance profile for OAuth 2.0](https://gitdocumentatie.logius.nl/publicatie/api/oauth/) | +| Normative | [Digikoppeling REST API koppelvlak specificatie](https://gitdocumentatie.logius.nl/publicatie/dk/restapi/) | +| Normative module | [GEO module v1.0](https://gitdocumentatie.logius.nl/publicatie/api/mod-geo/1.0.2/) | Before reading this document it is advised to gain knowledge of the informative documents, in particular the [Architecture](https://geonovum.github.io/KP-APIs/API-strategie-algemeen/Architectuur/). -This document describes the *Geospatial module*, containing rules for geospatial content and functions in APIs. \ No newline at end of file +This document describes the *Geospatial module*, containing rules for geospatial content and functions in APIs. diff --git a/sections/crs.md b/sections/crs.md new file mode 100644 index 0000000..d5835f3 --- /dev/null +++ b/sections/crs.md @@ -0,0 +1,307 @@ +# Coordinate Reference System (CRS) + +A Coordinate Reference System (CRS) or Spatial Reference System (SRS) is a framework to measure locations on the earth surface as coordinates. Geometries consist of coordinates. To be able to measure the geometry's coordinates on the earth surface a CRS is required in conjunction with the coordinates. + +CRSs are uniquely identified by means of a Spatial Reference System Identifier (SRID). +SRIDs may refer to different standards, for example EPSG Geodetic Parameter Dataset or Open Geospatial Consortium (OGC). + +CRSs may be grouped into ensemble CRSs, e.g. ETRS89 (EPSG:4258). The CRSs that are part of an ensemble CRS are called ensemble member CRSs or member CRSs that realize a ensemble CRS, e.g ETRF2000 (EPSG:9067) is a member of and realizes the ETRS89 (EPSG:4258) ensemble. When exchanging geometry an ensemble member CRS shall be used instead of an ensemble CRS when known and if accurate data is required. When transforming geometry from one CRS to another, use an ensemble member CRS (instead of an ensemble CRS) as input and output of coordinate transformation, when known and if accurate data is required. + +For a detailed description of CRSs see [[hr-crs]]. + + + +## CRS discovery + +A client shall be able to determine a list of CRSs supported by an API. + +
+

Provide a list of all CRSs that are supported by the API

+
+
Statement
+
+

If a REST API shall comply to the OGC API Features specification then the API must provide an endpoint to determine a list of supported CRSs.

+ +

If a REST API does not have to comply to the OGC API Features specification, e.g. when the API is used for administrative purposes, then the API shall also provide an endpoint to determine the supported CRSs.

+ +
+
Rationale
+
+

According to OGC API Features - part 1 - 7.13. Feature collections an OGC API Features API shall provide a GET operation on the `/collections` endpoint which returns a collections object. +

OGC API Features - part 2 - Coordinate Reference Systems by Reference [[ogcapi-features-2]] describes how to support different CRSs in your geospatial API. According to OGC API Features - part 2 - 6.2 Discovery and in particular Global list of CRS identifiers, a collections object provided by the API's `/collections` endpoint may contain a global list of supported CRSs by means of the `crs` property. This global CRS list applies to all feature collections delivered by the API, unless otherwise stated at a feature collection. +

Each feature collection mentioned within the `collections` list may also contain a `crs` property if the set of supported CRSs differs from the global CRS list. + If a feature collection supports exactly the same CRSs as mentioned in the global CRS list, then the `crs` property may be omitted. +

If a feature collection supports additional CRSs compared to the global CRS list in the collections object, then a reference to the global CRS list `#/crs` may be added in the feature collection object and the URIs of the additional CRSs are added to the CRS list in the `crs` property of the feature collection. +

If a feature collection supports a different set of CRSs than the set defined in the global CRS list, then a reference to the global CRS list is omitted and only the URIs of the supported CRSs are added to the CRS list in the `crs` property of the feature collection. +

For clients, it may be helpful to know the CRS identifier that may be used to retrieve features from that collection without the need to apply a CRS transformation. If all features in a feature collection are stored using a particular CRS, the property `storageCRS` shall be used to specify this CRS, in accordance with OGC API Features - part 2 - 6.2.2 Storage CRS. The value of this property shall be one of the CRSs supported by the API and advertised in the CRS list as stated in requirement 4 of OGC API Features - part 2 - 6.2.2 Storage CRS. If relevant, the epoch should also be specified, using the `storageCRSCoordinateEpoch` property. For an explanation of the use of epochs with CRS, see the CRS Guidelines [[hr-crs]]. +

+
How to test
+
+

If the REST API shall comply to the OGC API Features specification:

+
    +
  1. Issue an HTTP GET request to the /collections endpoint of the API.
  2. +
  3. Validate that the returned document contains a collections object with the crs property.
  4. +
+

If the REST API does not have to comply to the OGC API Features specification:

+
    +
  1. Issue an HTTP GET request to the /crss endpoint of the API.
  2. +
  3. Validate that the returned document contains an object with a crs property.
  4. +
+

In both cases, verify the following based on the response:

+
    +
  1. Validate that the crs property contains an array with CRS references in the form of URIs.
  2. +
  3. Validate that the CRS URIs return a GML document with an epsg:CommonMetadata element (xmlns:epsg="urn:x-ogp:spec:schema-xsd:EPSG:1.0:dataset).
  4. +
+
+
+
+ +
+

Make known in which CRS the geospatial data is stored by specifying the property storageCrs in the collection object

+
+
Statement
+
+ The value of this property shall be one of the CRSs the API supports. +
+
How to test
+
+
    +
  1. Issue an HTTP GET request to each collection in the /collections endpoint of the API.
  2. +
  3. Validate that each returned collection contains the storageCRS property.
  4. +
  5. Validate that the value of the storageCRS property is one of the URIs from the list of supported CRSs.
  6. +
+
+
+
+ +## CRS negotiation + +The default CRS for GeoJSON and for OGC API Features is CRS84 (OGC:CRS84), this CRS uses the WGS 84 datum with an ellipsoidal coordinate system in the order longitude-latitude. This refers to an ensemble of global CRSs that can be applied world-wide. For accurate applications the use of the CRS84 ensemble is not suitable. For more information about coordinate reference systems, read the Geonovum guidelines on CRS [[hr-crs]]. + + + +
+

Use CRS84 as the default coordinate reference system (CRS) in line with OGC API Features Requirement 10

+
+
Statement
+
+ The implication of this is, that if no CRS is explicitly included in the request, CRS84 is assumed. This rule also applies if the request uses POST. +
+
Rationale
+
+

Since most client-side mapping libraries use WGS 84 longitude-latitude (CRS84), the W3C/OGC Spatial Data on the Web working group recommends to use this as the default coordinate reference system. The API strategy caters for this supporting not only ETRS89 and RD, but also CRS84. +

The *default* CRS, i.e. the CRS which is assumed when not specified by either the API or the client, is CRS84, in line with GeoJSON and OGC API Features. +

+
How to test
+
+
    +
  1. Issue an HTTP GET request to retrieve some spatial data from the API without specifying a coordinate reference system.
  2. +
  3. Validate that the response includes a Content-Crs header with the URI for CRS84 or CRS84h.
  4. +
  5. Validate the retrieved spatial data using the CRS84 reference system (for 2D geometries) or the CRS84h reference system (for 3D geometries).
  6. +
+
+
+
+ + +
+

Use ETRS89 and/or RD when required

+
+
Statement
+
+ These are the preferred coordinate reference systems (CRS) for Dutch geospatial data. General usage of the European ETRS89 coordinate reference system (CRS) or RDNAP is preferred, but is not the default CRS. Hence, one of these CRSs has to be explicitly included in each request when one of these CRSs is desired in the response or used in a request. This is part of the Dutch Guideline for the use of CRSs [[hr-crs]]. +
+
How to test
+
+
    +
  1. Issue an HTTP GET request to retrieve some spatial data from the API, specifying ETRS89 and/or RD as coordinate reference system.
  2. +
  3. Validate that the response includes a Content-Crs header with the URI for the requested CRS.
  4. +
  5. Validate the retrieved spatial data using the coordinate reference system used in the request.
  6. +
+
+
+
+ +The guiding principles for CRS support: + +- Source systems record coordinates as they enter the system; +- The default CRS, CRS84, is listed first in the list of supported CRSs in the API; if the consumer does not specify the CRS it is assumed it uses the default. +- Coordinate reference systems API strategy: request/response in RD; ETRS89; CRS84; +- Use the latest version of [RDNAPTRANS™](https://docs.geostandaarden.nl/crs/crs/#transformatie-en-conversie-tussen-rdnap-en-etrs89) to transform RD to ETRS89 (correction grid); +- Which CRSs are supported in an API depends on context (e.g. user requirements) - see [Spatial Data on the Web Best Practice 7: Choose coordinate reference systems to suit your user's applications](https://www.w3.org/TR/sdw-bp/#bp-crs-choice) [[sdw-bp]]; +- Exchange format (notation) for ETRS89 and CRS84 (longitude, latitude) in decimal degrees, for example: (`5.96237626, 52.25502345`). The longitude and latitude are decimal numbers. The number of decimals in the fractional part may vary depending on the required accuracy. For an accuracy of 1 mm, 8 decimals in the fractional part are sufficient. See [Nauwkeurigheid van coördinaten](https://docs.geostandaarden.nl/crs/crs/#nauwkeurigheid-van-coordinaten) in [[hr-crs]]. +- Exchange format (notation) for RD (X, Y) in meters, for example: (`195427.520, 311611.840`). The X and Y coordinates are decimal numbers. The number of decimals in the fractional part may vary depending on the required accuracy. For an accuracy of 1 mm, 3 decimal places in the fractional part are sufficient. See [Nauwkeurigheid van coördinaten](https://docs.geostandaarden.nl/crs/crs/#nauwkeurigheid-van-coordinaten) in [[hr-crs]]. +- WGS 84 Pseudo Mercator (EPSG:3857) is rather inaccurate, but suitable for simple visualization of inprecise spatial data on the web, e.g. when it suffices if the data is recognizable on a map. WGS 84 Pseudo Mercator shall not be used for precise data that is meant for accurate spatial analysis. +- Use the CRS Guidelines [[hr-crs]] for coordinate transformations. +- Use an ensemble member CRS (instead of an ensemble CRS) for exchanging geometry, when known. +- Use an ensemble member CRS (instead of an ensemble CRS) as output of coordinate transformation, when known. +- APIs shall support and advertise both ensemble CRSs and ensemble member CRSs if geometry is exchanged and the CRS for the geometry is an ensemble member CRS. +- Under certain conditions WGS 84 can be made equal to e.g. ETRS89, this is called a 'null transformation', see [[hr-crs]]. If a null transformation is used to realize WGS 84, then the CRS (e.g. ETRS89) that is used to realize WGS 84 and the CRS for WGS 84 itself shall both be supported and advertised by an API. + +
+

The ensemble member should be one of the CRSs supported by the API

+
+
Statement
+
+ When the API provides data in an ensemble CRS like WGS 84 or ETRS89, while it is known to what ensemble member CRS the data actually refers, it should also be one of the CRSs supported by the API and advertised in the CRS list. For example when 2D data is transformed from RD with RDNAPTRANS not only ETRS89 (EPSG:4258) should be supported but also ETRF2000 (EPSG::9067). +
+
How to test
+
+
    +
  1. Issue an HTTP GET request to the /collections endpoint.
  2. +
  3. Validate that the returned document contains a collections object with the crs property.
  4. +
  5. Validate that the crs property contains an array with CRS references in the form of URIs.
  6. +
  7. Validate that when the crs property contains a URL for a ensemble CRS like ETRS89 (EPSG:4258), it also contains a URL for a ensemble member CRS like ETRF2000 (EPSG:9067).
  8. +
+
+
+
+ +
+

Support passing the coordinate reference system (CRS) of the bounding box in the request as a query parameter

+
+
Statement
+
+

Support the OGC API Features part 2 bbox-crs parameter in conformance to the standard. +

If a bounding box is sent to the server without these parameters, the default CRS, CRS84, is assumed as specified in /geo/default-crs. +

If an invalid value, i.e. a CRS which is not in the list of supported CRSs, is given for one of these parameters, the server responds with an HTTP status code `400`. +

+
How to test
+
+
    +
  1. Issue an HTTP GET request to the API, including the bbox parameter AND the bbox-crs parameter.
  2. +
  3. Validate that a document was returned with a status code 200.
  4. +
  5. Verify that the response includes a Content-Crs HTTP header with the URI of the requested CRS identifier.
  6. +
+
+
+
+ +
+

Support passing the coordinate reference system (CRS) of the geospatial filter in the request as a query parameter

+
+
Statement
+
+

Support the OGC API Features part 3 filter-crs parameter in conformance to the standard. +

If a geospatial filter is sent to the server without these parameters, the default CRS, CRS84, is assumed as specified in /geo/default-crs. +

If an invalid value, i.e. a CRS which is not in the list of supported CRSs, is given for one of these parameters, the server responds with an HTTP status code `400`. +

+
How to test
+
+
    +
  1. Issue an HTTP GET request to the API, including a geospatial filter AND the filter-crs parameter.
  2. +
  3. Validate that a document was returned with a status code 200.
  4. +
  5. Verify that the response includes a Content-Crs HTTP header with the URI of the requested CRS identifier.
  6. +
+
+
+
+ +In an API that supports the creation and/or updating of items, POST, PUT or PATCH requests with geospatial content in the body may be sent by a client to the server. In that case, it is necessary to indicate the CRS used, unless CRS84 (OGC:CRS84), the default CRS, is used. + +
+

When HTTP POST, PUT and/or PATCH requests are supported, pass the coordinate reference system (CRS) of geometry in the request body as a header

+
+
Statement
+
+

Support the OGC API Features part 4 Content-Crs header in conformance to the standard. +

Alternatively, if the feature representation supports expressing CRS information for each feature / geometry, the information can also be included in the feature representation. If no CRS is asserted, the default CRS, CRS84, is assumed, as stated in /geo/default-crs. +

+
How to test
+
+ In a request (i.e. when creating or updating an item on the server): +
    +
  1. Issue an HTTP POST request to the API with spatial data in the request body, including the Content-Crs header with the value of the CRS identifier for the spatial data in the body.
  2. +
  3. Verify that a document was returned with status code 201 in case a new item was created, or with status code 200.
  4. +
+ Repeat with a similar test voor PUT and/or PATCH if the server supports these. +
+
+
+ +
+

Support passing the desired coordinate reference system (CRS) of the geometry in the response as a query parameter

+
+
Statement
+
+ Support the OGC API Features part 2 crs parameter in conformance to the standard. +
+
How to test
+
+
    +
  1. Issue an HTTP GET request to the API, including the crs parameter.
  2. +
  3. Verify that the response has the status code 200, and includes a Content-Crs http header with the value of the requested CRS identifier.
  4. +
+
+
+
+ +
+

Assert the coordinate reference system (CRS) used in the response using a header

+
+
Statement
+
+ Support the OGC API Features part 2 Content-Crs header in conformance to the standard. +
+
How to test
+
+
    +
  1. Issue an HTTP GET request to the API, requesting spatial data.
  2. +
  3. Verify that the response includes the Content-Crs header with the URI of the requested CRS identifier if explicitly requested, or with the value http://www.opengis.net/def/crs/OGC/1.3/CRS84 if no CRS was explicitly requested.
  4. +
+
+
+
+ +The API should be able to handle the following scenarios based on the rules stated above: + +| Scenario | Explanation | +|-----------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| No geometry in request, no geometry in response | No CRS negotiation necessary | +| No geometry in request, geometry in response | The client can request a specific CRS for the geometries in the response using the `crs` parameter. The server indicates the geometry CRS in the response using the `Content-Crs` header. | +| Geometry in request body, no geometry in response | The client indicates the CRS of the geometry in the request body using the `Content-Crs` header. | +| Geometry in request body, geometry in response | The client indicates the CRS of the geometry in the request body using the `Content-Crs` header, and can request a specific CRS for the geometries in the response using the `crs` parameter. The server indicates the geometry CRS in the response using the `Content-Crs` header. | +| Geometry filter in request, no geometry in response | The client indicates the CRS of the geometry filter in the request using the `bbox-crs` parameter if a bounding box is used to filter geospatially, or the `filter-crs` parameter if another way of geospatial filtering is used. | +| Geometry filter in request, geometry in response | The client indicates the CRS of the geometry filter in the request using `bbox-crs` or `filter-crs` as in the previous scenario, and requests a specific CRS for the geometries in the response using the `crs` parameter. The server indicates the geometry CRS in response using the `Content-Crs` header. | + +Below is a list of the most commonly used CRSs in the Netherlands: + +| Name | Code | Type | Dimension | Scope | URI | +|----------------------------------|--------|---------------------------------------|-----------|----------|-----| +| Amersfoort / RD New | 28992 | easting, northing (x, y) | 2D | Dutch | | +| Amersfoort / RD New + NAP height | 7415 | easting, northing, height (x, y, h) | 3D | Dutch | | +| ETRS89 | 4258 | latitude, longitude (φ, λ) | 2D | European | | +| ETRS89 | 4937 | latitude, longitude, height (φ, λ, h) | 3D | European | | +| ETRF2000 | 7931 | latitude, longitude, height (φ, λ, h) | 3D | European | | +| ETRF2000 | 9067 | latitude, longitude (φ, λ) | 2D | European | | +| ITRF2014 | 7912 | latitude, longitude, height (φ, λ, h) | 3D | Global | | +| ITRF2014 | 9000 | latitude, longitude (φ, λ) | 2D | Global | | +| WGS 84 longitude-latitude | CRS84 | longitude, latitude (λ, φ) | 2D | Global | | +| WGS 84 longitude-latitude-height | CRS84h | longitude, latitude, height (λ, φ, h) | 3D | Global | | +| WGS 84 / Pseudo-Mercator | 3857 | easting, northing (x, y) | 2D | Global | | + +For a more extensive overview of CRSs see: . +Note that the URI of each CRS contains a version number and that new versions may be released in future. +Before using a URI verify if newer versions are available and use the latest version. + + + + + +## CRS transformation + +If the requested CRS is not the same as the storage CRS, a coordinate transformation is needed. Performance is increased when the dataset is transformed in multiple CRSs and stored in advance, and not transformed at the moment the request has arrived. In case of a transformation between RD and ETRS89, it is required that this transformation uses the latest version of the procedure of [RDNAPTRANS™](https://docs.geostandaarden.nl/crs/crs/#transformatie-en-conversie-tussen-rdnap-en-etrs89). diff --git a/inspire.md b/sections/inspire.md similarity index 98% rename from inspire.md rename to sections/inspire.md index bebfd61..ccd0828 100644 --- a/inspire.md +++ b/sections/inspire.md @@ -1,4 +1,5 @@ # INSPIRE requirements + [INSPIRE](https://inspire.ec.europa.eu/) is a European directive that forces data providers of geospatial datasets that belong to one of the 34 INSPIRE themes to publish the metadata, a viewservice and a download service. These services can also be APIs. For the OGC-API Features, an endorsed good practice has been described in a [document](https://github.com/INSPIRE-MIF/gp-ogc-api-features/blob/master/spec/oapif-inspire-download.md) that proposes a technical approach for implementing the requirements set out in the INSPIRE Implementing Rules for Network Services [[IRs for NS](https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:02009R0976-20141231&from=EN)] based on the newly adopted [OGC API - Features standard](http://docs.opengeospatial.org/is/17-069r3/17-069r3.html). @@ -13,4 +14,4 @@ The extra requirements stated in this document concern: - [describing encoding](https://github.com/INSPIRE-MIF/2017.2/blob/master/GeoJSON/geojson-encoding-rule.md#inspire-requirements-for-encoding-rules) - [metadata links](https://github.com/INSPIRE-MIF/gp-ogc-api-features/blob/master/spec/oapif-inspire-download.md#metadata-elements-of-the-data-set) -These requirements should be met when an API serves features for an INSPIRE dataset. \ No newline at end of file +These requirements should be met when an API serves features for an INSPIRE dataset. diff --git a/introduction.md b/sections/introduction.md similarity index 90% rename from introduction.md rename to sections/introduction.md index a2820bc..142d4c5 100644 --- a/introduction.md +++ b/sections/introduction.md @@ -1,10 +1,10 @@ # Introduction -This document provides rules for publishing geospatial data using Web APIs. Spatial data is +This document provides rules for publishing geospatial data using Web APIs. Spatial data is > data that describes anything with spatial extent (i.e. size, shape or position). Spatial data is also known as location information. [[sdw-bp]] -Geospatial data is more specific in that it is explicitly located relative to the Earth. +Geospatial data is more specific in that it is explicitly located relative to the Earth. Geospatial data is 'special' data in the sense that it typically indicates the location of things using geometry. This geometry allows geospatial functions such as 'find only the things located within this area' but also requires specific ways of handling. There are international regulations and standards for geospatial data that need to be taken into account in certain cases. @@ -14,3 +14,7 @@ Geospatial data is 'special' data in the sense that it typically indicates the l The Geospatial Module provides rules for the structuring of geospatial payloads and for functions in APIs to handle geospatial data. + +## Summary + +
diff --git a/sections/request-response.md b/sections/request-response.md new file mode 100644 index 0000000..1ef65c7 --- /dev/null +++ b/sections/request-response.md @@ -0,0 +1,540 @@ +# Request and response + +Providing requested resources is the essence of any API. This also applies to REST APIs that handle geospatial data. There are, however, some specific aspects when dealing with geospatial data in REST APIs. The most important aspects are described in this chapter: + +- how to encode geometries in APIs +- how to supply a spatial filter in the call (request) +- how to return results of a spatial search + +When requesting information, for example about cadastral parcels, users do not necessarily require the geometry, even if they used a spatial filter. A name or parcel ID may be sufficient. + + + +## GeoJSON + +[[RFC7946]] describes the GeoJSON format, including a convention for describing 2D geometric objects in CRS84 (OGC:CRS84). In the Geospatial module of the API strategy we adopt the GeoJSON conventions for describing geometry objects. The convention is extended to allow alternative projections. +The GeoJSON conventions and extensions described in this module apply to both geometry passed in input parameters and responses. + + + +

Example of embedding WKT in a JSON object using the following definition for a JSON object:

+
+  building:
+    type: object
+    required:
+      - geometry
+    properties:
+      geometry:
+        type: string
+        format: wkt
+  
+

Sample response:

+
+  {
+    "building": {
+      "geometry": "POLYGON Z((194174.445 465873.676 0, 194174.452 465872.291 0, 194158.154 465872.213 0, 194158.226 465856.695 0, 194223.89 465856.969 0, 194223.821 465872.48 0, 194207.529 465872.415 0, 194207.505 465882.528 0, 194207.498 465883.902 0, 194223.799 465883.967 0, 194223.732 465899.48 0, 194216.55 465899.45 0, 194215.15 465899.445 0, 194213.85 465899.439 0, 194158.068 465899.211 0, 194158.148 465883.685 0, 194174.42 465883.767 0, 194174.445 465873.676 0))"
+    }
+  }
+  
+ +

Example of embedding WKB in a JSON object using the following definition for a JSON object:

+
+  building:
+    type: object
+    required:
+      - geometry
+    properties:
+      geometry:
+        type: string
+        format: wkb
+  
+

Sample response:

+
+  {
+    "building": {
+      "geometry": "01030000A0F71C00000100000012000000F6285C8FF3B30741105839B4466F1C4100000000000000000E2DB29DF3B307416DE7FB29416F1C4100000000000000001D5A643B71B3074108AC1CDA406F1C4100000000000000008716D9CE71B307417B14AEC7026F1C410000000000000000EC51B81E7FB50741378941E0036F1C410000000000000000B07268917EB50741B81E85EB416F1C4100000000000000001D5A643BFCB407418FC2F5A8416F1C410000000000000000A4703D0AFCB407413108AC1C6A6F1C4100000000000000008B6CE7FBFBB4074154E3A59B6F6F1C410000000000000000AC1C5A647EB507417D3F35DE6F6F1C410000000000000000E5D022DB7DB50741B81E85EBAD6F1C4100000000000000006666666644B50741CDCCCCCCAD6F1C4100000000000000003333333339B507417B14AEC7AD6F1C410000000000000000CDCCCCCC2EB507414C3789C1AD6F1C4100000000000000008195438B70B307414E6210D8AC6F1C410000000000000000BE9F1A2F71B30741D7A370BD6E6F1C410000000000000000C3F5285CF3B30741B07268116F6F1C410000000000000000F6285C8FF3B30741105839B4466F1C410000000000000000"
+    }
+  }
+  
+ +## Call (requests) + +A simple spatial filter can be supplied as a bounding box. This is a common way of filtering spatial data and can be supplied as a parameter. We adopt the OGC API Features [[ogcapi-features-1]] bounding box parameter: + +
+

Supply a simple spatial filter as a bounding box parameter

+
+
Statement
+
+ Support the OGC API Features part 1 bbox query parameter in conformance to the standard.

+ +
Note that if a resource contains multiple geometries, it is up to the provider to decide if geometries of type single geometry or type multiple geometry are returned and that the provider shall clearly document this behavior.
+
+
Rationale
+
+

The default spatial operator intersects is used to determine which resources are returned. +

Due to possible performance issue, especially when a combination of filters is used, a provider may decide to limit the size of the bounding box or the number of results. It is also up to the provider to decide if an error is returned in such cases. The provider shall clearly document this behavior. +

The provider shall be able to provide resources that do not have a geometry property and are related to resources that match the bounding box filter. +

An error shall be given if the provided coordinates are outside the specified coordinate reference system. +

+
How to test
+
+
    +
  1. Issue an HTTP GET request to the API, including the bbox query parameter and using CRS Negotiation.
  2. +
  3. Validate that a response with status code 200 is returned.
  4. +
  5. Verify that only features that have a spatial geometry that intersects the bounding box are returned as part of the result set.
  6. +
+
+
+
+ + + + + + +
+

Place results of a global spatial query in the relevant geometric context

+
+
Statement
+
+ In case of a global query /api/v1/_search, results should be placed in the relevant geometric context, because results from different collections, i.e. different sets of resources of the same type, are retrieved. Express the name of the collection to which the results belong in the singular form using the property type. For example: + +
+
How to test
+
+
    +
  1. Issue an HTTP GET request to the API.
  2. +
  3. Validate that the returned document contains the expected type property for each member.
  4. +
+
+
+
+ +In case a REST API shall comply to the OGC API Features specification for creating, updating and deleting a resource, the following applies. + + +
+

Support GeoJSON in geospatial API requests

+
+
Statement
+
+ For representing geometric information in an API, use the convention for describing geometry as defined in the GeoJSON format [[RFC7946]]. Support GeoJSON as described in OGC API Features part 4, but note that this standard is still in development. + + +
+
How to test
+
+
    +
  1. Create a new resource that includes feature content (i.e. coordinates) using the HTTP POST method with request media type application/geo+json in the Content-Type header.
  2. +
  3. Validate that a response with status code 201 (Created) is returned.
  4. +
  5. Validate that the response includes the Location header with the URI of the newly added resource. +
+
+
+
+ +In case a REST API does not have to comply to the OGC API Features specification, e.g. for usage in administrative applications, the REST API shall use the JSON data format. If a resource contains geometry, that geometry shall be embedded as a GeoJSON Geometry object within the resource. The media type application/json must be supported. This may also apply to other media types application/*+json, however this depends on the media type specification. If the media type specification prescribes that resource information must be embedded in a JSON structure defined in the media specification, then the media type should not be supported while it is impossible to comply to that specification with the method described below. The media type application/geo+json should not be supported while the resource does not comply to the GeoJSON specification, i.e. the request resource does not embed a feature or feature collection. +A template for the definition of the schemas for the GeoJSON Geometry object in the requests in OpenAPI definitions is available: [geometryGeoJSON.yaml](https://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/schemas/geometryGeoJSON.yaml). +In case a collection of resources is embedded in the request resource, the name of the array containing the resources should be the plural of the resource name. + +
+

Embed GeoJSON Geometry object as part of the JSON resource in API requests

+
+
Statement
+
+ When a JSON (application/json) request contains a geometry, represent it in the same way as the Geometry object of GeoJSON. + + +
+
How to test
+
+
    +
  1. Create a new resource that includes geometry of GeoJSON Geometry object type using the HTTP POST method with request media type application/json in the Content-Type header.
  2. +
  3. Validate that a response with status code 201 (Created) is returned.
  4. +
  5. Validate that the response includes the Location header with the URI of the newly added resource. +
+
+
+
+ +## Result (response) + +In case a REST API shall comply to the OGC API Features specification, e.g. for usage in GIS applications, the following applies. + +
+

Support GeoJSON in geospatial API responsess

+
+
Statement
+
+ For representing 2D geometric information in an API response, use the convention for describing geometry as defined in the GeoJSON format [[RFC7946]]. Support GeoJSON as described in OGC API Features Requirements class 8.3 [[ogcapi-features-1]]. + + +
+
  • The resources' properties (e.g. naam) are passed in the properties object. Depending on the implemented filter capabilities the properties object may contain all or a selection of the resources' properties.
  • +
  • The OGC API Features specification provides the possibility to add an array of links to a feature and feature collection, which may contain a self link and in case of a feature collection may contain navigation links
  • +
    +
    +
    How to test
    +
    + Test case 1: +
      +
    1. Request a single resource that includes feature content (i.e. coordinates) with response media type application/geo+json in the Accept header.
    2. +
    3. Validate that a response with status code 200 is returned.
    4. +
    5. Validate that Content-Type header contains application/geo+json
    6. +
    7. Validate that the returned document is a GeoJSON Feature document.
    8. +
    + Test case 2: +
      +
    1. Request a collection of resources that includes feature content (i.e. coordinates) with response media type application/geo+json in the Accept header.
    2. +
    3. Validate that a response with status code 200 is returned.
    4. +
    5. Validate that Content-Type header contains application/geo+json
    6. +
    7. Validate that the returned document is a GeoJSON FeatureCollection document.
    8. +
    + Test case 3: +
      +
    1. Request a single resource that does not include feature content (i.e. coordinates) with response media type application/geo+json or application/json in the Accept header.
    2. +
    3. Validate that a response with status code 200 is returned.
    4. +
    5. Validate that Content-Type header contains application/json
    6. +
    7. Validate that the returned document is a JSON document.
    8. +
    + Test case 4: +
      +
    1. Request a collection of resources that do not include feature content (i.e. coordinates) with response media type application/geo+json or application/json in the Accept header.
    2. +
    3. Validate that a response with status code 200 is returned.
    4. +
    5. Validate that Content-Type header contains application/json
    6. +
    7. Validate that the returned document is a JSON document.
    8. +
    +
    +
    +
    + +In case a REST API does not have to comply to the OGC API Features specification, e.g. for usage in administrative applications, the REST API shall use the JSON data format. If resources contain geometry, the geometry shall be returned as a GeoJSON Geometry object embedded in the resource. The media type application/json must be supported. This may also apply to other media types application/\*+json, however this depends on the media type specification. If the media type specification prescribes that resource information must be embedded in a JSON structure defined in the media type specification, then the media type should not be supported while it is impossible to comply to that specification with the method described below. The media type application/geo+json should not be supported while the resource does not comply to the GeoJSON specification, i.e. the response does not return a feature or feature collection. +A template for the definition of the schemas for the GeoJSON Geometry object in the responses in OpenAPI definitions is available: [geometryGeoJSON.yaml](https://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/schemas/geometryGeoJSON.yaml). +In case a collection of resources is returned, the name of the array containing the resources should be the plural of the resource name. + + +
    +

    Embed GeoJSON Geometry object as part of the JSON resource in API responses

    +
    +
    Statement
    +
    + When a JSON (application/json) response contains a geometry, represent it in the same way as the Geometry object of GeoJSON. + + + +

    The resource and resource collection may be [[HAL]] resources and therefore may contain a `_links` object. The `_links` object should contain a self link and in case of a collection also navigation links (e.g. first, next prev, last). In such cases the application/hal+json media type may be used. +

    +
    How to test
    +
    + Test case 1: +
      +
    1. Request a single resource that contains geometry of GeoJSON Geometry object type: Point, MultiPoint, LineString, MultiLineString, Polygon or MultiPolygon and with response media type application/json in the Accept header.
    2. +
    3. Validate that a response with status code 200 is returned.
    4. +
    5. Validate that Content-Type header contains application/json
    6. +
    7. Validate that the returned document is a JSON document.
    8. +
    9. Validate that the returned document contains a property that complies to one of the GeoJSON Geometry objects mentioned above and contains: +
        +
      • a property type containing the name of one of the GeoJSON Geometry object types mentioned above, and
      • +
      • a property coordinates containing an array with the coordinates. Depending on the type of geometry object, the content of the array differs.
      • +
    10. +
    + Test case 2: +
      +
    1. Request a collection of resources that contain geometry of GeoJSON Geometry object type: Point, MultiPoint, LineString, MultiLineString, Polygon or MultiPolygon and with response media type application/json in the Accept header.
    2. +
    3. Validate that a response with status code 200 is returned.
    4. +
    5. Validate that Content-Type header contains application/json
    6. +
    7. Validate that the returned document is a JSON document.
    8. +
    9. Validate that the returned document contains an array of resources and that each resource contains a property that complies to one of the GeoJSON Geometry objects mentioned above and contains: +
        +
      • a property type containing the name of one of the GeoJSON Geometry object types mentioned above, and
      • +
      • a property coordinates containing an array with the coordinates. Depending on the type of geometry object, the content of the array differs.
      • +
    10. +
    + Test case 3: +
      +
    1. Request a single resource that contains geometry of GeoJSON Geometry object type: GeometryCollection and with response media type application/json in the Accept header.
    2. +
    3. Validate that a response with status code 200 is returned.
    4. +
    5. Validate that Content-Type header contains application/json
    6. +
    7. Validate that the returned document is a JSON document.
    8. +
    9. Validate that the returned document contains a property that complies to the GeoJSON Geometry object mentioned above and contains: +
        +
      • a property type containing the name of the GeoJSON Geometry object type: GeometryCollection, and
      • +
      • a property geometries containing an array of GeoJSON Geometry objects.
      • +
    10. +
    + Test case 4: +
      +
    1. Request a collection of resources that contain geometry of GeoJSON Geometry object type: GeometryCollection and with response media type application/json in the Accept header.
    2. +
    3. Validate that a response with status code 200 is returned.
    4. +
    5. Validate that Content-Type header contains application/json
    6. +
    7. Validate that the returned document is a JSON document.
    8. +
    9. Validate that the returned document contains an array of resources and that each resource contains a property that complies to the GeoJSON Geometry object mentioned above and contains: +
        +
      • a property type containing the name of the GeoJSON Geometry object type: GeometryCollection, and
      • +
      • a property geometries containing an array of GeoJSON Geometry objects.
      • +
      +
    10. +
    +
    +
    +