From 7b0a35c7c31c5c9317f5b82e9bccedf0fdb507e5 Mon Sep 17 00:00:00 2001 From: Jerome St-Louis Date: Wed, 3 Jul 2024 12:38:47 -0400 Subject: [PATCH] 14-encodings: Progress on encodings - CoverageJSON, PNG, GeoTIFF and COG - Initial stand-in files for other encodings - Fixed mediatype for CoverageJSON --- standard/clause_14_encodings.adoc | 32 ++++--- .../openapi/ogcapi-coverages-1.bundled.json | 6 +- .../responses/common-geodata/rCollection.yaml | 2 +- .../common-geodata/rCollectionsList.yaml | 2 +- .../responses/coverages-core/rCoverage.yaml | 2 +- .../requirements/requirements_class_cog.adoc | 38 ++++++++ .../requirements_class_coverage_subset.adoc | 2 +- .../requirements_class_coveragejson.adoc | 23 +++++ .../requirements_class_geotiff.adoc | 86 +++++++++++++++++++ .../requirements_class_jpeg2000.adoc | 0 .../requirements_class_jpegxl.adoc | 0 .../requirements/requirements_class_las.adoc | 0 .../requirements_class_laszip.adoc | 0 .../requirements_class_netcdf.adoc | 0 .../requirements/requirements_class_png.adoc | 35 ++++++++ .../requirements/requirements_class_zarr.adoc | 0 16 files changed, 210 insertions(+), 18 deletions(-) create mode 100644 standard/requirements/requirements_class_cog.adoc create mode 100644 standard/requirements/requirements_class_coveragejson.adoc create mode 100644 standard/requirements/requirements_class_geotiff.adoc create mode 100644 standard/requirements/requirements_class_jpeg2000.adoc create mode 100644 standard/requirements/requirements_class_jpegxl.adoc create mode 100644 standard/requirements/requirements_class_las.adoc create mode 100644 standard/requirements/requirements_class_laszip.adoc create mode 100644 standard/requirements/requirements_class_netcdf.adoc create mode 100644 standard/requirements/requirements_class_png.adoc create mode 100644 standard/requirements/requirements_class_zarr.adoc diff --git a/standard/clause_14_encodings.adoc b/standard/clause_14_encodings.adoc index 75586f7..d067cc1 100644 --- a/standard/clause_14_encodings.adoc +++ b/standard/clause_14_encodings.adoc @@ -8,6 +8,7 @@ These requirements classes include: * <> * <> +* <> * <> * <> * <> @@ -35,10 +36,10 @@ A table of the media types corresponding to each encoding requirements class def |==== ^|*Encoding* ^|*media type* |HTML |text/html -|GeoTIFF |image/tiff; application=geotiff +|GeoTIFF (including COG) |image/tiff; application=geotiff |netCDF |application/x-netcdf |CIS JSON |application/json (TODO: either OGC API will adopt a mechanism for negotiation by profile, or a more specific media type will be registered) -|CoverageJSON |application/prs.coverage+json +|CoverageJSON |application/vnd.cov+json |LAS |vnd.las |LASZip |vnd.laszip |PNG |image/png @@ -67,7 +68,16 @@ include::requirements/requirements_class_html.adoc[] The GeoTIFF requirements class defines support for encoding a coverage response according to the https://docs.ogc.org/is/19-008r4/19-008r4.html[OGC GeoTIFF standard]. -// TODO: include::requirements/requirements_class_geotiff.adoc[] +include::requirements/requirements_class_geotiff.adoc[] + +[[rc_encoding-cog]] +=== Requirements Class "Cloud Optimized GeoTIFF" + +==== Overview + +The Cloud Optimized GeoTIFF (COG) requirements class defines support for accessing a coverage response as a https://docs.ogc.org/is/21-026/21-026.html[COG] using HTTP range requests. + +include::requirements/requirements_class_cog.adoc[] === Requirements Class "netCDF" @@ -75,7 +85,7 @@ The GeoTIFF requirements class defines support for encoding a coverage response The netCDF requirements class defines support for encoding a coverage response according to the https://portal.ogc.org/files/?artifact_id=43732[OGC netCDF standard]. -// TODO: include::requirements/requirements_class_netcdf.adoc[] +include::requirements/requirements_class_netcdf.adoc[] [[rc_encoding-cisjson]] === Requirements Class "CIS JSON" @@ -134,7 +144,7 @@ include::requirements/requirements_class_cisjson.adoc[] The CoverageJSON requirements class defines support for encoding a coverage response according to the https://docs.ogc.org/cs/21-069r2/21-069r2.html[OGC CoverageJSON Community Standard]. -// TODO: include::requirements/requirements_class_coveragejson.adoc[] +include::requirements/requirements_class_coveragejson.adoc[] [[rc_encoding-las]] === Requirements Class "LAS" @@ -145,7 +155,7 @@ The LAS requirements class defines support for encoding a coverage response acco This requirements class is particularly well suited for distributing point cloud coverages. -// TODO: include::requirements/requirements_class_las.adoc[] +include::requirements/requirements_class_las.adoc[] [[rc_encoding-laszip]] === Requirements Class "LASZip" @@ -157,7 +167,7 @@ https://www.cs.unc.edu/~isenburg/lastools/download/laszip.pdf[LASZip] compressio This requirements class is particularly well suited for distributing point cloud coverages. -// TODO: include::requirements/requirements_class_laszip.adoc[] +include::requirements/requirements_class_laszip.adoc[] [[rc_encoding-png]] === Requirements Class "PNG" @@ -170,7 +180,7 @@ Because PNG encoding is limited to an integer data values, this requirements cla a specific scale factor and offset to be used to quantize coverage values, and allowing the implementation to inform the client of the scale factor and offset used for that quantization. -// TODO: include::requirements/requirements_class_png.adoc[] +include::requirements/requirements_class_png.adoc[] [[rc_encoding-jpegxl]] === Requirements Class "JPEG XL" @@ -181,7 +191,7 @@ The JPEG XL requirements class defines support for encoding a coverage response // JPEG XL supports a large number of bands, image dimensions, and floating points. -// TODO: include::requirements/requirements_class_jpegxl.adoc[] +include::requirements/requirements_class_jpegxl.adoc[] [[rc_encoding-jpeg2000]] === Requirements Class "JPEG 2000" @@ -193,7 +203,7 @@ support for georeferencing with http://www.opengis.net/doc/IS/GMLJP2/2.1[GMLJP2] // TODO: .jpf for floating point support, and/or parameters like PNG? -// TODO: include::requirements/requirements_class_jpeg2000.adoc[] +include::requirements/requirements_class_jpeg2000.adoc[] [[rc_encoding-zarr]] === Requirements Class "(Geo)Zarr" @@ -203,4 +213,4 @@ support for georeferencing with http://www.opengis.net/doc/IS/GMLJP2/2.1[GMLJP2] The (Geo)Zarr requirements class defines support for encoding a coverage response according to the https://portal.ogc.org/files/100727[OGC Zarr Community Standard], with eventual support for https://www.ogc.org/requests/ogc-to-form-geozarr-standards-working-group-public-comment-sought-on-draft-charter/[GeoZarr]. -// TODO: include::requirements/requirements_class_zarr.adoc[] +include::requirements/requirements_class_zarr.adoc[] diff --git a/standard/openapi/ogcapi-coverages-1.bundled.json b/standard/openapi/ogcapi-coverages-1.bundled.json index 81f8557..1ea1ff2 100644 --- a/standard/openapi/ogcapi-coverages-1.bundled.json +++ b/standard/openapi/ogcapi-coverages-1.bundled.json @@ -3436,7 +3436,7 @@ "Coverage": { "description": "A coverage, including any self-describing information supported by the encoding.", "content": { - "application/prs.coverage+json": { + "application/vnd.cov+json": { "schema": { "type": "string" } @@ -3716,7 +3716,7 @@ { "href": "http://data.example.org/collections/elevation/coverage.covjson", "rel": "http://www.opengis.net/def/rel/ogc/1.0/coverage", - "type": "application/prs.coverage+json", + "type": "application/vnd.cov+json", "title": "Elevation data (as CoverageJSON)" }, { @@ -3788,7 +3788,7 @@ { "href": "http://data.example.org/collections/elevation/coverage.covjson", "rel": "http://www.opengis.net/def/rel/ogc/1.0/coverage", - "type": "application/prs.coverage+json", + "type": "application/vnd.cov+json", "title": "Elevation data (as CoverageJSON)" }, { diff --git a/standard/openapi/responses/common-geodata/rCollection.yaml b/standard/openapi/responses/common-geodata/rCollection.yaml index 568159a..7eeeca1 100644 --- a/standard/openapi/responses/common-geodata/rCollection.yaml +++ b/standard/openapi/responses/common-geodata/rCollection.yaml @@ -31,7 +31,7 @@ content: title: Elevation data (as GeoTIFF) - href: http://data.example.org/collections/elevation/coverage.covjson rel: http://www.opengis.net/def/rel/ogc/1.0/coverage - type: application/prs.coverage+json + type: application/vnd.cov+json title: Elevation data (as CoverageJSON) - href: http://data.example.org/collections/elevation/coverage.cisjson rel: http://www.opengis.net/def/rel/ogc/1.0/coverage diff --git a/standard/openapi/responses/common-geodata/rCollectionsList.yaml b/standard/openapi/responses/common-geodata/rCollectionsList.yaml index d075c03..6b9da3c 100644 --- a/standard/openapi/responses/common-geodata/rCollectionsList.yaml +++ b/standard/openapi/responses/common-geodata/rCollectionsList.yaml @@ -46,7 +46,7 @@ content: title: Elevation data (as GeoTIFF) - href: http://data.example.org/collections/elevation/coverage.covjson rel: http://www.opengis.net/def/rel/ogc/1.0/coverage - type: application/prs.coverage+json + type: application/vnd.cov+json title: Elevation data (as CoverageJSON) - href: http://data.example.org/collections/elevation/coverage.cisjson rel: http://www.opengis.net/def/rel/ogc/1.0/coverage diff --git a/standard/openapi/responses/coverages-core/rCoverage.yaml b/standard/openapi/responses/coverages-core/rCoverage.yaml index 314f774..eb76d09 100644 --- a/standard/openapi/responses/coverages-core/rCoverage.yaml +++ b/standard/openapi/responses/coverages-core/rCoverage.yaml @@ -1,6 +1,6 @@ description: A coverage, including any self-describing information supported by the encoding. content: - application/prs.coverage+json: + application/vnd.cov+json: schema: type: string # SwaggerUI Validation errors? $ref: 'https://schemas.opengis.net/covjson/1.0/coveragejson.json' diff --git a/standard/requirements/requirements_class_cog.adoc b/standard/requirements/requirements_class_cog.adoc new file mode 100644 index 0000000..95da87a --- /dev/null +++ b/standard/requirements/requirements_class_cog.adoc @@ -0,0 +1,38 @@ +[[rc_cog]] +[cols="1,4",width="90%"] +|=== +2+|*Requirements Class* +2+|http://www.opengis.net/spec/ogcapi-coverages-1/1.0/req/cog +|Target type |Web API +|Dependency |http://www.opengis.net/spec/ogcapi-coverages-1/1.0/req/core +|Dependency |https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf +|Dependency |https://docs.ogc.org/is/19-008r4/19-008r4.html +|Dependency |https://docs.ogc.org/is/21-026/21-026.html +|=== + +// [[GeoTIFF]] OGC 19-008: *OGC GeoTIFF Standard*, Version 1.1, http://docs.opengeospatial.org/is/19-008r4/19-008r4.html +// [[[TIFF_V6,TIFF V6.0]]], Adobe Developers Association: TIFF Specification Revision 6.0. (1992) https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf[https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf] + +==== Requirements + +[[requirements-class-cog-clause]] + +===== Cloud Optimized GeoTIFF access + +[[req_cog_http-range]] +[width="90%",cols="2,6a"] +|=== +^|*Requirement {counter:req-id}* |*/req/cog/http-range* +^|A |The coverage resource (`/coverage`), as defined in the Core requirement class, SHALL support HTTP range requests as specified in +the https://docs.ogc.org/is/21-026/21-026.html#HTTPRangeSupportRequirements[`/req/http-range` requirement class of COG]. +|=== + +[[req_cog_cloud-optimized]] +[width="90%",cols="2,6a"] +|=== +^|*Requirement {counter:req-id}* |*/req/cog/cloud-optimized* +^|A |The coverage resource, as defined in the Core requirement class, SHALL support content negotiation of a https://docs.ogc.org/is/19-008r4/19-008r4.html[GeoTIFF] using the cloud-optimized profile, +(`Accept-Profile:`/`Content-Profile:` http://www.opengis.net/def/profile/geotiff/cloud-optimized`, `Accept:`/`Content-Type:` `image/tiff; application=geotiff` media type). +^|B |The response SHALL be a GeoTIFF document which validates against the GeoTIFF and TIFF standard. +^|C |If the response contains multiple fields, the fields SHALL be encoded as bands ordered following the `x-OGC-property-seq` sequence. +|=== diff --git a/standard/requirements/requirements_class_coverage_subset.adoc b/standard/requirements/requirements_class_coverage_subset.adoc index 421efa6..3904f5c 100644 --- a/standard/requirements/requirements_class_coverage_subset.adoc +++ b/standard/requirements/requirements_class_coverage_subset.adoc @@ -161,7 +161,7 @@ with the following characteristics (using an Extended Backus Naur Form (EBNF) fr ^|P |If a upper limit of the subset interval is populated with an asterisk `*`, then the maximum extent of the coverage along that axis SHALL be selected. ^|Q |Multiple subset parameters SHALL be interpreted, as if all dimension subsetting values were provided in a single subset parameter (comma separated)^1^. -|1 Example: subset=Lat(-90:90)&subset=Lon(-180:180)&subset=time("2018-02-12T23:20:52Z")&subset=atm_pressure_hpa(500) is equivalent to subset=Lat(-90:90),Lon(-180:180),time("2018-02-12T23:20:52Z"),atm_pressure_hpa(500) +2+|1 Example: subset=Lat(-90:90)&subset=Lon(-180:180)&subset=time("2018-02-12T23:20:52Z")&subset=atm_pressure_hpa(500) is equivalent to subset=Lat(-90:90),Lon(-180:180),time("2018-02-12T23:20:52Z"),atm_pressure_hpa(500) 2 Note that this is only valid of the spatial dimensions. The ‘additional’ dimensions rely on the names of the extent of the collection. |=== diff --git a/standard/requirements/requirements_class_coveragejson.adoc b/standard/requirements/requirements_class_coveragejson.adoc new file mode 100644 index 0000000..8e7ab15 --- /dev/null +++ b/standard/requirements/requirements_class_coveragejson.adoc @@ -0,0 +1,23 @@ +[[rc_coveragejson]] +[cols="1,4",width="90%"] +|=== +2+|*Requirements Class* +2+|http://www.opengis.net/spec/ogcapi-coverages-1/1.0/req/coveragejson +|Target type |Web API +|Dependency |http://www.opengis.net/spec/ogcapi-coverages-1/1.0/req/core +|Dependency |https://docs.ogc.org/cs/21-069r2/21-069r2.html +|=== + +==== Requirements + +[[requirements-class-coveragejson-clause]] + +===== Coverage JSON representation + +[[req_coveragejson_coverage]] +[width="90%",cols="2,6a"] +|=== +^|*Requirement {counter:req-id}* |*/req/coveragejson/coverage* +^|A |The coverage resource, as defined in the Core requirement class, SHALL support negotiating a https://docs.ogc.org/cs/21-069r2/21-069r2.html[CoverageJSON] response using the `application/vnd.cov+json` media type. +^|B |The response SHALL be a CoverageJSON document which validates against the CoverageJSON community standard. +|=== diff --git a/standard/requirements/requirements_class_geotiff.adoc b/standard/requirements/requirements_class_geotiff.adoc new file mode 100644 index 0000000..18cef6a --- /dev/null +++ b/standard/requirements/requirements_class_geotiff.adoc @@ -0,0 +1,86 @@ +[[rc_geotiff]] +[cols="1,4",width="90%"] +|=== +2+|*Requirements Class* +2+|http://www.opengis.net/spec/ogcapi-coverages-1/1.0/req/geotiff +|Target type |Web API +|Dependency |http://www.opengis.net/spec/ogcapi-coverages-1/1.0/req/core +|Dependency |https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf +|Dependency |https://docs.ogc.org/is/19-008r4/19-008r4.html +|=== + +// [[GeoTIFF]] OGC 19-008: *OGC GeoTIFF Standard*, Version 1.1, http://docs.opengeospatial.org/is/19-008r4/19-008r4.html +// [[[TIFF_V6,TIFF V6.0]]], Adobe Developers Association: TIFF Specification Revision 6.0. (1992) https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf[https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf] + +==== Requirements + +[[requirements-class-geotiff-clause]] + +===== GeoTIFF representation + +[[req_geotiff_coverage]] +[width="90%",cols="2,6a"] +|=== +^|*Requirement {counter:req-id}* |*/req/geotiff/coverage* +^|A |The coverage resource, as defined in the Core requirement class, SHALL support negotiating a https://docs.ogc.org/is/19-008r4/19-008r4.html[GeoTIFF] response using the `image/tiff; application=geotiff` media type. +^|B |The response SHALL be a GeoTIFF document which validates against the GeoTIFF and TIFF standard. +^|C |If the response contains multiple fields, the fields SHALL be encoded as bands ordered following the `x-OGC-property-seq` sequence. +|=== + +===== GeoTIFF parameters + +[[rec_geotiff_compression]] +[width="90%",cols="2,6a"] +|=== +^|*Recommendation {counter:rec-id}* |*/rec/geotiff/compression* +^|A |The coverage resource SHOULD support a `compression` parameter. +^|B |The possible values for the `compression` parameter SHOULD be `none`, `packbits`, `huffman`, `lzw`, `deflate`. +^|C |The GeoTIFF coverage response SHOULD use the compression method specified. +|=== + +[[rec_geotiff_predictor]] +[width="90%",cols="2,6a"] +|=== +^|*Recommendation {counter:rec-id}* |*/rec/geotiff/predictor* +^|A |The coverage resource SHOULD support a `predictor` parameter. +^|B |The possible values for the `compression` parameter SHOULD be `none`, `horizontal`, `floating-point`. +^|C |The GeoTIFF coverage response SHOULD use the predictor specified. +|=== + +[[rec_geotiff_interleave]] +[width="90%",cols="2,6a"] +|=== +^|*Recommendation {counter:rec-id}* |*/rec/geotiff/interleave* +^|A |The coverage resource SHOULD support a `interleave` parameter. +^|B |The possible values for the `interleave` parameter SHOULD be `pixel` (PlanarConfiguration value 1 for chunky, PLANARCONFIG_CONTIG in libtiff) and `band` +(PlanarConfiguration value 2 for planar configuration, PLANARCONFIG_SEPARATE in libtiff). +^|C |The GeoTIFF coverage response SHOULD use the interleave setting specified (corresponding to the PlanarConfiguration in TIFF terminology). +|=== + +[[rec_geotiff_tiling]] +[width="90%",cols="2,6a"] +|=== +^|*Recommendation {counter:rec-id}* |*/rec/geotiff/tiling* +^|A |The coverage resource SHOULD support a boolean `tiling` parameter. +^|B |The GeoTIFF coverage response SHOULD use tiling if `tiling` is true, or strips otherwise. +|=== + +[[rec_geotiff_tile-height-width]] +[width="90%",cols="2,6a"] +|=== +^|*Recommendation {counter:rec-id}* |*/rec/geotiff/tile-width-height* +^|A |The coverage resource SHOULD support integer multiple of 16 `tile-width` and `tile-height` parameters when a `tiling` parameter is used. +^|B |The Implementation SHOULD return an error if these parameters are provided without a `tiling` parameter, or if their value is not a multiple of 16 greater than 0. +^|C |The GeoTIFF coverage response SHOULD use these tile width and tile height (TileLength in TIFF terminology). +|=== + +[[rec_geotiff_overview-count]] +[width="90%",cols="2,6a"] +|=== +^|*Recommendation {counter:rec-id}* |*/rec/geotiff/overview-count* +^|A |The coverage resource SHOULD support a integer `overview-count`. +^|B |The Implementation SHOULD return an error if this parameter is smaller than 0. +^|C |The GeoTIFF coverage response SHOULD generate progressively smaller overviews based on that requested number of overviews. +|=== + +NOTE: Clients can use a combination of `tiling`, `tile-width`, `tile-height` and `overview-count` to get a GeoTIFF conforming to the https://docs.ogc.org/is/21-026/21-026.html[OGC Cloud Optimize GeoTIFF] standard. diff --git a/standard/requirements/requirements_class_jpeg2000.adoc b/standard/requirements/requirements_class_jpeg2000.adoc new file mode 100644 index 0000000..e69de29 diff --git a/standard/requirements/requirements_class_jpegxl.adoc b/standard/requirements/requirements_class_jpegxl.adoc new file mode 100644 index 0000000..e69de29 diff --git a/standard/requirements/requirements_class_las.adoc b/standard/requirements/requirements_class_las.adoc new file mode 100644 index 0000000..e69de29 diff --git a/standard/requirements/requirements_class_laszip.adoc b/standard/requirements/requirements_class_laszip.adoc new file mode 100644 index 0000000..e69de29 diff --git a/standard/requirements/requirements_class_netcdf.adoc b/standard/requirements/requirements_class_netcdf.adoc new file mode 100644 index 0000000..e69de29 diff --git a/standard/requirements/requirements_class_png.adoc b/standard/requirements/requirements_class_png.adoc new file mode 100644 index 0000000..97e239e --- /dev/null +++ b/standard/requirements/requirements_class_png.adoc @@ -0,0 +1,35 @@ +[[rc_png]] +[cols="1,4",width="90%"] +|=== +2+|*Requirements Class* +2+|http://www.opengis.net/spec/ogcapi-coverages-1/1.0/req/geotiff +|Target type |Web API +|Dependency |http://www.opengis.net/spec/ogcapi-coverages-1/1.0/req/core +|Dependency |https://www.w3.org/TR/png/ +|=== + +==== Requirements + +[[requirements-class-png-clause]] + +===== PNG representation + +[[req_png_coverage]] +[width="90%",cols="2,6a"] +|=== +^|*Requirement {counter:req-id}* |*/req/png/coverage* +^|A |The coverage resource, as defined in the Core requirement class, SHALL support negotiating a https://www.w3.org/TR/png/[PNG] response using the `image/png` media type. +^|B |The PNG response SHALL use 16-bit values for fields requiring more than 8-bit to encode accurately. +^|C |The Implementation SHALL return a 400 error for requests for any number of fields other than 1 or 3. +^|D |If the response contains multiple fields, the fields SHALL be encoded as bands ordered following the `x-OGC-property-seq` sequence. +^|E | A `Values-Scale:` response header with a numeric real value SHALL be returned indicating the factor by which values were multiplied before an offset was added to result in the encoded 8-bit or 16-bit PNG unsigned integer values. +^|F | A `Values-Offset:` response header with a numeric real value SHALL be returned indicating the offset which was added after multiplying values by the scale factor to result in the encoded 8-bit or 16-bit PNG unsigned integer values. +|=== + +[[rec_png_scale_offset]] +[width="90%",cols="2,6a"] +|=== +^|*Recommendation {counter:rec-id}* |*/rec/png/scale-offset* +^|A |The Implementation SHOULD support a `values-scale` query parameter on coverage resources when requesting a PNG output to indicate the value scale factor, as described in the `Values-Scale:` response header part of the content requirement. +^|B |The Implementation SHOULD support a `values-offset` query parameter on coverage resources when requesting a PNG output to indicate the value offset, as described in the `Values-Offset:` response header part of the content requirement. +|=== diff --git a/standard/requirements/requirements_class_zarr.adoc b/standard/requirements/requirements_class_zarr.adoc new file mode 100644 index 0000000..e69de29