Skip to content

Commit

Permalink
Merge pull request #20 from eodash/rasdaman
Browse files Browse the repository at this point in the history
Implementation of rasdaman WCS handler
  • Loading branch information
santilland authored Oct 7, 2024
2 parents c8adc12 + 98781f1 commit fcb97dd
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
80 changes: 80 additions & 0 deletions src/eodash_catalog/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,50 @@
generate_veda_cog_link,
parse_datestring_to_tz_aware_datetime,
replace_with_env_variables,
retrieveExtentFromWCS,
retrieveExtentFromWMSWMTS,
)

LOGGER = get_logger(__name__)


def process_WCS_rasdaman_Endpoint(
catalog_config: dict, endpoint_config: dict, collection_config: dict, catalog: Catalog
) -> Collection:
collection = get_or_create_collection(
catalog, collection_config["Name"], collection_config, catalog_config, endpoint_config
)
bbox, datetimes = retrieveExtentFromWCS(
endpoint_config["EndPoint"],
endpoint_config["CoverageId"],
version=endpoint_config.get("Version", "2.0.1"),
)
for dt in datetimes:
item = Item(
id=format_datetime_to_isostring_zulu(dt),
bbox=bbox,
properties={},
geometry=None,
datetime=dt,
)
add_visualization_info(item, collection_config, endpoint_config, datetimes=[dt])
link = collection.add_item(item)
# bubble up information we want to the link
link.extra_fields["datetime"] = format_datetime_to_isostring_zulu(dt)

if datetimes:
collection.update_extent_from_items()
else:
LOGGER.warn(f"NO datetimes returned for collection: {endpoint_config['CoverageId']}!")

add_collection_information(catalog_config, collection, collection_config)
# if not coll:
# raise ValueError(f"Collection {collection_id} not found in endpoint {endpoint_config}")
# item_id = endpoint_config.get("CollectionId", "datacube")
# item = coll.get_item(item_id)
return collection


def process_STAC_Datacube_Endpoint(
catalog_config: dict, endpoint_config: dict, collection_config: dict, catalog: Catalog
) -> Collection:
Expand Down Expand Up @@ -427,6 +465,16 @@ def handle_xcube_endpoint(
return collection


def handle_rasdaman_endpoint(
catalog_config: dict, endpoint_config: dict, collection_config: dict, catalog: Catalog
) -> Collection:
collection = process_WCS_rasdaman_Endpoint(
catalog_config, endpoint_config, collection_config, catalog
)
# add_example_info(collection, collection_config, endpoint_config, catalog_config)
return collection


def handle_GeoDB_endpoint(
catalog_config: dict, endpoint_config: dict, collection_config: dict, catalog: Catalog
) -> Collection:
Expand Down Expand Up @@ -705,6 +753,38 @@ def add_visualization_info(
link,
)
stac_object.add_link(link)
elif endpoint_config["Name"] == "rasdaman":
extra_fields.update(
{
"wms:layers": [endpoint_config["CoverageId"]],
"role": ["data"],
}
)
dimensions = {}
if dimensions_config := endpoint_config.get("Dimensions", {}):
for key, value in dimensions_config.items():
dimensions[key] = value
if datetimes is not None:
dimensions["TIME"] = format_datetime_to_isostring_zulu(datetimes[0])
if dimensions != {}:
extra_fields["wms:dimensions"] = dimensions
if "Styles" in endpoint_config:
extra_fields["wms:styles"] = endpoint_config["Styles"]
media_type = endpoint_config.get("MediaType", "image/png")
endpoint_url = endpoint_config["EndPoint"]
# custom replacing of all ENV VARS present as template in URL as {VAR}
link = Link(
rel="wms",
target=endpoint_url,
media_type=media_type,
title=collection_config["Name"],
extra_fields=extra_fields,
)
add_projection_info(
endpoint_config,
link,
)
stac_object.add_link(link)
elif endpoint_config["Name"] == "JAXA_WMTS_PALSAR":
target_url = "{}".format(endpoint_config.get("EndPoint"))
# custom time just for this special case as a default for collection wmts
Expand Down
5 changes: 5 additions & 0 deletions src/eodash_catalog/generate_indicators.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
handle_collection_only,
handle_custom_endpoint,
handle_GeoDB_endpoint,
handle_rasdaman_endpoint,
handle_raw_source,
handle_SH_endpoint,
handle_SH_WMS_endpoint,
Expand Down Expand Up @@ -229,6 +230,10 @@ def process_collection_file(
collection = handle_xcube_endpoint(
catalog_config, endpoint_config, collection_config, catalog
)
elif endpoint_config["Name"] == "rasdaman":
collection = handle_rasdaman_endpoint(
catalog_config, endpoint_config, collection_config, catalog
)
elif endpoint_config["Name"] == "WMS":
collection = handle_WMS_endpoint(
catalog_config, endpoint_config, collection_config, catalog
Expand Down
47 changes: 47 additions & 0 deletions src/eodash_catalog/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from typing import Any

from dateutil import parser
from owslib.wcs import WebCoverageService
from owslib.wms import WebMapService
from owslib.wmts import WebMapTileService
from pystac import Catalog, Collection, Item, RelType
Expand Down Expand Up @@ -56,6 +57,52 @@ def create_geojson_from_bbox(bbox: list[float | int]) -> dict:
return feature_collection


def retrieveExtentFromWCS(
capabilities_url: str,
coverage: str,
version: str = "2.0.1",
) -> tuple[list[float], list[datetime]]:
times = []
try:
service = WebCoverageService(capabilities_url, version)
if coverage in list(service.contents):
description = service.getDescribeCoverage(coverage)
area_val = description.findall(".//{http://www.rasdaman.org}areasOfValidity")
if len(area_val) == 1:
areas = area_val[0].getchildren()
if len(areas) > 1:
times = [t.get("start") for t in areas]
# get unique times
times = reduce(lambda re, x: [*re, x] if x not in re else re, times, [])
except Exception as e:
LOGGER.warn("Issue extracting information from service capabilities")
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(e).__name__, e.args)
LOGGER.warn(message)

bbox = [-180.0, -90.0, 180.0, 90.0]
owsnmspc = "{http://www.opengis.net/ows/2.0}"
# somehow this is not parsed from the rasdaman endpoint
if service and service[coverage].boundingBoxWGS84:
bbox = [float(x) for x in service[coverage].boundingBoxWGS84]
elif service:
# we try to get it ourselves
wgs84bbox = service.contents[coverage]._elem.findall(".//" + owsnmspc + "WGS84BoundingBox")
if len(wgs84bbox) == 1:
lc = wgs84bbox[0].find(".//" + owsnmspc + "LowerCorner").text
uc = wgs84bbox[0].find(".//" + owsnmspc + "UpperCorner").text
bbox = [
float(lc.split()[0]),
float(lc.split()[1]),
float(uc.split()[0]),
float(uc.split()[1]),
]
description.findall(".//{http://www.rasdaman.org}areasOfValidity")

datetimes = [parse_datestring_to_tz_aware_datetime(time_str) for time_str in times]
return bbox, datetimes


def retrieveExtentFromWMSWMTS(
capabilities_url: str, layer: str, version: str = "1.1.1", wmts: bool = False
) -> tuple[list[float], list[datetime]]:
Expand Down

0 comments on commit fcb97dd

Please sign in to comment.