|
| 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 | +} |
0 commit comments