eodash_catalog 0.3.0__py3-none-any.whl → 0.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of eodash_catalog might be problematic. Click here for more details.

@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2024-present Daniel Santillan <daniel.santillan@eox.at>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- __version__ = "0.3.0"
4
+ __version__ = "0.3.2"
@@ -1,4 +1,5 @@
1
1
  import importlib
2
+ import io
2
3
  import json
3
4
  import os
4
5
  import sys
@@ -8,6 +9,7 @@ from datetime import datetime, timedelta
8
9
  from itertools import groupby
9
10
  from operator import itemgetter
10
11
 
12
+ import pyarrow.parquet as pq
11
13
  import requests
12
14
  from pystac import Asset, Catalog, Collection, Item, Link, SpatialExtent, Summaries, TemporalExtent
13
15
  from pystac_client import Client
@@ -28,6 +30,7 @@ from eodash_catalog.thumbnails import generate_thumbnail
28
30
  from eodash_catalog.utils import (
29
31
  Options,
30
32
  create_geometry_from_bbox,
33
+ extract_extent_from_geoparquet,
31
34
  filter_time_entries,
32
35
  format_datetime_to_isostring_zulu,
33
36
  generate_veda_cog_link,
@@ -830,7 +833,11 @@ def generate_veda_tiles_link(endpoint_config: dict, item: str | None) -> str:
830
833
  if endpoint_config.get("NoData"):
831
834
  no_data = "&no_data={}".format(endpoint_config["NoData"])
832
835
  item = item if item else "{item}"
833
- target_url = f"https://openveda.cloud/api/raster/collections/{collection}/items/{item}/tiles/WebMercatorQuad/{{z}}/{{x}}/{{y}}?{assets}{color_formula}{no_data}"
836
+ target_url_base = endpoint_config["EndPoint"].replace("/stac/", "")
837
+ target_url = (
838
+ f"{target_url_base}/raster/collections/{collection}/items/{item}"
839
+ f"/tiles/WebMercatorQuad/{{z}}/{{x}}/{{y}}?{assets}{color_formula}{no_data}"
840
+ )
834
841
  return target_url
835
842
 
836
843
 
@@ -1214,6 +1221,33 @@ def handle_raw_source(
1214
1221
  # eodash v4 compatibility, adding last referenced style to collection
1215
1222
  if style_link:
1216
1223
  collection.add_link(style_link)
1224
+ elif endpoint_config.get("ParquetSource"):
1225
+ # if parquet source is provided, download it and create items from it
1226
+ parquet_source = endpoint_config["ParquetSource"]
1227
+ if parquet_source.startswith("http"):
1228
+ # download parquet file
1229
+ parquet_file = requests.get(parquet_source)
1230
+ if parquet_file.status_code != 200:
1231
+ LOGGER.error(f"Failed to download parquet file from {parquet_source}")
1232
+ return collection
1233
+ try:
1234
+ table = pq.read_table(io.BytesIO(parquet_file.content))
1235
+ except Exception as e:
1236
+ LOGGER.error(f"Failed to read parquet file: {e}")
1237
+ return collection
1238
+ extents = extract_extent_from_geoparquet(table)
1239
+ collection.extent.temporal = extents[0]
1240
+ collection.extent.spatial = extents[1]
1241
+ collection.add_asset(
1242
+ "geoparquet",
1243
+ Asset(
1244
+ href=parquet_source,
1245
+ media_type="application/vnd.apache.parquet",
1246
+ title="GeoParquet Items",
1247
+ roles=["collection-mirror"],
1248
+ ),
1249
+ )
1250
+
1217
1251
  else:
1218
1252
  LOGGER.warn(f"NO datetimes configured for collection: {collection_config['Name']}!")
1219
1253
 
eodash_catalog/utils.py CHANGED
@@ -18,7 +18,7 @@ from dateutil import parser
18
18
  from owslib.wcs import WebCoverageService
19
19
  from owslib.wms import WebMapService
20
20
  from owslib.wmts import WebMapTileService
21
- from pystac import Asset, Catalog, Collection, Item, Link, RelType, SpatialExtent, TemporalExtent
21
+ from pystac import Asset, Catalog, Collection, Item, RelType, SpatialExtent, TemporalExtent
22
22
  from pytz import timezone as pytztimezone
23
23
  from shapely import geometry as sgeom
24
24
  from shapely import wkb
@@ -290,8 +290,12 @@ def generate_veda_cog_link(endpoint_config: dict, file_url: str | None) -> str:
290
290
  )
291
291
 
292
292
  file_url = f"url={file_url}&" if file_url else ""
293
-
294
- target_url = f"https://openveda.cloud/api/raster/cog/tiles/WebMercatorQuad/{{z}}/{{x}}/{{y}}?{file_url}resampling_method=nearest{bidx}{colormap}{colormap_name}{rescale}{Nodata}"
293
+ target_url_base = endpoint_config["EndPoint"].replace("/stac/", "")
294
+ target_url = (
295
+ f"{target_url_base}/raster/cog/tiles/WebMercatorQuad/{{z}}/{{x}}/{{y}}?"
296
+ f"{file_url}resampling_method=nearest"
297
+ f"{bidx}{colormap}{colormap_name}{rescale}{Nodata}"
298
+ )
295
299
  return target_url
296
300
 
297
301
 
@@ -444,6 +448,29 @@ def update_extents_from_collection_children(collection: Collection):
444
448
  collection.extent.temporal = TemporalExtent([time_extent])
445
449
 
446
450
 
451
+ def extract_extent_from_geoparquet(table) -> tuple[TemporalExtent, SpatialExtent]:
452
+ """
453
+ Extract spatial and temporal extents from a GeoParquet file.
454
+ Args:
455
+ table (pyarrow.Table): The table containing the GeoParquet data.
456
+ Returns:
457
+ tuple: A tuple containing spatial and temporal extents.
458
+ """
459
+ # add extent information to the collection
460
+ min_datetime = pc.min(table["datetime"]).as_py()
461
+ max_datetime = pc.max(table["datetime"]).as_py()
462
+ if not min_datetime:
463
+ # cases when datetime was null
464
+ # fallback to start_datetime
465
+ min_datetime = pc.min(table["start_datetime"]).as_py()
466
+ max_datetime = pc.max(table["start_datetime"]).as_py()
467
+ temporal = TemporalExtent([min_datetime, max_datetime])
468
+ geoms = [wkb.loads(g.as_py()) for g in table["geometry"] if g is not None]
469
+ bbox = sgeom.MultiPolygon(geoms).bounds
470
+ spatial = SpatialExtent([bbox])
471
+ return [temporal, spatial]
472
+
473
+
447
474
  def save_items(
448
475
  collection: Collection,
449
476
  items: list[Item],
@@ -493,25 +520,9 @@ def save_items(
493
520
  output_path = f"{buildcatpath}/{colpath}"
494
521
  os.makedirs(output_path, exist_ok=True)
495
522
  stacgp.arrow.to_parquet(table, f"{output_path}/items.parquet")
496
- gp_link = Link(
497
- rel="items",
498
- target="./items.parquet",
499
- media_type="application/vnd.apache.parquet",
500
- title="GeoParquet Items",
501
- )
502
- collection.add_link(gp_link)
503
- # add extent information to the collection
504
- min_datetime = pc.min(table["datetime"]).as_py()
505
- max_datetime = pc.max(table["datetime"]).as_py()
506
- if not min_datetime:
507
- # cases when datetime was null
508
- # fallback to start_datetime
509
- min_datetime = pc.min(table["start_datetime"]).as_py()
510
- max_datetime = pc.max(table["start_datetime"]).as_py()
511
- collection.extent.temporal = TemporalExtent([min_datetime, max_datetime])
512
- geoms = [wkb.loads(g.as_py()) for g in table["geometry"] if g is not None]
513
- bbox = sgeom.MultiPolygon(geoms).bounds
514
- collection.extent.spatial = SpatialExtent([bbox])
523
+ extents = extract_extent_from_geoparquet(table)
524
+ collection.extent.temporal = extents[0]
525
+ collection.extent.spatial = extents[1]
515
526
  # Make sure to also reference the geoparquet as asset
516
527
  collection.add_asset(
517
528
  "geoparquet",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eodash_catalog
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: This package is intended to help create a compatible STAC catalog for the eodash dashboard client. It supports configuration of multiple endpoint types for information extraction.
5
5
  Project-URL: Documentation, https://github.com/eodash/eodash_catalog#readme
6
6
  Project-URL: Issues, https://github.com/eodash/eodash_catalog/issues
@@ -1,14 +1,14 @@
1
- eodash_catalog/__about__.py,sha256=bCZYdSa6GnF02KXY7cawZv1-fJp_In6NVisHLjGyS2Y,137
1
+ eodash_catalog/__about__.py,sha256=mydI-qYrMicO3OMTwk88yDLDzfB11OJosFgmcQuLT6U,137
2
2
  eodash_catalog/__init__.py,sha256=_W_9emPYf6FUqc0P8L2SmADx6hGSd7PlQV3yRmCk5uM,115
3
3
  eodash_catalog/duration.py,sha256=TBG7v1lCpbYowADK5uJ2M8kPxsvQneFAFi1NIE26dy4,10754
4
- eodash_catalog/endpoints.py,sha256=qPH5FKkGj6i9jTs_VYMWojuH1rbEDwUSxr354Qcnttw,49077
4
+ eodash_catalog/endpoints.py,sha256=NTZ0LlYZ7fJZLvgWZP1aqrNXpBS6GSjfhrfIqU5lDaA,50442
5
5
  eodash_catalog/generate_indicators.py,sha256=FPeiZm9TE4PpbTyH6UMegQ7HwaARzO91IrLtzFjFSF0,21900
6
6
  eodash_catalog/sh_endpoint.py,sha256=XjZsZJ5jfJZLQenSTqUhiUZ5YAu9M9nv2KL1Qv3Be-I,1219
7
7
  eodash_catalog/stac_handling.py,sha256=waw8qRjwjdbDBRtialc4bG3WSjXAATklc-W5kLKywqE,25548
8
8
  eodash_catalog/thumbnails.py,sha256=oNbWdRC8KTLUC4PbSMlSaiOeLXfkIpa0j-sOZdn1RGU,2262
9
- eodash_catalog/utils.py,sha256=PTt1WFcgOdPC4zFFAONWGGbRNF4qQQ549AaSU8hNXnA,22461
10
- eodash_catalog-0.3.0.dist-info/METADATA,sha256=9kmJGF71U3kFYx05pONMgMwh7wJJU406kGj6B5lTfc8,3019
11
- eodash_catalog-0.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
- eodash_catalog-0.3.0.dist-info/entry_points.txt,sha256=kuUQrDG1PtYd8kPjf5XM6H_NtQd9Ozwl0jjiGtAvZSM,87
13
- eodash_catalog-0.3.0.dist-info/licenses/LICENSE.txt,sha256=oJCW5zQxnFD-J0hGz6Zh5Lkpdk1oAndmWhseTmV224E,1107
14
- eodash_catalog-0.3.0.dist-info/RECORD,,
9
+ eodash_catalog/utils.py,sha256=1PafWiW_5SRa4_BsxODNzB43uYyvcsKJvCFIRExH0gA,22752
10
+ eodash_catalog-0.3.2.dist-info/METADATA,sha256=VgwGcib6LSQPiw2D7c6mdP5Vp8R-L9NgSPYyx7Oc35Q,3019
11
+ eodash_catalog-0.3.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
+ eodash_catalog-0.3.2.dist-info/entry_points.txt,sha256=kuUQrDG1PtYd8kPjf5XM6H_NtQd9Ozwl0jjiGtAvZSM,87
13
+ eodash_catalog-0.3.2.dist-info/licenses/LICENSE.txt,sha256=oJCW5zQxnFD-J0hGz6Zh5Lkpdk1oAndmWhseTmV224E,1107
14
+ eodash_catalog-0.3.2.dist-info/RECORD,,