From db8c28172a0ed8106d12d669acd1b0f11981fbff Mon Sep 17 00:00:00 2001 From: Chris Holmes Date: Thu, 5 Apr 2018 16:18:53 -0700 Subject: [PATCH 1/9] moved extension readme text to reflect new folder location --- json-spec/README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/json-spec/README.md b/json-spec/README.md index deae7e6f7..ddc08eca4 100644 --- a/json-spec/README.md +++ b/json-spec/README.md @@ -25,9 +25,6 @@ schema definition, which is a dependency. **Schema Validation:** The *[package.json](package.json)* file defines packaging for node.js NPM module installation to do actual schema valiadtion. The instructions are below. -**Extensions:** The *[extensions/](extensions/)* folder is where profiles and extensions live. These are recommendations for -adding fields for specific domains (like Earth Observation), and for useful constructus. - ## Sample Discussion The first sample, **[sample.json](sample.json)** is the most minimal possible compliant `Item` record. Most all data will From 99ebd412d628377e0ccab06b3152347c27c5a795 Mon Sep 17 00:00:00 2001 From: Chris Holmes Date: Thu, 5 Apr 2018 16:20:06 -0700 Subject: [PATCH 2/9] moved extension readme text to reflect new folder location --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 3f9c9ee37..68c7a84ae 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,9 @@ other tools. **[api-spec/](api-spec/)** defines a dynamic API, specified as a [yaml](api-spec/spec.yaml) file in [OpenAPI](http://openapis.org) 2.0 (swagger). +**Extensions:** The *[extensions/](extensions/)* folder is where profiles and extensions live. Profiles are recommendations for +adding fields for specific domains (like Earth Observation). Extensions bring additional functionality to the core specs. + **Additional documents** include the current [roadmap](roadmap.md) and a complementary [how to help](how-to-help.md) document, a [list of implementations](implementations.md), and a discussion of the collaboration [principles](principles.md) and specification approach. From 22158ef4e76db5e870027fd6cf8ce89ed87a8f14 Mon Sep 17 00:00:00 2001 From: Chris Holmes Date: Fri, 6 Apr 2018 12:56:16 -0700 Subject: [PATCH 3/9] added full landsat example for extensions --- extensions/examples/L1T-collection.json | 93 +++++++++ extensions/examples/README.md | 8 + extensions/examples/landsat8-merged.json | 230 +++++++++++++++++++++++ extensions/examples/landsat8-sample.json | 149 +++++++++++++++ 4 files changed, 480 insertions(+) create mode 100644 extensions/examples/L1T-collection.json create mode 100644 extensions/examples/README.md create mode 100644 extensions/examples/landsat8-merged.json create mode 100644 extensions/examples/landsat8-sample.json diff --git a/extensions/examples/L1T-collection.json b/extensions/examples/L1T-collection.json new file mode 100644 index 000000000..b0864a11b --- /dev/null +++ b/extensions/examples/L1T-collection.json @@ -0,0 +1,93 @@ + +{ + + + "properties": { + "collection_name": "L1T", + "collection_description": "Landat 8 imagery that is radiometrically calibrated and orthorectified using gound points and Digital Elevation Model (DEM) data to correct relief displacement.", + "provider": "USGS", + "license": "PDDL-1.0", + "eo:gsd" : 30, + "eo:platform": "landsat-8", + "eo:instrument": "OLI_TIRS", + }, + + "eo:bands": { + "1": { + "common_name": "coastal", + "gsd": 30.0, + "accuracy": null, + "wavelength": 0.44, + "fwhm": 0.02 + }, + "2": { + "common_name": "blue", + "gsd": 30.0, + "accuracy": null, + "wavelength": 0.48, + "fwhm": 0.06 + }, + "3": { + "common_name": "green", + "gsd": 30.0, + "accuracy": null, + "wavelength": 0.56, + "fwhm": 0.06 + }, + "4": { + "common_name": "red", + "gsd": 30.0, + "accuracy": null, + "wavelength": 0.65, + "fwhm": 0.04 + }, + "5": { + "common_name": "nir", + "gsd": 30.0, + "accuracy": null, + "wavelength": 0.86, + "fwhm": 0.03 + }, + "6": { + "common_name": "swir16", + "gsd": 30.0, + "accuracy": null, + "wavelength": 1.6, + "fwhm": 0.08 + }, + "7": { + "common_name": "swir22", + "gsd": 30.0, + "accuracy": null, + "wavelength": 2.2, + "fwhm": 0.2 + }, + "8": { + "common_name": "pan", + "gsd": 15.0, + "accuracy": null, + "wavelength": 0.59, + "fwhm": 0.18 + }, + "9": { + "common_name": "cirrus", + "gsd": 30.0, + "accuracy": null, + "wavelength": 1.37, + "fwhm": 0.02 + }, + "10": { + "common_name": "lwir11", + "gsd": 100.0, + "accuracy": null, + "wavelength": 10.9, + "fwhm": 0.8 + }, + "11": { + "common_name": "lwir12", + "gsd": 100.0, + "accuracy": null, + "wavelength": 12.0, + "fwhm": 1.0 + } + } \ No newline at end of file diff --git a/extensions/examples/README.md b/extensions/examples/README.md new file mode 100644 index 000000000..40fac8c6f --- /dev/null +++ b/extensions/examples/README.md @@ -0,0 +1,8 @@ +## Landsat Example with EO profile and Collection extension + +The files in this directory contain a full example of Landsat data. It follows the Earth Observation +Profile, and uses the 'Collection' extension to be less duplicative of information + +* [landsat8-sample](landsat8-sample.json) is a core `Item` including the link to its collection information. +* [L1T-collection](L1T-collection.json) shows the collection information for Landsat 8 L1T collection +* [landsat8-merged](landsat8-merged.json) is a fully expanded record, showing the result of merging of the collection data and the core `Item`. \ No newline at end of file diff --git a/extensions/examples/landsat8-merged.json b/extensions/examples/landsat8-merged.json new file mode 100644 index 000000000..b92e23f57 --- /dev/null +++ b/extensions/examples/landsat8-merged.json @@ -0,0 +1,230 @@ +{ + "id": "LC81530252014153LGN00", + "type": "Feature", + "bbox": [ 49.16354,72.27502,51.36812,75.67662 + ], + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 51.33855, + 72.27502 + ], + [ + 51.36812, + 75.70821 + ], + [ + 49.16354, + 72.39640 + ], + [ + 49.19092, + 75.67662 + ], + [ + 51.33855, + 72.27502 + ] + ] + ] + ] + }, + + "properties": { + "datetime": "2014-06-02T09:22:02Z", + "provider": "USGS", + "license": "PDDL-1.0", + "eo:platform": "landsat-8", + "eo:instrument": "OLI_TIRS", + "eo:collection": "L1T", + "eo:gsd": 30.0, + "eo:cloud_cover" : 10, + "eo:off_nadir" : 0.000, + "eo:azimuth": 0.00, + "eo:sun_azimuth" : 149.01607154, + "eo:sun_elevation" : 59.21424700, + "landsat:wrs_path": 153, + "landsat:wrs_row": 25, + "landsat:earth_sun_distance": 1.0141560, + "landsat:ground_control_points_verify": 114, + "landsat:geometric_rmse_model": 7.562, + "landsat:image_quality_tirs": 9, + "landsat:ground_control_points_model": 313, + "landsat:geometric_rmse_model_x": 5.96, + "landsat:geometric_rmse_model_y": 4.654, + "landsat:geometric_rmse_verify": 5.364, + "landsat:image_quality_oli": 9 + }, + + "links": [ + { "rel":"self", "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00.json"}, + { "rel":"alternate", "href": "https://landsatonaws.com/L8/153/025/LC81530252014153LGN00", "type": "html"}, + { "rel":"catalog", "href": "http://landsat-pds.s3.amazonaws.com/L8/catalog.json"} + ], + + "assets" :{ + "thumbnail": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_thumb_large.jpg", + "required": true, + "type": "jpeg" + }, + "metadata": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_MTL.txt", + "required": true, + "type": "mtl" + }, + "B1": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B1.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["1"] + }, + "B2": { + + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B2.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["2"] + }, + "B3": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B3.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["3"] + }, + "B4": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B4.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["4"] + }, + "B5": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B5.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["5"] + }, + "B6": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B6.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["6"] + }, + "B7": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B7.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["7"] + }, + "B8": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B8.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["8"] + }, + "B9": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B9.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["9"] + }, + "B10": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B10.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["10"] + }, + "B11": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B11.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["11"] + }, + + "eo:bands": { + "1": { + "common_name": "coastal", + "gsd": 30.0, + "accuracy": null, + "wavelength": 0.44, + "fwhm": 0.02 + }, + "2": { + "common_name": "blue", + "gsd": 30.0, + "accuracy": null, + "wavelength": 0.48, + "fwhm": 0.06 + }, + "3": { + "common_name": "green", + "gsd": 30.0, + "accuracy": null, + "wavelength": 0.56, + "fwhm": 0.06 + }, + "4": { + "common_name": "red", + "gsd": 30.0, + "accuracy": null, + "wavelength": 0.65, + "fwhm": 0.04 + }, + "5": { + "common_name": "nir", + "gsd": 30.0, + "accuracy": null, + "wavelength": 0.86, + "fwhm": 0.03 + }, + "6": { + "common_name": "swir16", + "gsd": 30.0, + "accuracy": null, + "wavelength": 1.6, + "fwhm": 0.08 + }, + "7": { + "common_name": "swir22", + "gsd": 30.0, + "accuracy": null, + "wavelength": 2.2, + "fwhm": 0.2 + }, + "8": { + "common_name": "pan", + "gsd": 15.0, + "accuracy": null, + "wavelength": 0.59, + "fwhm": 0.18 + }, + "9": { + "common_name": "cirrus", + "gsd": 30.0, + "accuracy": null, + "wavelength": 1.37, + "fwhm": 0.02 + }, + "10": { + "common_name": "lwir11", + "gsd": 100.0, + "accuracy": null, + "wavelength": 10.9, + "fwhm": 0.8 + }, + "11": { + "common_name": "lwir12", + "gsd": 100.0, + "accuracy": null, + "wavelength": 12.0, + "fwhm": 1.0 + } + } + + + } + + } diff --git a/extensions/examples/landsat8-sample.json b/extensions/examples/landsat8-sample.json new file mode 100644 index 000000000..dfccdd7c5 --- /dev/null +++ b/extensions/examples/landsat8-sample.json @@ -0,0 +1,149 @@ +{ + "id": "LC81530252014153LGN00", + "type": "Feature", + "bbox": [ 49.16354,72.27502,51.36812,75.67662 + ], + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 51.33855, + 72.27502 + ], + [ + 51.36812, + 75.70821 + ], + [ + 49.16354, + 72.39640 + ], + [ + 49.19092, + 75.67662 + ], + [ + 51.33855, + 72.27502 + ] + ] + ] + ] + }, + + "properties": { + "datetime": "2014-06-02T09:22:02Z", + "provider": "USGS", + "license": "PDDL-1.0", + "eo:collection": "L1T", + "eo:gsd": 30.0, + "eo:cloud_cover" : 10, + "eo:off_nadir" : 0.000, + "eo:azimuth": 0.00, + "eo:sun_azimuth" : 149.01607154, + "eo:sun_elevation" : 59.21424700, + "landsat:wrs_path": 153, + "landsat:wrs_row": 25, + "landsat:earth_sun_distance": 1.0141560, + "landsat:ground_control_points_verify": 114, + "landsat:geometric_rmse_model": 7.562, + "landsat:image_quality_tirs": 9, + "landsat:ground_control_points_model": 313, + "landsat:geometric_rmse_model_x": 5.96, + "landsat:geometric_rmse_model_y": 4.654, + "landsat:geometric_rmse_verify": 5.364, + "landsat:image_quality_oli": 9 + }, + + "links": [ + { "rel":"self", "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00.json"}, + { "rel":"alternate", "href": "https://landsatonaws.com/L8/153/025/LC81530252014153LGN00", "type": "html"}, + { "rel":"catalog", "href": "http://landsat-pds.s3.amazonaws.com/L8/catalog.json"} + { "rel":"collection", "href": "http://landsat-pds.s3.amazonaws.com/L8/L1T-collection.json"} + ], + + "assets" :{ + "thumbnail": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_thumb_large.jpg", + "required": true, + "type": "jpeg" + }, + "metadata": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_MTL.txt", + "required": true, + "type": "mtl" + }, + "B1": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B1.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["1"] + }, + "B2": { + + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B2.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["2"] + }, + "B3": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B3.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["3"] + }, + "B4": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B4.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["4"] + }, + "B5": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B5.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["5"] + }, + "B6": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B6.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["6"] + }, + "B7": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B7.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["7"] + }, + "B8": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B8.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["8"] + }, + "B9": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B9.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["9"] + }, + "B10": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B10.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["10"] + }, + "B11": { + "href": "http://landsat-pds.s3.amazonaws.com/L8/153/025/LC81530252014153LGN00/LC81530252014153LGN00_B11.TIF", + "type": "GeoTIFF", + "required": true, + "eo:bands": ["11"] + } + + + } + + } From 92ea25533807203cf2c02a078a6e0c6594b2a39b Mon Sep 17 00:00:00 2001 From: Chris Holmes Date: Fri, 6 Apr 2018 13:10:42 -0700 Subject: [PATCH 4/9] added warning, cleanup --- extensions/stac-collection-spec.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/extensions/stac-collection-spec.md b/extensions/stac-collection-spec.md index 1d59aa500..1397d9c80 100644 --- a/extensions/stac-collection-spec.md +++ b/extensions/stac-collection-spec.md @@ -1,6 +1,11 @@ # STAC Collection Extension Spec -A group of STAC `Item` objects from a single source usually shared common metadata. This is especially true with satellite imagery that uses the STAC EO Extension. Rather than including these common metadata fields on every `Item`, they can be grouped into a `Collection`. +A group of STAC `Item` objects from a single source usually share a set of common metadata. This is especially true with satellite imagery that uses the STAC EO Extension. Rather than including these common metadata fields on every `Item`, they can be grouped into a `Collection`. + +### Warning +This extension is still in its very first iteration, and likely will change as it gets use. Indeed there is a desire to combine it somehow with the static catalog +'catalog.json' file, and to make sure it works very generically. There is a powerful and useful idea here, to be able to reference fields that don't need to repeat +in every item. But the naming and fields may shift. Please try it out and give feedback on what works. ## Collection Extension Description @@ -9,7 +14,10 @@ A group of STAC `Item` objects from a single source usually shared common metada | collection_name | string | Collection Name | A name given to the Collection | collection_description | string (optional) | Collection Description | A human readable description of the collection -A `Collection` does not have many specific fields, as it may contain any fields that are in the core spec as well as any other extension. If a field is specified in `Collection`, it will be ignored in any `Item` that links to that `Collection`. This is important because a `Collection` is the metadta that is common across all `Item` objects. If a field is variable at all, it should be part of the `Item` record. +A `Collection` does not have many specific fields, as it may contain any fields that are in the core spec as well as any other extension. If a field +is specified in `Collection`, it will be ignored in any `Item` that links to that `Collection`. This is important because a `Collection` represents +the metadata that is common across all `Item` objects. If a field is variable at all, it should be part of the `Item` record. An `Item` that links +to a `Collection` is essentially saying: *all fields listed in the collection are also true for me*. #### Linking to a `Collection` An `Item` links to a collection by providing a "link" with "rel" set to "collection". For example @@ -28,7 +36,7 @@ The fields from the `Collection` record can be merged with an `Item` record to g "license": "MIT" } } -# an item (incomplete) +# an item (variable information) { "id": "SCENE_001", "properties": { @@ -62,6 +70,9 @@ The merged `Item` then looks like this: } ``` +Both STAC API's and static catalogs should return by default the core `Item` with a link to the collection. They may +also choose to link to a 'merged item' that includes all the repeating information as one of the 'assets'. + #### `Collection` Example This is an example `Collection` for Landsat-8 imagery and uses the EO extension. ``` From f246bb2997812608f8e4b06176f72c296bce9be4 Mon Sep 17 00:00:00 2001 From: Tim Rutherford Date: Fri, 6 Apr 2018 16:14:45 -0600 Subject: [PATCH 5/9] Features/time interval (#96) * Switching time ranges to use period syntax This matches what WFS is using as well as incorporating an extension into the core * updating yaml docs --- api-spec/STAC-fragment.yaml | 30 ++++++----------- api-spec/STAC-standalone.yaml | 24 +++++--------- api-spec/WFS3core+STAC.yaml | 22 ++++--------- api-spec/filters.md | 61 ++++++++++++++++++++++++----------- 4 files changed, 66 insertions(+), 71 deletions(-) diff --git a/api-spec/STAC-fragment.yaml b/api-spec/STAC-fragment.yaml index 98947127f..282bf1fcc 100644 --- a/api-spec/STAC-fragment.yaml +++ b/api-spec/STAC-fragment.yaml @@ -125,17 +125,18 @@ components: name: time in: query description: >- - A time range search that accepts a JSON search object. - + Either a date-time or a period string that adheres to RFC3339. Examples: + * A date-time: "2018-02-12T23:20:50Z" + * A period: "2018-02-12T00:00:00Z/2018-03-18T12:31:12Z" or "2018-02-12T00:00:00Z/P1M6DT12H31M12S" Only features that have a temporal property that intersects the value of `time` are selected. - If a feature has multiple temporal properties, it is the decision of the - server whether only a single temporal property is used to determine the - extent or all relevant temporal properties. + server whether only a single temporal property is used to determine + the extent or all relevant temporal properties. required: false schema: - $ref: '#/components/schemas/timeRange' + type: string + style: form explode: false schemas: searchBody: @@ -151,9 +152,7 @@ components: - 39 - -105 - 41 - time: - gt: "2018-03-15T00:00:00.000Z" - lt: "2018-06-01T00:00:00.000Z" + time: "2018-03-15T00:00:00.000Z" bboxFilter: type: object description: Only return items that intersect the provided bounding box. @@ -165,7 +164,7 @@ components: type: object properties: time: - $ref: '#/components/schemas/timeRange' + $ref: '#/components/parameters/time' intersectsFilter: type: object description: Only returns items that intersect with the provided polygon. @@ -221,17 +220,6 @@ components: description: >- A single date-time string that adheres to RFC3339, for example 1985-04-12T23:20:50.52Z - timeRange: - type: object - properties: - gt: - $ref: '#/components/schemas/time' - lt: - $ref: '#/components/schemas/time' - gte: - $ref: '#/components/schemas/time' - lte: - $ref: '#/components/schemas/time' itemCollection: type: object required: diff --git a/api-spec/STAC-standalone.yaml b/api-spec/STAC-standalone.yaml index 595fbeb3f..778a09e21 100644 --- a/api-spec/STAC-standalone.yaml +++ b/api-spec/STAC-standalone.yaml @@ -150,27 +150,19 @@ components: time: name: time in: query - description: >- - A time range search that accepts a JSON search object. - + description: | + Either a date-time or a period string that adheres to RFC3339. Examples: + * A date-time: "2018-02-12T23:20:50Z" + * A period: "2018-02-12T00:00:00Z/2018-03-18T12:31:12Z" or "2018-02-12T00:00:00Z/P1M6DT12H31M12S" Only features that have a temporal property that intersects the value of `time` are selected. - If a feature has multiple temporal properties, it is the decision of the - server whether only a single temporal property is used to determine the - extent or all relevant temporal properties. + server whether only a single temporal property is used to determine + the extent or all relevant temporal properties. required: false schema: - type: object - properties: - gt: - $ref: '#/components/schemas/time' - lt: - $ref: '#/components/schemas/time' - gte: - $ref: '#/components/schemas/time' - lte: - $ref: '#/components/schemas/time' + type: string + style: form explode: false collectionId: name: collectionId diff --git a/api-spec/WFS3core+STAC.yaml b/api-spec/WFS3core+STAC.yaml index af7c3c321..c52f8aa9e 100644 --- a/api-spec/WFS3core+STAC.yaml +++ b/api-spec/WFS3core+STAC.yaml @@ -308,26 +308,18 @@ components: name: time in: query description: >- - A time range search that accepts a JSON search object. - + Either a date-time or a period string that adheres to RFC3339. Examples: + * A date-time: "2018-02-12T23:20:50Z" + * A period: "2018-02-12T00:00:00Z/2018-03-18T12:31:12Z" or "2018-02-12T00:00:00Z/P1M6DT12H31M12S" Only features that have a temporal property that intersects the value of `time` are selected. - If a feature has multiple temporal properties, it is the decision of the - server whether only a single temporal property is used to determine the - extent or all relevant temporal properties. + server whether only a single temporal property is used to determine + the extent or all relevant temporal properties. required: false schema: - type: object - properties: - gt: - $ref: '#/components/schemas/time' - lt: - $ref: '#/components/schemas/time' - gte: - $ref: '#/components/schemas/time' - lte: - $ref: '#/components/schemas/time' + type: string + style: form explode: false collectionId: name: collectionId diff --git a/api-spec/filters.md b/api-spec/filters.md index f93b1fbd7..cff123c55 100644 --- a/api-spec/filters.md +++ b/api-spec/filters.md @@ -6,7 +6,7 @@ and are required to be supported. The filters are designed to be simple as possible for a client to construct. To match the default JSON responses the encoding of filters is done by default in JSON. This allows clients to support filtering without additional tools. The -search enpoint will accept application/json format queries, and GET on the collection will support URL encoded JSON. POST +search endpoint will accept application/json format queries, and GET on the collection will support URL encoded JSON. POST search the is recommended way to filter results to avoid the URL encoding issues that can happen with GET. Searching using POST will accept a JSON object where the top level keys are specifying which type of filter @@ -20,33 +20,60 @@ This query will perform an intersects operation on the geometry values of the it objects may provide a bbox property in addition to geometry, but it should not be used for the bbox filter since it is an optional field in GeoJSON. -example +###### examples: ###### +POST: ``` { "bbox": [-180,-90,180,90] } ``` -The temporal query will be based on [RFC 3339](https://tools.ietf.org/html/rfc3339) and should support time ranges as well as equality. To support range -queries, we are using a simple JSON based language. Ranges will be specified as an object with keys indicating the comparison to use. +GET: +``` +?bbox=[-180,-90,180,90] +``` + +The temporal query will be based on [RFC 3339](https://tools.ietf.org/html/rfc3339) and should support time ranges as well as equality. It will compare against the datetime property of the STAC Item. + +###### To find items with an exact date ###### + +POST: +``` +{ + "time": "2007-03-01T13:00:00Z" +} +``` -Equality is specified as `{"time": "2018-03-20T16:11:44.353Z"}` -Before is `{"time":{"lt":"2018-03-20T16:11:44.353Z"}}` -After is `{"time":{"gt":"2018-03-20T16:11:44.353Z"}}` -Before with Equality is `{"time":{"lte":"2018-03-20T16:11:44.353Z"}}` -After with Equality is `{"time":{"gte":"2018-03-20T16:11:44.353Z"}}` +GET: +``` +?time=2007-03-01T13:00:00Z +``` -These queries can be combined to specify a search range: +###### To specify a time range, use the interval syntax: ###### +POST: ``` { - "time": { - "gt":"2018-03-15T00:00:00.000Z", - "lt":"2018-06-01T00:00:00.000Z", - } -} + "time": "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z" +} ``` +GET: +``` +?time=2007-03-01T13:00:00Z/2008-05-11T15:30:00Z +``` + +###### Specify intervals using durations: ###### + +`2007-03-01T13:00:00Z/P1Y2M10DT2H30M` + +If time is a period with out a start or end date, the end date is assigned to now: + +`P1Y2M10DT2H30M` is the same as `"P1Y2M10DT2H30M/" + new Date().toISOString()` + + + + Filter Extensions ----------------- @@ -124,10 +151,6 @@ Some additional extensions that have been discussed: CQL support for generic queries: `{"CQL": "CQL Select String"}` -Time intervals: -`{"time": "P1Y"}` Assume Duration/now if no time specified? -`{"time": "2018/P1M"}` Any time in january of 2018 - Adding filters to search ------------------------ From 4e9af239e102a31226719565482a8a7e6c568d64 Mon Sep 17 00:00:00 2001 From: Chris Holmes Date: Fri, 6 Apr 2018 16:17:53 -0700 Subject: [PATCH 6/9] various cleanup, added warning, brought in dependency on the collection spec to make that relationship clearer --- extensions/stac-eo-spec.md | 86 +++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/extensions/stac-eo-spec.md b/extensions/stac-eo-spec.md index 5700c2349..1e94b25b9 100644 --- a/extensions/stac-eo-spec.md +++ b/extensions/stac-eo-spec.md @@ -1,33 +1,38 @@ -# STAC EO Extension JSON Spec +# STAC EO Profile -This document explains the fields of the STAC Earth Observation (EO) Extension to a STAC `Item`. EO data is considered to be data that represents a snapshot of the earth for a single date and time. It could consist of multiple spectral bands in any part of the electromagnetic spectrum. Examples of EO data include sensors with visible, short-wave and mid-wave IR bands (e.g., the OLI instrument on Landsat-8), long-wave IR bands (e.g. TIRS aboard Landsat-8), as well as SAR instruments (e.g. Sentinel-1). +This document explains the fields of the STAC Earth Observation (EO) Profile, which adds to the core fields of a STAC `Item`. EO data is considered to be data that +represents a snapshot of the earth for a single date and time. It could consist of multiple spectral bands in any part of the electromagnetic spectrum. Examples of EO data + include sensors with visible, short-wave and mid-wave IR bands (e.g., the OLI instrument on Landsat-8), long-wave IR bands (e.g. TIRS aboard Landsat-8), as well as SAR + instruments (e.g. Sentinel-1). ## EO Extension Description -These are fields that extend the `Item` object -## `Item` additions +These are fields that extend the `Item` object, as well as the items's assets field and `Collection` level metadata. The EO Profile generally assumes that you are +using the [STAC collection extension](stac-collection-spec.md), so puts all the repetitive fields at the `Collection` level. Since the collection extension is still +being fleshed out it is also acceptable to just put the required Collection fields as `Item` level properties. + +## Item additions | element | type info | name | description | |----------------------|---------------------------|-------------------------|---------------------------------------------------------------------------------------------| | eo:gsd | float | Ground Sample distance | The minimum distance between pixel centers available, in meters | -| eo:platform | string | Unique name of platform | Specific name of the platform (e.g., landsat-8, sentinel-2A, larrysdrone) | -| eo:instrument | string | Instrument used | Name of instrument or sensor (e.g., MODIS, ASTER, OLI, Canon F-1) | -| eo:bands | dictionary | Band Info | Band specific metadata (see below) | eo:crs | string | ref system | CRS of the datasource in full WKT format. null if no crs | eo:cloud_cover | integer (optional) | Cloud Cover Pct | Percent of cloud cover (1-100) | | eo:off_nadir | float (optional) | Off nadir | Viewing angle. 0-90 degrees, measured from nadir | eo:azimuth | float (optional) | Azimuth | Viewing azimuth angle. 0-360 degrees, measured clockwise from north | eo:sun_azimuth | float (optional) | Sun Azimuth | Sun azimuth angle. 0-360 degrees, measured clockwise from north | eo:sun_elevation | float (optional) | Sun Elevation | Sun elevation angle. 0-90 degrees measured from horizon +| eo:collection | string (optional | Collection Name | The name of the STAC `Collection` this `Item` belongs to | -## `Item` Field Descriptions -**eo:gsd** is the nominal Ground Sample Distance for the data, as measured in meters on the ground. Since GSD can vary across a scene depending on projection, this should be the average GSD in the center of the image. If the data includes multiple bands with different GSD values, this should be the best GSD available. +All of these values go in the 'properties' object of the STAC Item. As can be seen most are optional, though they are highly recommended for Earth Observation +imagery. It is likely more optional fields will be added as multiple providers expose the fields they use and consensus as to common names and values emerge. +For now if you are a provider with fields you'd like to add just put them under your own prefix, but also propose its use in an [issue](https://github.com/radiantearth/stac-spec/issues). -**eo:platform** is the name of the specific platform the instrument is attached to. For satellites this would be the name of the satellite (e.g., landsat-8, sentinel-2A), whereas for drones this would be a unique name for the drone. -**eo:instrument** The instrument is the name of the sensor used, although for Items which contain data from multiple sensors this could also name multiple sensors. For example, data from the Landsat-8 platform is collected with the OLI sensor as well as the TIRS sensor, but the data is distributed together and commonly referred to as OLI_TIRS. +### Item Field Descriptions in Properties -**eo:bands** This is a dictionary of band information where each key in the dictionary is an identifier for the band (e.g., "B01", "B02", "B1", "B5", "QA"). See below for more information on band metadata. +**eo:gsd** is the nominal Ground Sample Distance for the data, as measured in meters on the ground. Since GSD can vary across a scene depending on projection, this should be the average GSD in the center of the image. If the data includes multiple bands with different GSD values, this should be the best GSD available. If there are different +GSD values in the bands those should be specified in the `eo:bands` section of the Collection, specified below. **eo:crs**: The Coordinate Reference System (CRS) is the native reference system (sometimes called a 'projection') used by the data, provided in [Well-Known Text (WKT) format](https://en.wikipedia.org/wiki/Well-known_text). This field is required. If the data does not have a CRS, such as in the case of non-rectified imagery with Ground Control Points, eo:crs should be set to null. @@ -41,8 +46,54 @@ These are fields that extend the `Item` object **eo:sun_elevation**: This is the angle from the tangent of ths scene center point to the sun. Measured in degrees (0-90). -## `Item:eo:bands` -The bands field of a `Item` is a dictionary where the index identifies a specific band. This is often a band number (e.g., 1, B1, B01), but could be any unique identifier. +**eo:collection**: This should refer to the `collection_name` field in the Collection metadata that is referenced in the `links` section of the `Item`. This is +used to enable filtering between different collections, which is important when more than one collection is contained in a single catalog. + +### Item:links additions + +Additionally there should be an entry in the `links` array that is called `collection`, as specified in the [STAC collection extension](stac-collection-spec.md). + +``` +{ "rel": "collection", "href": "link/to/collection/record" } +``` + +See that spec for more information. + +### Item:assets additions + +One of the unique features of Earth Observation data is that providers arrange their assets in all sorts of different ways. Some, like Landsat, provide a file for +each band, while others combine bands in to multiple files. Some provide multi-band 'analytic' products as well as 3 band 'visual' ones, and then the order of the +bands that they include are often different. + +The EO profile includes a full definition of the bands in the `Collection` file, but then each asset will specify what bands it covers, and in what order. + +| element | type info | name | description | +|----------------------|---------------------------|-------------------------|---------------------------------------------------------------------------------------------| +| eo:bands | string array | Bands (optional) | An array of strings that index the `eo:bands` field in a `Collection`. + +The strings in the array should be the lookup for the dictionary of the `eo:bads` section of a `Collection`, specified below. + +## Collection additions + +These fields belong in the `Collection` file, which is a dependency of the EO profile (if you are experimenting withnot using a collection link +then these fields are still required, and should be in the Item properties - they will just be duplicative). The `collection_name` is required for the +extension, and is used in the `Item` to enable search by collection. It is also recommended to use the `collection_description` so a more informative +description can be displayed to users. + +| element | type info | name | description | +|----------------------|---------------------------|-------------------------|---------------------------------------------------------------------------------------------| +| eo:platform | string | Unique name of platform | Specific name of the platform (e.g., landsat-8, sentinel-2A, larrysdrone) | +| eo:instrument | string | Instrument used | Name of instrument or sensor (e.g., MODIS, ASTER, OLI, Canon F-1) | +| eo:bands | dictionary | Band Info | Band specific metadata (see below) + +**eo:platform** is the name of the specific platform the instrument is attached to. For satellites this would be the name of the satellite (e.g., landsat-8, sentinel-2A), whereas for drones this would be a unique name for the drone. + +**eo:instrument** The instrument is the name of the sensor used, although for Items which contain data from multiple sensors this could also name multiple sensors. For example, data from the Landsat-8 platform is collected with the OLI sensor as well as the TIRS sensor, but the data is distributed together and commonly referred to as OLI_TIRS. + +**eo:bands** This is a dictionary of band information where each key in the dictionary is an identifier for the band (e.g., "B01", "B02", "B1", "B5", "QA"). See below for more information on band metadata. + +### eo:bands in Collection +The bands field of a `Collection` is a dictionary where the index identifies a specific band. This is often a band number (e.g., 1, B1, B01), but can be a string (like 'udm' for an unusable data mask band, and can be any unique identifier. It is used in the `eo:bands` property of an asset in an `Item | element | type info | name | description | |----------------------|---------------------------|-------------------------|---------------------------------------------------------------------------------------------| @@ -52,7 +103,7 @@ The bands field of a `Item` is a dictionary where the index identifies a specifi | center_wavelength | float (optional) | Center wavelength | The center wavelength of the band, in microns | full_width_half_max | float (optional) | Full width at half maximum | The width of the band, as measured at half the maximum transmission, in microns -## `Item:eo:bands` Field Descriptions +### eo:bands in Collection Field Descriptions **common_name** is a name commonly used to refer to the band to make it easier to search for bands across instruments. See below for a list of accepted common names. @@ -64,7 +115,7 @@ The bands field of a `Item` is a dictionary where the index identifies a specifi **full_width_half_max** (FWHM) is a common way to describe the size of a spectral band. It is the width, in microns, of the bandpass measured at a half of the maximum transmission. Thus, if the maximum transmission of the bandpass was 80%, the FWHM is measured as the width of the bandpass at 40% transmission. -## Common Band Names +### Common Band Names The band's common_name is the name that is commonly used to refer to that band's spectral properties. The table below shows the common name based on the average band range for the band numbers of several popular instruments. | Common Name | Band Range (μm) | Landsat 5 | Landsat 7 | Landsat 8 | Sentinel 2 | MODIS | @@ -81,3 +132,6 @@ The band's common_name is the name that is commonly used to refer to that band's |lwir11 | 10.5 - 11.5 | | | 10 | | 31 |lwir12 | 11.5 - 12.5 | | | 11 | | 32 +### Sample data + +See the [examples/](examples/) folder for a full landsat definition. \ No newline at end of file From fb655c30f2d021d3e7728c3b98a6ec614d8dd14f Mon Sep 17 00:00:00 2001 From: Chris Holmes Date: Fri, 6 Apr 2018 16:21:34 -0700 Subject: [PATCH 7/9] updated info on the EO profile --- json-spec/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/json-spec/README.md b/json-spec/README.md index ddc08eca4..f479e0f63 100644 --- a/json-spec/README.md +++ b/json-spec/README.md @@ -71,7 +71,7 @@ too loose right now, it just checks for a string, see the 'relative vs absolute STAC Items are still a work in progress, and feedback is very much appreciated. The core fields were designed to be quite flexible, adapting to many different data organization schemes. Organizations are encouraged to adapt -the core fields to their needs, finding any limitations that would need the specification. +the core fields to their needs, finding any limitations that would need to be addressed the specification. Implementors are encouraged to publish their implementations, ideally contributing to the examples folder. This will enable a spreading of best practices, and it is hoped that additional specification extensions can @@ -79,16 +79,16 @@ become best practices or their own specifications. There is also interest in representing additional domain-specific information. The core STAC fields were made to be flexible to a variety of assets. But there is a lot of value in shared fields that may not apply -to every STAC data type, but are shared by a certain domain. The most likely first domain will be "Earth -Observation" - satellite imagery - as many of the initial participants in creating the specification were -from that domain. +to every STAC data type, but are shared by a certain domain. There is a just released 'profile' for +Earth Observation, see the [extensions/](../extensions/) folder in the top directory for a set of recommended +fields if you are providing earth observation data. ### Recommendations The evolution of the STAC JSON spec will take place in this repository, primarily informed by the 'examples' folder. This will show how a variety of providers at least could represent their catalogs in STAC static catalogs (and as things mature the examples will mirror their production catalogs). The various recommendations can -be viewed in the **TODO:** [recommendations](recommendations.md) document. Some of these will likely +be viewed in the **TODO** [recommendations](recommendations.md) document. Some of these will likely evolve to be requirements, or at least documented specification options and extensions. From a9f39dc840477b35e8c00b699f51398428ec05a2 Mon Sep 17 00:00:00 2001 From: Chris Holmes Date: Fri, 6 Apr 2018 16:24:59 -0700 Subject: [PATCH 8/9] update so the self link is a valid URL --- json-spec/examples/digitalglobe-sample.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json-spec/examples/digitalglobe-sample.json b/json-spec/examples/digitalglobe-sample.json index 5021a425c..59eae99b4 100644 --- a/json-spec/examples/digitalglobe-sample.json +++ b/json-spec/examples/digitalglobe-sample.json @@ -87,7 +87,7 @@ "links": [ { "rel": "self", - "href": "my url" + "href": "https://s3.amazonaws.com/digitalglobe-static-catalog/collections/dg_worldview02_LV1B/103001004B316600_P002_MUL" }, { "rel": "collection", From fc84a35c5d0b2fabc8d660b31682f546ae006f7f Mon Sep 17 00:00:00 2001 From: Chris Holmes Date: Fri, 6 Apr 2018 16:38:37 -0700 Subject: [PATCH 9/9] finished up the todos --- api-spec/wfs-stac.md | 45 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/api-spec/wfs-stac.md b/api-spec/wfs-stac.md index 59103c7a3..39551fe56 100644 --- a/api-spec/wfs-stac.md +++ b/api-spec/wfs-stac.md @@ -27,9 +27,48 @@ STAC endpoint. ### WFS Structure -TODO: Give an overview of the main WFS endpoints +A Web Feature Service is a standard API that represents collections of geospatial data. + +``` +GET /collections +``` + +Lists the collections of data on the server that can be queried ([7.11](https://rawgit.com/opengeospatial/WFS_FES/master/docs/17-069.html#_feature_collections_metadata)), +and each describes basic information about the geospatial data collection, like its name and description, as well as the +spatial and temporal extents of all the data contained. A STAC search extension would only query those collections which +have data that validates as STAC `Items` - with a datetime field and references to assets. But a STAC can live alongside +other WFS collections, like an organization might choose to have their building and road data in WFS collections, alongside +their STAC-compatible imagery data. + +``` +GET /collections/{name}/items?bbox=160.6,-55.95,-170,-25.89 +``` + +Requests all the data in the collection that is in New Zealand. The filtering is made to be compatible with the STAC API, +and the two specs seek to share the general query and filtering patterns. The key difference is that a STAC search endpoint +will do cross collection search. A typical WFS will have multiple collections, and each will just offer search for its particular +collection. + ### Strongly Typed STAC data -TODO: explain the advantages of using WFS to provide schema information at a collection level, for stronger typing -of data. Plus transactions. \ No newline at end of file +The scenario that using a WFS with a STAC search endpoint that makes the most sense is when a data provider wants to provide more +insight in to heterogenous data that is exposed on a STAC search. For example they might have imagery data from different satellite providers +and even some drone data. These will all have different fields. A single STAC endpoint can be used to expose them all. But it can be quite +useful to let users inspect a particular data type. That area of the `/collections/{name}` hierarchy can be used to expose additional +metadata and validation schemas that give more insight in to that data, as well as a place to query just that data. + +In general it is recommended to provide as much information about different types of data as possible, so using WFS is recommended. But +the standalone option is there for those who just want to expose their data as quickly and easily as possible. Note a WFS can +provide heterogenous data from any of its collections endpoints, but the STAC API recommendation is to use one collection per +logical data type. + +### Potential Transaction Extension + +The other benefit of individual collection endpoints is that it gives a logical location for simple RESTful transactions + +``` +POST /collections/landsat/items/ +``` + +There have been a couple implementations that have done transactions, and soon will contribute an extension.