Skip to content

Commit aca208f

Browse files
STAC well known types for Assets, Links, Storage, Authentication and Providers (#62)
* STAC well known types for Assets, Links, Storage, Authentication and Providers * Document three-valued boolean logic for query expressions
1 parent 8fea7f9 commit aca208f

10 files changed

Lines changed: 922 additions & 5 deletions

File tree

‎apis/datasets/stac/v1/asset.proto‎

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
// This file models STAC 1.1 Asset and Band Objects using Tilebox's compact shared-profile representation. Access and band
2+
// profile tables deduplicate repeated metadata without changing the reconstructed STAC semantics.
3+
//
4+
// https://github.com/radiantearth/stac-spec/blob/v1.1.0/item-spec/item-spec.md#asset-object
5+
6+
edition = "2023";
7+
package datasets.stac.v1;
8+
9+
import "buf/validate/validate.proto";
10+
import "datasets/stac/v1/asset_metadata.proto";
11+
import "datasets/stac/v1/core.proto";
12+
import "datasets/stac/v1/product.proto";
13+
import "datasets/stac/v1/sar.proto";
14+
import "datasets/stac/v1/satellite.proto";
15+
16+
option features.field_presence = IMPLICIT;
17+
18+
// KnownAssetRole contains the STAC 1.1, EO 2.0, and SAR 1.3.2 recommended asset roles. STAC asset roles are open;
19+
// values not listed here are stored in Asset.custom_roles.
20+
enum KnownAssetRole {
21+
KNOWN_ASSET_ROLE_UNSPECIFIED = 0;
22+
23+
// STAC 1.1 recommended asset roles occupy values 1-99.
24+
// https://github.com/radiantearth/stac-spec/blob/v1.1.0/best-practices.md#list-of-asset-roles
25+
KNOWN_ASSET_ROLE_DATA = 1;
26+
KNOWN_ASSET_ROLE_METADATA = 2;
27+
KNOWN_ASSET_ROLE_THUMBNAIL = 3;
28+
KNOWN_ASSET_ROLE_OVERVIEW = 4;
29+
KNOWN_ASSET_ROLE_VISUAL = 5;
30+
KNOWN_ASSET_ROLE_DATE = 6;
31+
KNOWN_ASSET_ROLE_GRAPHIC = 7;
32+
KNOWN_ASSET_ROLE_DATA_MASK = 8;
33+
KNOWN_ASSET_ROLE_SNOW_ICE = 9;
34+
KNOWN_ASSET_ROLE_LAND_WATER = 10;
35+
KNOWN_ASSET_ROLE_WATER_MASK = 11;
36+
KNOWN_ASSET_ROLE_ISO_19115 = 12;
37+
38+
// EO 2.0 best-practice asset roles occupy values 100-199.
39+
// https://github.com/stac-extensions/eo/blob/v2.0.0/README.md#best-practices
40+
KNOWN_ASSET_ROLE_REFLECTANCE = 100;
41+
KNOWN_ASSET_ROLE_TEMPERATURE = 101;
42+
KNOWN_ASSET_ROLE_SATURATION = 102;
43+
KNOWN_ASSET_ROLE_CLOUD = 103;
44+
KNOWN_ASSET_ROLE_CLOUD_SHADOW = 104;
45+
46+
// SAR 1.3.2 best-practice asset roles occupy values 200-299.
47+
// https://github.com/stac-extensions/sar/blob/v1.3.2/README.md#best-practices
48+
KNOWN_ASSET_ROLE_LOCAL_INCIDENCE_ANGLE = 200;
49+
KNOWN_ASSET_ROLE_ELLIPSOID_INCIDENCE_ANGLE = 201;
50+
KNOWN_ASSET_ROLE_NOISE_POWER = 202;
51+
KNOWN_ASSET_ROLE_AMPLITUDE = 203;
52+
KNOWN_ASSET_ROLE_MAGNITUDE = 204;
53+
KNOWN_ASSET_ROLE_SIGMA0 = 205;
54+
KNOWN_ASSET_ROLE_BETA0 = 206;
55+
KNOWN_ASSET_ROLE_GAMMA0 = 207;
56+
KNOWN_ASSET_ROLE_DATE_OFFSET = 208;
57+
KNOWN_ASSET_ROLE_COVMAT = 209;
58+
KNOWN_ASSET_ROLE_PRD = 210;
59+
}
60+
61+
// DataType contains the complete closed STAC 1.1 data_type vocabulary.
62+
enum DataType {
63+
DATA_TYPE_UNSPECIFIED = 0;
64+
DATA_TYPE_INT8 = 1;
65+
DATA_TYPE_INT16 = 2;
66+
DATA_TYPE_INT32 = 3;
67+
DATA_TYPE_INT64 = 4;
68+
DATA_TYPE_UINT8 = 5;
69+
DATA_TYPE_UINT16 = 6;
70+
DATA_TYPE_UINT32 = 7;
71+
DATA_TYPE_UINT64 = 8;
72+
DATA_TYPE_FLOAT16 = 9;
73+
DATA_TYPE_FLOAT32 = 10;
74+
DATA_TYPE_FLOAT64 = 11;
75+
DATA_TYPE_CINT16 = 12;
76+
DATA_TYPE_CINT32 = 13;
77+
DATA_TYPE_CFLOAT32 = 14;
78+
DATA_TYPE_CFLOAT64 = 15;
79+
DATA_TYPE_OTHER = 16;
80+
}
81+
82+
// Statistics contains the statistics fields used by the supported Items.
83+
message Statistics {
84+
double minimum = 1 [features.field_presence = EXPLICIT];
85+
double maximum = 2 [features.field_presence = EXPLICIT];
86+
}
87+
88+
// AssetAccessProfile deduplicates access metadata shared by asset locations in one STAC Item.
89+
message AssetAccessProfile {
90+
// Alternate Assets map key, such as `s3` or `https`, when used for an alternate location.
91+
string alternate_key = 1;
92+
// Default alternate:name for locations using this profile.
93+
string default_alternate_name = 2 [features.field_presence = EXPLICIT];
94+
// Item-specific common URI prefix used to compress hrefs. A location's full href is the byte concatenation of
95+
// base_href and its href suffix; URI reference resolution and path normalization are not applied.
96+
string base_href = 3;
97+
// Keys into the item-level Storage.schemes registry.
98+
repeated string storage_refs = 4;
99+
// Keys into the item-level Authentication.schemes registry.
100+
repeated string auth_refs = 5;
101+
}
102+
103+
// AssetLocation selects an access profile and supplies a relative or absolute href.
104+
message AssetLocation {
105+
// Required index into Assets.access_profiles. Zero is a valid index.
106+
uint32 access_profile_index = 1 [
107+
features.field_presence = EXPLICIT,
108+
(buf.validate.field).required = true
109+
];
110+
// Href suffix for the selected profile. This must be present on primary locations. When absent on an alternate,
111+
// it reuses the primary location's href suffix verbatim before applying the alternate profile's base_href.
112+
// A present empty string represents the selected profile's base_href exactly.
113+
string href = 2 [features.field_presence = EXPLICIT];
114+
// Per-location override for the access profile's default alternate:name.
115+
string alternate_name = 3 [features.field_presence = EXPLICIT];
116+
}
117+
118+
// Band is a reusable STAC 1.1 band profile containing common, EO, Raster, and Classification fields. Fields present
119+
// here override the corresponding inheritable Asset fields; ingestion should omit values lifted to the Asset.
120+
message Band {
121+
string name = 1 [
122+
features.field_presence = EXPLICIT,
123+
(buf.validate.field).string.min_len = 1
124+
];
125+
string description = 2 [features.field_presence = EXPLICIT];
126+
DataType data_type = 3 [(buf.validate.field).enum.defined_only = true];
127+
double nodata = 4 [features.field_presence = EXPLICIT];
128+
string unit = 5 [features.field_presence = EXPLICIT];
129+
EOProperties eo = 6;
130+
RasterProperties raster = 7;
131+
repeated ClassificationClass classes = 8;
132+
// SAR 1.3.2 permits frequency, center-frequency, and bandwidth metadata on Band Objects.
133+
SARProperties sar = 9;
134+
}
135+
136+
// Asset contains the canonical STAC 1.1 Asset Object fields used by the supported Items. Inheritable metadata applies
137+
// to every band unless a Band overrides it. Ingestion should lift values shared by all bands to this level.
138+
message Asset {
139+
option (buf.validate.message).cel = {
140+
id: "asset.primary_href"
141+
message: "the primary asset location must provide an href"
142+
expression: "has(this.primary.href)"
143+
};
144+
145+
// Key from the STAC assets object.
146+
string key = 1 [(buf.validate.field).string.min_len = 1];
147+
AssetLocation primary = 2 [(buf.validate.field).required = true];
148+
repeated AssetLocation alternates = 3;
149+
MediaType media_type = 4;
150+
string title = 5 [features.field_presence = EXPLICIT];
151+
string description = 6 [features.field_presence = EXPLICIT];
152+
// STAC role order is not semantically meaningful. Known roles are stored compactly; all other values remain strings.
153+
repeated KnownAssetRole roles = 7 [(buf.validate.field).repeated.items.enum = {
154+
defined_only: true
155+
not_in: [0]
156+
}];
157+
repeated string custom_roles = 8 [(buf.validate.field).repeated.items.string.min_len = 1];
158+
double gsd = 9 [features.field_presence = EXPLICIT];
159+
// Ordered indices into Assets.band_profiles. References deliberately have no per-use overrides: metadata differences
160+
// require distinct profiles, which keeps reconstruction to direct lookup plus normal STAC Asset-to-Band inheritance.
161+
repeated uint32 band_profile_indices = 10;
162+
DataType data_type = 11 [(buf.validate.field).enum.defined_only = true];
163+
double nodata = 12 [features.field_presence = EXPLICIT];
164+
Statistics statistics = 13;
165+
string unit = 14 [features.field_presence = EXPLICIT];
166+
EOProperties eo = 15;
167+
RasterProperties raster = 16;
168+
Projection projection = 17;
169+
View view = 18;
170+
repeated ClassificationClass classes = 19;
171+
File file = 20;
172+
SARProperties sar = 21;
173+
SatelliteProperties satellite = 22;
174+
ProductProperties product = 23;
175+
}
176+
177+
// Assets contains the shared profile tables and assets of one STAC Item. Asset locations reference access_profiles by
178+
// index, and assets reference band_profiles by ordered indices. Both tables deduplicate repeated metadata; every index
179+
// must reference an existing profile. Band references intentionally cannot override profiles: use a distinct profile
180+
// for every unique Band. Use one access profile with an empty base_href and refs for uncompressed absolute hrefs.
181+
// Empty repeated fields are intentionally canonicalized: protobuf does not distinguish an absent JSON array from [].
182+
message Assets {
183+
repeated AssetAccessProfile access_profiles = 1;
184+
repeated Band band_profiles = 2;
185+
repeated Asset assets = 3;
186+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// This file models the common STAC extensions used to describe imagery assets, bands, pixel values, spatial grids,
2+
// viewing geometry, and files in Tilebox datasets.
3+
// EO 2.0: https://github.com/stac-extensions/eo/blob/v2.0.0/README.md
4+
// Raster 2.0: https://github.com/stac-extensions/raster/blob/v2.0.0/README.md
5+
// Classification 2.0: https://github.com/stac-extensions/classification/blob/v2.0.0/README.md
6+
// Projection 2.0: https://github.com/stac-extensions/projection/blob/v2.0.0/README.md
7+
// View 1.1: https://github.com/stac-extensions/view/blob/v1.1.0/README.md
8+
// File 2.1: https://github.com/stac-extensions/file/blob/v2.1.0/README.md
9+
10+
edition = "2023";
11+
package datasets.stac.v1;
12+
13+
import "buf/validate/validate.proto";
14+
15+
option features.field_presence = IMPLICIT;
16+
17+
// EOCommonName is the closed EO 2.0 common-name vocabulary.
18+
enum EOCommonName {
19+
EO_COMMON_NAME_UNSPECIFIED = 0;
20+
EO_COMMON_NAME_PAN = 1;
21+
EO_COMMON_NAME_COASTAL = 2;
22+
EO_COMMON_NAME_BLUE = 3;
23+
EO_COMMON_NAME_GREEN = 4;
24+
EO_COMMON_NAME_GREEN05 = 5;
25+
EO_COMMON_NAME_YELLOW = 6;
26+
EO_COMMON_NAME_RED = 7;
27+
EO_COMMON_NAME_REDEDGE = 8;
28+
EO_COMMON_NAME_REDEDGE071 = 9;
29+
EO_COMMON_NAME_REDEDGE075 = 10;
30+
EO_COMMON_NAME_REDEDGE078 = 11;
31+
EO_COMMON_NAME_NIR = 12;
32+
EO_COMMON_NAME_NIR08 = 13;
33+
EO_COMMON_NAME_NIR09 = 14;
34+
EO_COMMON_NAME_CIRRUS = 15;
35+
EO_COMMON_NAME_SWIR16 = 16;
36+
EO_COMMON_NAME_SWIR22 = 17;
37+
EO_COMMON_NAME_LWIR = 18;
38+
EO_COMMON_NAME_LWIR11 = 19;
39+
EO_COMMON_NAME_LWIR12 = 20;
40+
}
41+
42+
// EOProperties contains the EO 2.0 fields that are useful at asset or band level.
43+
// eo:cloud_cover and eo:snow_cover are intentionally omitted: they are typically Item properties and should become
44+
// dedicated top-level Tilebox dataset fields instead of being embedded in Assets.
45+
message EOProperties {
46+
EOCommonName common_name = 1 [(buf.validate.field).enum.defined_only = true];
47+
// Spectral values are expressed in micrometres.
48+
double center_wavelength = 2 [features.field_presence = EXPLICIT];
49+
double full_width_half_max = 3 [features.field_presence = EXPLICIT];
50+
double solar_illumination = 4 [features.field_presence = EXPLICIT];
51+
}
52+
53+
// RasterSampling contains the closed Raster 2.0 raster:sampling vocabulary.
54+
enum RasterSampling {
55+
RASTER_SAMPLING_UNSPECIFIED = 0;
56+
RASTER_SAMPLING_AREA = 1;
57+
RASTER_SAMPLING_POINT = 2;
58+
}
59+
60+
// RasterProperties contains the Raster 2.0 fields used by the supported Items.
61+
message RasterProperties {
62+
RasterSampling sampling = 1 [(buf.validate.field).enum.defined_only = true];
63+
double scale = 2 [features.field_presence = EXPLICIT];
64+
double offset = 3 [features.field_presence = EXPLICIT];
65+
// Spatial resolution is expressed in metres.
66+
double spatial_resolution = 4 [features.field_presence = EXPLICIT];
67+
}
68+
69+
// ClassificationClass contains all Classification 2.0 class fields. Bit-field definitions are intentionally deferred.
70+
message ClassificationClass {
71+
int64 value = 1 [
72+
features.field_presence = EXPLICIT,
73+
(buf.validate.field).required = true
74+
];
75+
string description = 2 [features.field_presence = EXPLICIT];
76+
string name = 3 [
77+
features.field_presence = EXPLICIT,
78+
(buf.validate.field).required = true,
79+
(buf.validate.field).string.pattern = "^[0-9A-Za-z-_]+$"
80+
];
81+
string title = 4 [features.field_presence = EXPLICIT];
82+
string color_hint = 5 [
83+
features.field_presence = EXPLICIT,
84+
(buf.validate.field).string.pattern = "^[0-9A-Fa-f]{6}$"
85+
];
86+
bool nodata = 6 [features.field_presence = EXPLICIT];
87+
double percentage = 7 [
88+
features.field_presence = EXPLICIT,
89+
(buf.validate.field).double = {
90+
gte: 0
91+
lte: 100
92+
}
93+
];
94+
uint64 count = 8 [features.field_presence = EXPLICIT];
95+
}
96+
97+
// Projection contains the Projection 2.0 fields used by the supported Items.
98+
message Projection {
99+
// Explicit presence distinguishes a missing code from a value. A STAC JSON null is treated as missing.
100+
string code = 1 [
101+
features.field_presence = EXPLICIT,
102+
(buf.validate.field).string.min_len = 1
103+
];
104+
// Four values describe a 2D bbox and six values describe a 3D bbox.
105+
repeated double bbox = 2;
106+
// Exactly two integers in Y, X order.
107+
repeated int64 shape = 3;
108+
// Six values describe a 2D affine transform and nine values describe a 3D transform.
109+
repeated double transform = 4;
110+
}
111+
112+
// View contains the View 1.1 fields used by the supported Items.
113+
message View {
114+
double incidence_angle = 1 [features.field_presence = EXPLICIT];
115+
double azimuth = 2 [features.field_presence = EXPLICIT];
116+
}
117+
118+
// File contains the File 2.1 fields used by the supported Items.
119+
message File {
120+
// Decoded binary multihash. STAC JSON represents this as lowercase hexadecimal.
121+
bytes checksum = 1 [features.field_presence = EXPLICIT];
122+
uint64 size = 2 [features.field_presence = EXPLICIT];
123+
string local_path = 3 [features.field_presence = EXPLICIT];
124+
}

0 commit comments

Comments
 (0)