Skip to content

Commit 14da94d

Browse files
Merge pull request #854 from radiantearth/null-geometry-clarification
Null geometry clarification
2 parents a4f60e2 + 760e743 commit 14da94d

File tree

4 files changed

+89
-19
lines changed

4 files changed

+89
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1010
- JSON-schema file in the Point Cloud extension.
1111

1212
### Changes
13+
- Clarification on null geometries, making bbox not required if a null geometry is used.
1314
- Multiple extents (bounding boxes / intervals) are allowed per Collection
1415

1516
### Removed

best-practices.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* [Field and ID formatting](#field-and-id-formatting)
66
* [Field selection and Metadata Linking](#field-selection-and-metadata-linking)
77
* [Datetime selection](#datetime-selection)
8+
* [Unlocated Items](#unlocated-items)
89
* [Representing Vector Layers in STAC](#representing-vector-layers-in-stac)
910
* [Common Use Cases of Additional Fields for Assets](#common-use-cases-of-additional-fields-for-assets)
1011
* [Static and Dynamic Catalogs](#static-and-dynamic-catalogs)
@@ -69,6 +70,45 @@ might choose to have `datetime` be the start. The key is to put in a date and ti
6970
the focus of STAC. If `datetime` is set to `null` then it is strongly recommended to use it in conjunction with a content extension
7071
that explains why it should not be set for that type of data.
7172

73+
## Unlocated Items
74+
75+
Though the [GeoJSON standard](https://tools.ietf.org/html/rfc7946) allows null geometries, in STAC we strongly recommend
76+
that every item have a geometry, since the general expectation of someone using a SpatioTemporal Catalog is to be able to query
77+
all data by space and time. But there are some use cases where it can make sense to create a STAC Item before it gets
78+
a geometry. The most common of these is 'level 1' satellite data, where an image is downlinked and cataloged before it has
79+
been geospatially located.
80+
81+
The recommendation for data that does not yet have a location is to follow the GeoJSON concept that it is an ['unlocated'
82+
feature](https://tools.ietf.org/html/rfc7946#section-3.2). So if the catalog has data that is not located then it can follow
83+
GeoJSON and set the geometry to null. Though normally required, in this case the `bbox` field should not be included.
84+
85+
Note that this recommendation is only for cases where data does not yet have a geometry and it cannot be estimated. There
86+
are further details on the two most commonly requested desired use cases for setting geometry to null:
87+
88+
### Unrectified Satellite Data
89+
90+
Most satellite data is downlinked without information that precisely describes where it is located on earth. A satellite
91+
imagery processing pipeline will always attempt to locate it, but often that process takes a number of hours, or never
92+
quite completes (like when it is too cloudy). It can be useful to start to populate the Item before it has a geometry.
93+
In this case the recommendation is to use the 'estimated' position from the satellite, to populate at least the bounding box,
94+
and use the same broad bounds for the geometry (or leaving it null) until there is precise ground lock. This estimation is
95+
usually done by onboard equipment, like GPS or star trackers, but can be off by kilometers or more. But it is very useful for
96+
STAC users to be able to at least find approximate area in their searches. A commonly used field for communicating ground lock
97+
is not yet established, but likely should be (an extension proposal would be appreciated). If there is no way to provide an
98+
estimate then the data then a null geometry with no `bbox` can be used, as described above. But the data will likely not
99+
show up in STAC API searches, as most will at least implicitly use a geometry. Though this section is written with
100+
satellite data in mind, one can easily imagine other data types that start with a less precise geometry but have it
101+
refined after processing.
102+
103+
### Data that is not spatial
104+
105+
The other case that often comes up is people who love STAC and want to use it to catalog everything they have, even if it is
106+
not spatial. This use case is not currently supported by STAC, as we are focused on data that is both temporal and spatial
107+
in nature. The [OGC API - Records](https://github.com/opengeospatial/ogcapi-records) is an emerging standard that likely
108+
will be able to handle a wider range of data to catalog than STAC. It builds on [OGC API -
109+
Features](https://github.com/opengeospatial/ogcapi-features) just like [STAC API](https://github.com/radiantearth/stac-api-spec/)
110+
does. The [collection assets extension](extensions/collection-assets) may also provide an option for some use cases.
111+
72112
## Representing Vector Layers in STAC
73113

74114
Many implementors are tempted to try to use STAC for 'everything', using it as a universal catalog of all their 'stuff'.

item-spec/item-spec.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ inherited from GeoJSON.
3333
| stac_extensions | \[string] | A list of extensions the Item implements. |
3434
| id | string | **REQUIRED.** Provider identifier. As most geospatial assets are already defined by some identification scheme by the data provider it is recommended to simply use that ID. Data providers are advised to include sufficient information to make their IDs globally unique, including things like unique satellite IDs. |
3535
| type | string | **REQUIRED.** Type of the GeoJSON Object. MUST be set to `Feature`. |
36-
| geometry | [GeoJSON Geometry Object](https://tools.ietf.org/html/rfc7946#section-3.1) | **REQUIRED.** Defines the full footprint of the asset represented by this item, formatted according to [RFC 7946, section 3.1](https://tools.ietf.org/html/rfc7946#section-3.1). The footprint should be the default GeoJSON geometry, though additional geometries can be included. Coordinates are specified in Longitude/Latitude or Longitude/Latitude/Elevation based on [WGS 84](http://www.opengis.net/def/crs/OGC/1.3/CRS84). |
37-
| bbox | \[number] | **REQUIRED.** Bounding Box of the asset represented by this item, formatted according to [RFC 7946, section 5](https://tools.ietf.org/html/rfc7946#section-5). |
36+
| geometry | [GeoJSON Geometry Object](https://tools.ietf.org/html/rfc7946#section-3.1) \| [null](https://tools.ietf.org/html/rfc7946#section-3.2) | **REQUIRED.** Defines the full footprint of the asset represented by this item, formatted according to [RFC 7946, section 3.1](https://tools.ietf.org/html/rfc7946#section-3.1). The footprint should be the default GeoJSON geometry, though additional geometries can be included. Coordinates are specified in Longitude/Latitude or Longitude/Latitude/Elevation based on [WGS 84](http://www.opengis.net/def/crs/OGC/1.3/CRS84). |
37+
| bbox | \[number] | **REQUIRED if `geometry` is not `null`.** Bounding Box of the asset represented by this item, formatted according to [RFC 7946, section 5](https://tools.ietf.org/html/rfc7946#section-5). |
3838
| properties | [Properties Object](#properties-object) | **REQUIRED.** A dictionary of additional metadata for the item. |
3939
| links | \[[Link Object](#link-object)] | **REQUIRED.** List of link objects to resources and related URLs. A link with the `rel` set to `self` is strongly recommended. |
4040
| assets | Map<string, [Asset Object](#asset-object)> | **REQUIRED.** Dictionary of asset objects that can be downloaded, each with a unique key. |

item-spec/json-schema/item.json

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,59 @@
3434
{
3535
"$ref": "https://geojson.org/schema/Feature.json"
3636
},
37+
{
38+
"oneOf": [
39+
{
40+
"type": "object",
41+
"required": [
42+
"geometry",
43+
"bbox"
44+
],
45+
"properties": {
46+
"geometry": {
47+
"$ref": "https://geojson.org/schema/Geometry.json"
48+
},
49+
"bbox": {
50+
"type": "array",
51+
"oneOf": [
52+
{
53+
"minItems": 4,
54+
"maxItems": 4
55+
},
56+
{
57+
"minItems": 6,
58+
"maxItems": 6
59+
}
60+
],
61+
"items": {
62+
"type": "number"
63+
}
64+
}
65+
}
66+
},
67+
{
68+
"type": "object",
69+
"required": [
70+
"geometry"
71+
],
72+
"properties": {
73+
"geometry": {
74+
"type": "null"
75+
},
76+
"bbox": {
77+
"not": {}
78+
}
79+
}
80+
}
81+
]
82+
},
3783
{
3884
"type": "object",
3985
"required": [
4086
"stac_version",
4187
"id",
4288
"links",
4389
"assets",
44-
"bbox",
4590
"properties"
4691
],
4792
"properties": {
@@ -73,22 +118,6 @@
73118
"description": "Provider item ID",
74119
"type": "string"
75120
},
76-
"bbox": {
77-
"type": "array",
78-
"oneOf": [
79-
{
80-
"minItems": 4,
81-
"maxItems": 4
82-
},
83-
{
84-
"minItems": 6,
85-
"maxItems": 6
86-
}
87-
],
88-
"items": {
89-
"type": "number"
90-
}
91-
},
92121
"links": {
93122
"title": "Item links",
94123
"description": "Links to item relations",

0 commit comments

Comments
 (0)