Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bands RFC #1213 #1254

Merged
merged 12 commits into from
Aug 5, 2024
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Added

- `bands` is a new field in common metadata to replace `eo:bands` and `raster:bands` ([#1213](https://github.com/radiantearth/stac-spec/discussions/1213))
- The fields `data_type`, `nodata`, `statistics` and `unit` have been added to common metadata ([#1213](https://github.com/radiantearth/stac-spec/discussions/1213))
- The `keywords` field known from Collections is available in common metadata. ([#1187](https://github.com/radiantearth/stac-spec/issues/1187))
- New fields `method`, `headers` and `body` in the Link Object. ([#1198](https://github.com/radiantearth/stac-spec/issues/1198))
- The `license` field additionally supports SPDX expressions and the value `other`.
Expand Down
250 changes: 237 additions & 13 deletions best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,12 @@
- [Field selection and Metadata Linking](#field-selection-and-metadata-linking)
- [Datetime selection](#datetime-selection)
- [Unlocated Items](#unlocated-items)
- [Unrectified Satellite Data](#unrectified-satellite-data)
- [Data that is not spatial](#data-that-is-not-spatial)
- [Representing Vector Layers in STAC](#representing-vector-layers-in-stac)
- **[Asset and Link Best Practices](#asset-and-link-best-practices)**
- [Common Use Cases of Additional Fields for Assets](#common-use-cases-of-additional-fields-for-assets)
- [Working with Media Types](#working-with-media-types)
- [Common Media Types in STAC](#common-media-types-in-stac)
- [Formats with no registered media type](#formats-with-no-registered-media-type)
- [Asset Roles](#asset-roles)
- [List of Asset Roles](#list-of-asset-roles)
- [Bands](#bands)
- **[Catalog & Collection Best Practices](#catalog--collection-practices)**
- [Static and Dynamic Catalogs](#static-and-dynamic-catalogs)
- [Static Catalogs](#static-catalogs)
Expand All @@ -38,13 +34,11 @@
- [Published Catalogs](#published-catalogs)
- [Using Relation Types](#using-relation-types)
- [Versioning for Catalogs](#versioning-for-catalogs)
- [Example](#example)
- [Static to Dynamic best practices](#static-to-dynamic-best-practices)
- [Ingestion and links](#ingestion-and-links)
- [Keep catalogs in sync with cloud notification and queue services](#keep-catalogs-in-sync-with-cloud-notification-and-queue-services)
- [How to Differentiate STAC Files](#how-to-differentiate-stac-files)


This document makes a number of recommendations for creating real world SpatioTemporal Asset Catalogs. None of them
are required to meet the core specification, but following these practices will make life easier for client tooling
and for users. They come about from practical experience of implementors and introduce a bit more 'constraint' for
Expand Down Expand Up @@ -294,7 +288,7 @@ providing them at the Asset level can prove to be very useful for using the data
with different spatial resolution than the overall best resolution. Note this should not be used for different
spatial resolutions due to specific processing of assets - look into the [raster
extension](https://github.com/stac-extensions/raster) for that use case.
- `eo:bands` ([EO extension](https://github.com/stac-extensions/eo/)):
- `bands` (e.g. in combination with the [EO extension](https://github.com/stac-extensions/eo/)):
Provide spectral band information, and order of bands, within an individual asset.
- `proj:epsg`/`proj:wkt2`/`proj:projjson` ([projection extension](https://github.com/stac-extensions/projection/)):
Specify different projection for some assets. If the projection is different
Expand All @@ -305,7 +299,7 @@ providing them at the Asset level can prove to be very useful for using the data
If assets have different spatial resolutions and slightly different exact bounding boxes,
specify these per asset to indicate the size of the asset in pixels and its exact GeoTransform in the native projection.
- `sar:polarizations` ([sar extension](https://github.com/stac-extensions/sar)):
Provide the polarization content and ordering of a specific asset, similar to `eo:bands`.
Provide the polarization content and ordering of a specific asset.
- `sar:product_type` ([sar extension](https://github.com/stac-extensions/sar)):
If mixing multiple product types within a single Item, this can be used to specify the product_type for each asset.

Expand Down Expand Up @@ -428,6 +422,236 @@ If your data for the Item does not come with a thumbnail already we do recommend
| Spatial extent | Limited | Full | Full |
| Use case | Quick overview, often in lists of items/collections | Display for a single Item/Collection, sometimes shown on a web map | Display for a single Item/Collection, often shown on a map, may be displayed in GIS software |

### Bands

The new `bands` array in combination with the property inheritance introduced in STAC 1.1 provides users with more flexibility.
m-mohr marked this conversation as resolved.
Show resolved Hide resolved
The following best practices should be considered, especially when migrating from `eo:bands` and `raster:bands`.

#### Single band

Single band assets can be defined in two ways.
Properties can be defined in the `bands` array or in the assets directly.

Example using the `bands` array:

```json
{
"assets": {
"example": {
"href": "example.tif",
"bands": [
{
"data_type": "uint16",
"eo:common_name": "red",
"raster:spatial_resolution": 10
}
]
}
}
}
```

Example without bands:

```json
{
"assets": {
"example": {
"href": "example.tif",
"data_type": "uint16",
"eo:common_name": "red",
"raster:spatial_resolution": 10
}
}
}
```

STAC recommands that single band assets should only use the `bands` array in the following cases:

1. **It's important in to convey that a band is present in the asset.**
- This is the case if the data access mechanism requires you to specify the name of index of the band to retrieve the data,
then the band should be specified as such.
- This is also the case if the band has a specific name.
The `name` property is only available in bands and as such can't be specified for the Asset.
2. **It is important that the (often spectral) band is part of a set of bands.**
- For example, if the `bands` array is exposed in the Collection Summaries,
there should be bands defined in the Items or Item Assets as otherwise there's nothing to summarize.
3. **Individual bands are repeated in different assets.**
- This may happen if you provide assets with different resolutions or file formats.
The `name` property with the same value should be used so that users can identify that the bands are the same.
It also enables clients to easily combine and summarize the bands.

#### Multiple bands

Generally, all properties that have the same value across all bands should not be listed in bands but in assets directly.

For example, if your bands in an asset is defined as follows:

```json
{
"assets": {
"example": {
"href": "example.tif",
"bands": [
{
"name": "r",
"eo:common_name": "red",
"data_type": "uint16",
"raster:spatial_resolution": 10
},
{
"name": "g",
"eo:common_name": "green",
"data_type": "uint16",
"raster:spatial_resolution": 10
},
{
"name": "b",
"eo:common_name": "blue",
"data_type": "uint16",
"raster:spatial_resolution": 10
}
]
}
}
}
```

The `data_type` and `raster:spatial_resolution` has the same value for all bands.
As such you can deduplicate those properties and list them in the asset directly:

```json
{
"assets": {
"example": {
"href": "example.tif",
"data_type": "uint16",
"raster:spatial_resolution": 10,
"bands": [
{
"name": "r",
"eo:common_name": "red"
},
{
"name": "g",
"eo:common_name": "green"
},
{
"name": "b",
"eo:common_name": "blue"
}
]
}
}
}
```

#### Band migration

It should be relatively simple to migrate from STAC 1.0 (i.e. `eo:bands` and/or `raster:bands`) to the new `bands` array.

Usually, you can simply merge the each object on a by-index basis.
Nevertheless, you should consider deduplicating properties with the same values across all bands to the Asset.
For some fields you need to add the extension prefix of the `eo` or `raster` extension to the property name.

STAC 1.0 example:

```json
{
"assets": {
"example": {
"href": "example.tif",
"eo:bands": [
{
"name": "r",
"common_name": "red"
},
{
"name": "g",
"common_name": "green"
},
{
"name": "b",
"common_name": "blue"
},
{
"name": "nir",
"common_name": "nir"
}
],
"raster:bands": [
{
"data_type": "uint16",
"spatial_resolution": 10,
"sampling": "area"
},
{
"data_type": "uint16",
"spatial_resolution": 10,
"sampling": "area"
},
{
"data_type": "uint16",
"spatial_resolution": 10,
"sampling": "area"
},
{
"data_type": "uint16",
"spatial_resolution": 30,
"sampling": "area"
}
]
}
}
}
```

After migrating to STAC 1.1 this is ideally provided as follows:

```json
{
"assets": {
"example": {
"href": "example.tif",
"data_type": "uint16",
"raster:sampling": "area",
"raster:spatial_resolution": 10,
"bands": [
{
"name": "r",
"eo:common_name": "red",
},
{
"name": "g",
"eo:common_name": "green"
},
{
"name": "b",
"eo:common_name": "blue"
},
{
"name": "nir",
"eo:common_name": "nir",
"raster:spatial_resolution": 30
}
]
}
}
}
```

The following was done:

- The arrays have been merged into a single property `bands`.
- The properties `common_name` and `spatial_resolution` were renamed to include the extension prefixes.
- The properties `data_type` and `raster:sampling` (renamed from `sampling`) were deduplicated to the Asset
as the values were the same across all bands.
- The `spatial_resolution` was also deduplicated, i.e. `10` is provided on the asset level,
which is inherited by the bands unless explicitly overridden.
Therefore, the `nir` band overrides the value `10` with a value of `30`.

As a result, the new `bands` array is more lightweight and easier to handle.

## Catalog & Collection Practices

*Note: This section uses the term 'Catalog' (with an uppercase C) to refer to the JSON entity specified in the
Expand Down Expand Up @@ -577,11 +801,11 @@ in the array are meaningless, as each Item is describing its transform, so combi
So if the values contained in the array are independently meaningful (not interconnected) and there aren't hundreds of potential
values then it is likely a good candidate to summarize.

We do highly recommend including an [`eo:bands`](https://github.com/stac-extensions/eo/blob/main/README.md#eobands)
summary if your Items implement `eo:bands`,
We do highly recommend including a [`bands`](./item-spec/common-metadata.md#bands)
summary if your Items implement `bands`,
especially if it represents just one satellite or constellation. This should be a union of all the potential bands that you
have in assets. It is ok to only add the summary at the Collection level without putting an explicit `eo:bands` summary at the
`properties` level of an Item, since that is optional. This gives users of the Collection a sense of the sensor capabilities without
have in assets. It is ok to only add the summary at the Collection level without putting `bands` at the
`properties` level of an Item. This gives users of the Collection a sense of the sensor capabilities without
having to examine specific Items or aggregate across every Item.

Note that the ranges of summaries don't have to be exact. If you are publishing a catalog that is constantly updating with
Expand Down
Loading