Skip to content

Commit

Permalink
Geojson cog support (#10)
Browse files Browse the repository at this point in the history
* add handling of geojson and cog files
  • Loading branch information
lubojr authored Jul 12, 2024
1 parent 360637b commit 29b906b
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 1 deletion.
58 changes: 57 additions & 1 deletion src/eodash_catalog/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import requests
from dateutil import parser
from pystac import Catalog, Collection, Item, Link, SpatialExtent, Summaries
from pystac import Asset, Catalog, Collection, Item, Link, SpatialExtent, Summaries
from pystac_client import Client

from eodash_catalog.sh_endpoint import get_SH_token
Expand All @@ -23,6 +23,7 @@
from eodash_catalog.thumbnails import generate_thumbnail
from eodash_catalog.utils import (
Options,
create_geojson_from_bbox,
create_geojson_point,
generate_veda_cog_link,
retrieveExtentFromWMSWMTS,
Expand Down Expand Up @@ -764,3 +765,58 @@ def handle_custom_endpoint(
collection_config,
)
return collection


def handle_raw_source(
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
)
if len(endpoint_config.get("TimeEntries", [])) > 0:
for time_entry in endpoint_config["TimeEntries"]:
extra_fields = {}
if "DataProjection" in endpoint_config:
extra_fields["proj:epsg"] = endpoint_config["DataProjection"]
assets = {}
media_type = "application/geo+json"
style_type = "text/vector-styles"
if endpoint_config["Name"] == "COG source":
style_type = "text/cog-styles"
media_type = "image/tiff"
for a in time_entry["Assets"]:
assets[a["Identifier"]] = Asset(
href=a["File"], roles=["data"], media_type=media_type, extra_fields=extra_fields
)
bbox = endpoint_config.get("Bbox", [-180, -85, 180, 85])
item = Item(
id=time_entry["Time"],
bbox=bbox,
properties={},
geometry=create_geojson_from_bbox(bbox),
datetime=parser.isoparse(time_entry["Time"]),
assets=assets,
)
ep_st = endpoint_config["Style"]
style_link = Link(
rel="style",
target=ep_st
if ep_st.startswith("http")
else f"{catalog_config['assets_endpoint']}/{ep_st}",
media_type=style_type,
extra_fields={
"asset:keys": list(assets),
},
)
item.add_link(style_link)
if "DataProjection" in endpoint_config:
collection.extra_fields["proj:epsg"] = endpoint_config["DataProjection"]
link = collection.add_item(item)
link.extra_fields["datetime"] = time_entry["Time"]
link.extra_fields["assets"] = [a["File"] for a in time_entry["Assets"]]
add_collection_information(catalog_config, collection, collection_config)
collection.update_extent_from_items()
return collection
5 changes: 5 additions & 0 deletions src/eodash_catalog/generate_indicators.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
handle_collection_only,
handle_custom_endpoint,
handle_GeoDB_endpoint,
handle_raw_source,
handle_SH_endpoint,
handle_SH_WMS_endpoint,
handle_VEDA_endpoint,
Expand Down Expand Up @@ -240,6 +241,10 @@ def process_collection_file(
collection_config,
catalog,
)
elif resource["Name"] in ["COG source", "GeoJSON source"]:
collection = handle_raw_source(
catalog_config, resource, collection_config, catalog
)
else:
raise ValueError("Type of Resource is not supported")
if collection:
Expand Down
15 changes: 15 additions & 0 deletions src/eodash_catalog/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ def create_geojson_point(lon: int | float, lat: int | float) -> dict[str, Any]:
return {"type": "Feature", "geometry": point, "properties": {}}


def create_geojson_from_bbox(bbox: list[float | int]) -> dict:
coordinates = [
[bbox[0], bbox[1]],
[bbox[2], bbox[1]],
[bbox[2], bbox[3]],
[bbox[0], bbox[3]],
[bbox[0], bbox[1]],
]
polygon = {"type": "Polygon", "coordinates": [coordinates]}

feature = {"type": "Feature", "geometry": polygon, "properties": {}}
feature_collection = {"type": "FeatureCollection", "features": [feature]}
return feature_collection


def retrieveExtentFromWMSWMTS(
capabilities_url: str, layer: str, version: str = "1.1.1", wmts: bool = False
) -> tuple[list[float], list[str]]:
Expand Down
1 change: 1 addition & 0 deletions tests/test-data/regional_forecast.json

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions tests/test_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,47 @@ def test_baselayers_and_overlays_added(catalog_output_folder):
]
assert len(baselayer_links) == 1
assert len(overlay_links) == 1


def test_geojson_dataset_handled(catalog_output_folder):
collection_name = "crop_forecast_at"
root_collection_path = os.path.join(catalog_output_folder, collection_name)
child_collection_path = os.path.join(root_collection_path, collection_name)
child_child_collection_path = os.path.join(child_collection_path, collection_name)
item_dir = os.path.join(child_child_collection_path, "2024")
item_paths = os.listdir(item_dir)
assert len(item_paths) == 1
with open(os.path.join(child_collection_path, "collection.json")) as fp:
collection_json = json.load(fp)
geojson_links = [
link
for link in collection_json["links"]
if (link.get("rel", "") == "item" and len(link.get("assets", [])) > 0)
]
# geojson link with assets exists
assert len(geojson_links) > 0
# and has a correct value
assert (
geojson_links[0]["assets"][0]
== "https://raw.githubusercontent.com/eodash/eodash_catalog/main/tests/regional_forecast.json"
)
# epsg code saved on collection
assert collection_json.get("proj:epsg", "") == 3035
# epsg code is saved to item
with open(os.path.join(item_dir, item_paths[0])) as fp:
item_json = json.load(fp)
assert item_json["assets"]["vector_data"]["type"] == "application/geo+json"
assert item_json["collection"] == collection_name


def test_cog_dataset_handled(catalog_output_folder):
collection_name = "solar_energy"
root_collection_path = os.path.join(catalog_output_folder, collection_name)
child_collection_path = os.path.join(root_collection_path, collection_name)
child_child_collection_path = os.path.join(child_collection_path, collection_name)
item_dir = os.path.join(child_child_collection_path, "2023")
item_paths = os.listdir(item_dir)
with open(os.path.join(item_dir, item_paths[0])) as fp:
item_json = json.load(fp)
assert item_json["assets"]["solar_power"]["type"] == "image/tiff"
assert item_json["collection"] == collection_name
2 changes: 2 additions & 0 deletions tests/testing-catalogs/testing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ assets_endpoint: "https://raw.githubusercontent.com/eurodatacube/eodash-assets/m
collections:
- test_wms_no_time
- test_indicator
- test_CROPOMAT1
- test_see_solar_energy
51 changes: 51 additions & 0 deletions tests/testing-collections/test_CROPOMAT1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Name: crop_forecast_at
Title: Austria yield
EodashIdentifier: CROPOMAT1
Subtitle: Yield forecast under "what-if" scenarios
Description: ""
Themes:
- agriculture
- economy
Tags:
- Crop
- Yield
- Water
- Forecast
DataSource:
Spaceborne:
Satellite:
- Sentinel-2
- CLMS HR-VPP Vegetation Indices
- CLMS HR-VPP Seasonal Trajectory
InSitu:
- Meteorological data from local Meteorological offices (AT)
Agency:
- ESA
Provider:
- Name: CropOM
Url: https://cropom.com
- Name: Danube Data Cube
Url: https://ddc.cropom.com
- Name: Copernicus Land Monitoring Service
Url: https://land.copernicus.eu/en/dataset-catalog
- Name: FAO
Url: https://www.fao.org/home/en
License:
- Name: Commercial license
Url: https://cropom.com/terms_and_conditions.pdf
References:
- Name: Danube Data Cube documentation
Url: https://doc.cropom.com
- Name: AquaCrop
Url: https://www.fao.org/aquacrop/en/
Resources:
- Name: GeoJSON source
Style: crop_forecast_CropOM/style_yield.json
Bbox: [9.27, 46.2, 17.3, 49.2]
DataProjection: 3035
TimeEntries:
- Time: "20240101"
Assets:
- Identifier: vector_data
File: "https://raw.githubusercontent.com/eodash/eodash_catalog/main/tests/regional_forecast.json"
Legend: crop_forecast_CropOM/cm_legend.png
25 changes: 25 additions & 0 deletions tests/testing-collections/test_see_solar_energy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Name: solar_energy
Title: Solar energy cog example
EodashIdentifier: SEE
Description: testing
Themes:
- placeholder
Tags:
- placeholder
DataSource:
Spaceborne:
Satellite:
- Sentinel-2
Agency:
- ESA
Resources:
- Name: COG source
Style: test_assets/cog_style.json
Bbox: [11, 46.5, 15.5, 48.9]
TimeEntries:
- Time: "2023"
Assets:
- Identifier: solar_power
File: https://eox-gtif-public.s3.eu-central-1.amazonaws.com/DHI/v2/SolarPowerPotential_Annual_COG_clipped_3857_fixed.tif
- Identifier: wsf
File: https://eox-gtif-public.s3.eu-central-1.amazonaws.com/DHI/WSF_EucDist_Austria_3857_COG_fix.tif

0 comments on commit 29b906b

Please sign in to comment.