|
15 | 15 | "safe": "http://www.esa.int/safe/sentinel-1.0", |
16 | 16 | "s1": "http://www.esa.int/safe/sentinel-1.0/sentinel-1", |
17 | 17 | "s1sarl1": "http://www.esa.int/safe/sentinel-1.0/sentinel-1/sar/level-1", |
| 18 | + "gml": "http://www.opengis.net/gml", |
18 | 19 | } |
19 | 20 |
|
20 | 21 | SENTINEL1_FOLDER = importlib.resources.files("xarray_sentinel") / "resources/sentinel1" |
@@ -176,6 +177,98 @@ def parse_manifest_sentinel1( |
176 | 177 | return attributes, files |
177 | 178 |
|
178 | 179 |
|
| 180 | +def make_sentinel1_stac_item( |
| 181 | + item_id: str, |
| 182 | + manifest_path: PathOrFileType, |
| 183 | + annotation: PathOrFileType, |
| 184 | + namespaces=SENTINEL1_NAMESPACES, |
| 185 | +) -> dict[str, Any]: |
| 186 | + manifest = ElementTree.parse(manifest_path).getroot() |
| 187 | + |
| 188 | + product_information = parse_tag(annotation, ".//productInformation") |
| 189 | + image_information = parse_tag(annotation, ".//imageInformation") |
| 190 | + |
| 191 | + coordinates = [ |
| 192 | + [float(v) for v in token.split(",")] |
| 193 | + for token in findtext(manifest, ".//gml:coordinates").split() |
| 194 | + ] |
| 195 | + coordinates += coordinates[:1] |
| 196 | + product_timeliness = findtext(manifest, ".//s1sarl1:productTimelinessCategory") |
| 197 | + product_timeliness_map = { |
| 198 | + "Fast-24h": { |
| 199 | + "product:timeliness_category": "STC", |
| 200 | + "product:timeliness": "PT24H", |
| 201 | + } |
| 202 | + } |
| 203 | + |
| 204 | + stac_item = { |
| 205 | + "type": "Feature", |
| 206 | + "stac_version": "1.1.0", |
| 207 | + "stac_extensions": [ |
| 208 | + "https://stac-extensions.github.io/product/v0.1.0/schema.json", |
| 209 | + "https://stac-extensions.github.io/processing/v1.2.0/schema.json", |
| 210 | + "https://stac-extensions.github.io/sat/v1.0.0/schema.json", |
| 211 | + "https://stac-extensions.github.io/view/v1.0.0/schema.json", |
| 212 | + "https://stac-extensions.github.io/sar/v1.2.0/schema.json", |
| 213 | + "https://stac-extensions.github.io/eopf/v1.0.0/schema.json", |
| 214 | + ], |
| 215 | + "id": item_id, |
| 216 | + "properties": { |
| 217 | + "datetime": None, |
| 218 | + "start_datetime": findtext(manifest, ".//safe:startTime") + "Z", |
| 219 | + "end_datetime": findtext(manifest, ".//safe:stopTime") + "Z", |
| 220 | + "created": manifest.find( |
| 221 | + ".//safe:processing", namespaces=namespaces |
| 222 | + ).attrib["stop"] |
| 223 | + + "Z", |
| 224 | + "platform": "sentinel-1" |
| 225 | + + findtext(manifest, ".//safe:platform/safe:number").lower(), |
| 226 | + "instruments": ["sar"], |
| 227 | + "constellation": "sentinel-1", |
| 228 | + "product:type": "S01SSMSLC", |
| 229 | + "product:timeliness_category": product_timeliness_map[product_timeliness][ |
| 230 | + "product:timeliness_category" |
| 231 | + ], |
| 232 | + "product:timeliness": product_timeliness_map[product_timeliness][ |
| 233 | + "product:timeliness" |
| 234 | + ], |
| 235 | + "processing:software": manifest.find( |
| 236 | + ".//safe:software", namespaces=namespaces |
| 237 | + ).attrib, |
| 238 | + "sat:platform_international_designator": findtext( |
| 239 | + manifest, ".//safe:nssdcIdentifier" |
| 240 | + ), |
| 241 | + "sat:absolute_orbit": int(findall(manifest, ".//safe:orbitNumber")[0]), |
| 242 | + "sat:relative_orbit": int( |
| 243 | + findall(manifest, ".//safe:relativeOrbitNumber")[0] |
| 244 | + ), |
| 245 | + "sat:orbit_state": findtext(manifest, ".//s1:pass").lower(), |
| 246 | + "sat:anx_datetime": findtext(manifest, ".//s1:ascendingNodeTime") + "Z", |
| 247 | + "view:incidence_angle": image_information["incidenceAngleMidSwath"], |
| 248 | + "sar:polarizations": findall( |
| 249 | + manifest, ".//s1sarl1:transmitterReceiverPolarisation" |
| 250 | + ), |
| 251 | + "sar:instrument_mode": findtext( |
| 252 | + manifest, ".//s1sarl1:instrumentMode/s1sarl1:mode" |
| 253 | + ), |
| 254 | + "sar:frequency_band": "C", |
| 255 | + "sar:center_frequency": product_information["radarFrequency"] / 1e9, |
| 256 | + "sar:pixel_spacing_range": image_information["rangePixelSpacing"], |
| 257 | + "sar:pixel_spacing_azimuth": image_information["azimuthPixelSpacing"], |
| 258 | + "sar:observation_direction": "right", |
| 259 | + "sar:beam_ids": findall( |
| 260 | + manifest, ".//s1sarl1:instrumentMode/s1sarl1:swath" |
| 261 | + ), |
| 262 | + "eopf:datatake_id": int(findtext(manifest, ".//s1sarl1:missionDataTakeID")), |
| 263 | + }, |
| 264 | + "geometry": {"type": "Polygon", "coordinates": [coordinates]}, |
| 265 | + "links": [], |
| 266 | + "assets": {}, |
| 267 | + } |
| 268 | + return stac_item |
| 269 | + |
| 270 | + |
| 271 | +# DEPRECATED |
179 | 272 | def make_stac_item(attrs: Mapping[str, Any]) -> dict[str, Any]: |
180 | 273 | assert attrs["family_name"] == "SENTINEL-1" |
181 | 274 |
|
|
0 commit comments