Skip to content

Commit d35745e

Browse files
committed
Add a more complete and modern STAC Item maker
1 parent 8e8ddd9 commit d35745e

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

xarray_sentinel/esa_safe.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"safe": "http://www.esa.int/safe/sentinel-1.0",
1616
"s1": "http://www.esa.int/safe/sentinel-1.0/sentinel-1",
1717
"s1sarl1": "http://www.esa.int/safe/sentinel-1.0/sentinel-1/sar/level-1",
18+
"gml": "http://www.opengis.net/gml",
1819
}
1920

2021
SENTINEL1_FOLDER = importlib.resources.files("xarray_sentinel") / "resources/sentinel1"
@@ -176,6 +177,98 @@ def parse_manifest_sentinel1(
176177
return attributes, files
177178

178179

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
179272
def make_stac_item(attrs: Mapping[str, Any]) -> dict[str, Any]:
180273
assert attrs["family_name"] == "SENTINEL-1"
181274

0 commit comments

Comments
 (0)