diff --git a/pom.xml b/pom.xml
index 74904364..2c2064d7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.openeo
openeo-opensearch-client
- 1.3.1_2.12-SNAPSHOT
+ 1.4.0_2.12-SNAPSHOT
UTF-8
diff --git a/src/main/scala/org/openeo/opensearch/OpenSearchResponses.scala b/src/main/scala/org/openeo/opensearch/OpenSearchResponses.scala
index 2cbd2bad..1b2df770 100644
--- a/src/main/scala/org/openeo/opensearch/OpenSearchResponses.scala
+++ b/src/main/scala/org/openeo/opensearch/OpenSearchResponses.scala
@@ -750,6 +750,16 @@ object OpenSearchResponses {
suffixes.map(s=>Link(URI.create(s"${getGDALPrefix(path)}$path/${prefix}_$s.tif"),Some(s)))
}
+ private def getGlobalMosaicsSentinel1FilePaths(path: String): Seq[Link] = {
+ val bandNames =
+ if (path contains "_IW_") Seq("VH", "VV")
+ else if (path contains "_DH_") Seq("HH", "HV")
+ else throw new IllegalArgumentException(path)
+
+ bandNames
+ .map(bandName => Link(URI.create(s"${getGDALPrefix(path)}$path/$bandName.tif"), title = Some(bandName)))
+ }
+
private def ensureValidGeometry(geometry: Json): Json = {
// TODO: This is required because the old Creodias API can return incorrect MultiPolygon geometries.
// This can be removed once the API is fixed.
@@ -834,6 +844,8 @@ object OpenSearchResponses {
getLandsat8FilePaths(path = f.id).toArray
} else if (f.id.startsWith("/eodata/Sentinel-1-RTC")) {
getSentinel1RTCFilePaths(path = f.id).toArray
+ } else if (f.id.startsWith("/eodata/Global-Mosaics/Sentinel-1")) {
+ getGlobalMosaicsSentinel1FilePaths(path = f.id).toArray
} else {
f.links
}
diff --git a/src/test/resources/org/openeo/creodiasGlobalMosaicsSentinel1.json b/src/test/resources/org/openeo/creodiasGlobalMosaicsSentinel1.json
new file mode 100644
index 00000000..db793e8e
--- /dev/null
+++ b/src/test/resources/org/openeo/creodiasGlobalMosaicsSentinel1.json
@@ -0,0 +1,137 @@
+{
+ "type": "FeatureCollection",
+ "properties": {
+ "id": "4126eeb8-956b-5bd0-b6d8-99cf088365fb",
+ "totalResults": null,
+ "exactCount": 0,
+ "startIndex": 1,
+ "itemsPerPage": 1000,
+ "query": {
+ "originalFilters": {
+ "box": "116.56784977351838,33.818177847881614,116.67755861181377,33.88958185515551",
+ "status": "ONLINE",
+ "dataset": "ESA-DATASET",
+ "platform": "SENTINEL-1",
+ "startDate": "2023-09-01T00:00:00Z",
+ "completionDate": "2024-10-01T00:00:00Z",
+ "collection": "GLOBAL-MOSAICS"
+ },
+ "appliedFilters": {
+ "box": "116.56784977351838,33.818177847881614,116.67755861181377,33.88958185515551",
+ "status": "ONLINE",
+ "dataset": "ESA-DATASET",
+ "platform": "SENTINEL-1",
+ "startDate": "2023-09-01T00:00:00Z",
+ "completionDate": "2024-10-01T00:00:00Z",
+ "collection": "GLOBAL-MOSAICS"
+ },
+ "processingTime": 0.812684961
+ },
+ "links": [
+ {
+ "rel": "self",
+ "type": "application/json",
+ "title": "self",
+ "href": "https://catalogue.dataspace.copernicus.eu/resto/api/collections/GLOBAL-MOSAICS/search.json?box=116.56784977351838%2C33.818177847881614%2C116.67755861181377%2C33.88958185515551&page=1&maxRecords=1000&status=ONLINE&dataset=ESA-DATASET&platform=SENTINEL-1&startDate=2023-09-01T00%3A00%3A00Z&completionDate=2024-10-01T00%3A00%3A00Z"
+ },
+ {
+ "rel": "search",
+ "type": "application/opensearchdescription+xml",
+ "title": "OpenSearch Description Document",
+ "href": "https://catalogue.dataspace.copernicus.eu/resto/api/collections/GLOBAL-MOSAICS/describe.xml"
+ }
+ ]
+ },
+ "features": [
+ {
+ "type": "Feature",
+ "id": "e605002a-63a5-49ca-9abf-7e65c6d94f6a",
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ 115.923810175081,
+ 33.4343643656752
+ ],
+ [
+ 115.912416716213,
+ 34.3368332245052
+ ],
+ [
+ 117.000434893879,
+ 34.3416634578714
+ ],
+ [
+ 117.000430336879,
+ 33.4390338814186
+ ],
+ [
+ 115.923810175081,
+ 33.4343643656752
+ ]
+ ]
+ ]
+ },
+ "properties": {
+ "collection": "GLOBAL-MOSAICS",
+ "status": "ONLINE",
+ "license": {
+ "licenseId": "unlicensed",
+ "hasToBeSigned": "never",
+ "grantedCountries": null,
+ "grantedOrganizationCountries": null,
+ "grantedFlags": null,
+ "viewService": "public",
+ "signatureQuota": -1,
+ "description": {
+ "shortName": "No license"
+ }
+ },
+ "parentIdentifier": null,
+ "title": "Sentinel-1_IW_mosaic_2023_M12_50SMC_0_0",
+ "description": null,
+ "organisationName": null,
+ "startDate": "2023-12-01T00:00:00.000Z",
+ "completionDate": "2023-12-31T23:59:59.000Z",
+ "productType": "S1SAR_L3_IW_MCM",
+ "processingLevel": null,
+ "platform": "SENTINEL-1",
+ "instrument": null,
+ "resolution": 0,
+ "sensorMode": null,
+ "orbitNumber": 0,
+ "quicklook": null,
+ "thumbnail": null,
+ "updated": "2024-06-19T03:28:32.729Z",
+ "published": "2024-06-19T03:28:32.729Z",
+ "snowCover": 0,
+ "cloudCover": 0,
+ "gmlgeometry": "115.923810175081,33.4343643656752 115.912416716213,34.3368332245052 117.000434893879,34.3416634578714 117.000430336879,33.4390338814186 115.923810175081,33.4343643656752",
+ "centroid": {
+ "type": "Point",
+ "coordinates": [
+ 116.459279094554,
+ 33.8887658994282
+ ]
+ },
+ "productIdentifier": "/eodata/Global-Mosaics/Sentinel-1/S1SAR_L3_IW_MCM/2023/12/01/Sentinel-1_IW_mosaic_2023_M12_50SMC_0_0",
+ "services": {
+ "download": {
+ "url": "https://catalogue.dataspace.copernicus.eu/download/e605002a-63a5-49ca-9abf-7e65c6d94f6a",
+ "mimeType": "application/octet-stream",
+ "size": -1
+ }
+ },
+ "links": [
+ {
+ "rel": "self",
+ "type": "application/json",
+ "title": "GeoJSON link for e605002a-63a5-49ca-9abf-7e65c6d94f6a",
+ "href": "https://catalogue.dataspace.copernicus.eu/resto/collections/GLOBAL-MOSAICS/e605002a-63a5-49ca-9abf-7e65c6d94f6a.json"
+ }
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/test/scala/org/openeo/opensearch/CreoFeatureCollectionTest.scala b/src/test/scala/org/openeo/opensearch/CreoFeatureCollectionTest.scala
index 96987b74..0d9b27a1 100644
--- a/src/test/scala/org/openeo/opensearch/CreoFeatureCollectionTest.scala
+++ b/src/test/scala/org/openeo/opensearch/CreoFeatureCollectionTest.scala
@@ -209,4 +209,23 @@ class CreoFeatureCollectionTest {
assertTrue(featureIds.forall(_.startsWith("/eodata/Sentinel-2")), "unexpected product identifiers")
assertFalse(featureIds contains corruptTileProductIdentifier, "corrupt tile is still present")
}
+
+ @Test
+ def globalMosaicsSentinel1Response(): Unit = {
+ val productsResponse = loadJsonResource("creodiasGlobalMosaicsSentinel1.json")
+
+ val FeatureCollection(_, features) = CreoFeatureCollection.parse(productsResponse, dedup = true)
+
+ val titledHrefs = for {
+ feature <- features
+ link <- feature.links
+ } yield (link.title, link.href.toString)
+
+ val expected = Set(
+ (Some("VV"), "/eodata/Global-Mosaics/Sentinel-1/S1SAR_L3_IW_MCM/2023/12/01/Sentinel-1_IW_mosaic_2023_M12_50SMC_0_0/VV.tif"),
+ (Some("VH"), "/eodata/Global-Mosaics/Sentinel-1/S1SAR_L3_IW_MCM/2023/12/01/Sentinel-1_IW_mosaic_2023_M12_50SMC_0_0/VH.tif"),
+ )
+
+ assertEquals(expected, titledHrefs.toSet)
+ }
}