CDSE OData → STAC crosswalk
This reference describes pygeocdse.converters.odata2stac. See how to convert responses for usage. Products without footprints are skipped; retained products require a beginningDateTime attribute. Polygon and MultiPolygon footprints are supported. Unmapped attributes are logged and omitted, and OData pagination links are not copied.
Attribute fields
| attribute | STAC (core / extension) | STAC field / property | Transformation applied |
|---|---|---|---|
beginningDateTime (attribute) |
STAC Core | datetime |
Parsed RFC3339 timestamp via _parse_rfc3339, assigned to Item.datetime. |
GeoFootprint (product top-level field) |
STAC Core | geometry |
GeoJSON geometry copied as-is to Item.geometry. |
GeoFootprint (product top-level field) |
STAC Core | bbox |
Bounding box computed from GeoJSON geometry (Polygon / MultiPolygon) using _bbox_from_geojson_geometry. |
Id (product top-level field) |
STAC Core | id |
Converted to string and assigned to Item.id. |
Name (product top-level field) |
STAC Link | links[].rel=derived_from |
Creates a derived-from link pointing to the OData query filtering by Name and expanding Assets/Attributes. |
beginningDateTime |
STAC Core | properties["start_datetime"] |
Parsed RFC3339 and written as ISO8601 string (.isoformat()). |
endingDateTime |
STAC Core | properties["end_datetime"] |
Parsed RFC3339 and written as ISO8601 string (.isoformat()). |
orbitNumber |
sat | sat:absolute_orbit |
Ensures Sat extension then sets item.ext.sat.absolute_orbit = value. |
relativeOrbitNumber |
sat | sat:relative_orbit |
Ensures Sat extension then sets item.ext.sat.relative_orbit = value. |
orbitDirection |
sat | sat:orbit_state |
Ensures Sat extension then maps to enum: OrbitState[str(value).upper()]. |
polarisationChannels |
sar | sar:polarizations |
Ensures SAR extension then splits string on & and maps to Polarization[...] enum list. |
productType |
product | product:type |
Ensures Product extension then sets product_ext.product_type = value. |
timeliness |
product | product:timeliness_category + product:timeliness |
Ensures Product extension then applies timeliness_category=value and hardcodes timeliness="N/A". |
processingCenter |
processing | processing:facility |
Ensures Processing extension then sets proc_ext.facility = value. |
processingLevel |
processing | processing:level |
Ensures Processing extension then maps with LEVEL_MAP (e.g. S2MSI1C→L1, LEVEL2→L2, etc.), fallback to original value. |
processingDate |
processing | processing:datetime |
Ensures Processing extension then parses RFC3339 and sets proc_ext.processing_datetime. |
processorName |
processing | processing:software |
Ensures Processing extension then sets proc_ext.software = value. |
processorVersion |
processing | processing:version |
Ensures Processing extension then sets proc_ext.version = value. |
operationalMode |
sar | sar:instrument_mode |
Ensures SAR extension then sets item.ext.sar.instrument_mode = str(value). |
swathIdentifier |
sar | sar:beam_ids |
Ensures SAR extension then splits whitespace string (e.g. "IW1 IW2 IW3") into list; stored as properties["sar:beam_ids"] (PySTAC SAR ext doesn’t expose it). |
platformShortName |
STAC Core | properties["constellation"] |
Lowercases and stores constellation (e.g. "SENTINEL-1"→"sentinel-1"). |
platformShortName + platformSerialIdentifier |
STAC Core | properties["platform"] |
Builds platform by concatenating lowercase platformShortName + lowercase platformSerialIdentifier extracted from product["Attributes"] (e.g. "sentinel-1" + "a" → "sentinel-1a"). |
platformSerialIdentifier |
(handled indirectly) | (none directly) | Explicitly skipped in dispatch (continue) because it’s consumed by on_platform_short_name for platform concatenation. |
instrumentShortName |
STAC Core | properties["instruments"] |
Lowercases and stores list: ["sar"] for "SAR". |
cloudCover |
eo | eo:cloud_cover |
Ensures EO extension then sets item.ext.eo.cloud_cover = float(value) (e.g. "74.0"→74.0). |
Asset-related mapping (non-attribute fields)
These are not from Attributes, but from OData Locations / Checksum:
| OData field | STAC (core / extension) | STAC field | Transformation applied |
|---|---|---|---|
Locations[].DownloadLink |
STAC Core | assets[<FormatType>].href |
Creates one asset per location using href=DownloadLink. |
Locations[].FormatType |
STAC Core | assets[<key>] and asset.title |
Uses FormatType as the asset key and as title. |
Locations[].ContentLength |
file (via extra_fields) | asset.extra_fields["file:size"] |
Stores size as extra field. |
Locations[].Checksum[] |
(custom extra_fields) | asset.extra_fields["checksum:<Algorithm>"] |
For each checksum, creates an extra field key namespaced by algorithm. |
Id (when no Locations) |
STAC Core | assets["Product"] |
Adds ZIP asset: href=https://download.dataspace.copernicus.eu/odata/v1/Products(<Id>)/$value, media_type application/zip, roles ["data","metadata","archive"]. |
S3Path (if present and no Locations) |
STAC Core | assets["data"] |
Adds guessed asset with href=S3Path, media_type from ContentType, extra fields size/checksum. |
Sentinel-1 slice metadata
sliceNumber is mapped through Sentinel1Extension.slice_number to s1:slice_number.