Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: update stac collection TDE-453 #134

Merged
merged 15 commits into from
Sep 23, 2022
4 changes: 4 additions & 0 deletions scripts/files/files_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ def get_file_name_from_path(path: str) -> str:

def is_tiff(path: str) -> bool:
return path.lower().endswith((".tiff", ".tif"))


def is_json(path: str) -> bool:
return path.lower().endswith(".json")
80 changes: 72 additions & 8 deletions scripts/stac/imagery/collection.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime
from typing import Any, Dict, List, Optional

import ulid
Expand Down Expand Up @@ -27,17 +28,80 @@ def __init__(
raise Exception("incorrect initialising parameters must have 'stac' or 'title and description'")

def add_link(self, href: str, rel: str = "item", file_type: str = "application/json") -> None:
# Will be implemented in Future PR
pass
self.stac["links"].append({"rel": rel, "href": href, "type": file_type})

def update_spatial_extent(self, item_bbox: List[float]) -> None:
MDavidson17 marked this conversation as resolved.
Show resolved Hide resolved
# Will be implemented in Future PR
pass
if "extent" not in self.stac:
self.update_extent(bbox=item_bbox)
return
if not self.stac["extent"]["spatial"]["bbox"]:
self.update_extent(bbox=item_bbox)
return

bbox = self.stac["extent"]["spatial"]["bbox"]
min_x = min(bbox[0], bbox[2])
max_x = max(bbox[0], bbox[2])
min_y = min(bbox[1], bbox[3])
max_y = max(bbox[1], bbox[3])

item_min_x = min(item_bbox[0], item_bbox[2])
item_max_x = max(item_bbox[0], item_bbox[2])
item_min_y = min(item_bbox[1], item_bbox[3])
item_max_y = max(item_bbox[1], item_bbox[3])

if item_min_x < min_x:
min_x = item_min_x
if item_min_y < min_y:
min_y = item_min_y
if item_max_x > max_x:
max_x = item_max_x
if item_max_y > max_y:
max_y = item_max_y

self.update_extent(bbox=[min_x, min_y, max_x, max_y])

def update_temporal_extent(self, item_start_datetime: str, item_end_datetime: str) -> None:
MDavidson17 marked this conversation as resolved.
Show resolved Hide resolved
# Will be implemented in Future PR
pass
if "extent" not in self.stac:
self.update_extent(interval=[item_start_datetime, item_end_datetime])
return
if not self.stac["extent"]["temporal"]["interval"]:
self.update_extent(interval=[item_start_datetime, item_end_datetime])
return

interval = self.stac["extent"]["temporal"]["interval"]

item_start = datetime.strptime(item_start_datetime, "%Y-%m-%dT%H:%M:%SZ")
item_end = datetime.strptime(item_end_datetime, "%Y-%m-%dT%H:%M:%SZ")

collection_datetimes = []
for date in interval:
collection_datetimes.append(datetime.strptime(date, "%Y-%m-%dT%H:%M:%SZ"))

start_datetime = min(collection_datetimes[0], collection_datetimes[1])
end_datetime = max(collection_datetimes[0], collection_datetimes[1])

if item_start < start_datetime:
start_datetime = item_start
if item_end > end_datetime:
end_datetime = item_end

self.update_extent(
interval=[
start_datetime.strftime("%Y-%m-%dT%H:%M:%SZ"),
end_datetime.strftime("%Y-%m-%dT%H:%M:%SZ"),
]
)

def update_extent(self, bbox: Optional[List[float]] = None, interval: Optional[List[str]] = None) -> None:
# Will be implemented in Future PR
pass
if "extent" not in self.stac:
self.stac["extent"] = {
"spatial": {
"bbox": bbox,
},
"temporal": {"interval": interval},
}
return
if bbox:
self.stac["extent"]["spatial"]["bbox"] = bbox
if interval:
self.stac["extent"]["temporal"]["interval"] = interval
33 changes: 33 additions & 0 deletions scripts/stac/tests/collection_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,36 @@ def test_imagery_stac_collection_initialise() -> None:

assert collection.stac["title"] == title
assert collection.stac["description"] == description


def test_imagery_stac_collection_update() -> None:
title = "Test Urban Imagery"
description = "Test Urban Imagery Description"
bbox = [1799667.5, 5815977.0, 1800422.5, 5814986.0]
start_datetime = "2021-01-27T00:00:00Z"
end_datetime = "2021-01-27T00:00:00Z"
collection = ImageryCollection(title, description)
collection.update_spatial_extent(bbox)
collection.update_temporal_extent(start_datetime, end_datetime)
assert collection.stac["extent"]["temporal"]["interval"] == [start_datetime, end_datetime]


def test_imagery_stac_collection_update_twice() -> None:
title = "Test Urban Imagery"
description = "Test Urban Imagery Description"
collection = ImageryCollection(title, description)

bbox_one = [174.889641, -41.217532, 174.902344, -41.203521]
start_datetime_one = "2021-01-27T00:00:00Z"
end_datetime_one = "2021-01-27T00:00:00Z"
collection.update_spatial_extent(bbox_one)
collection.update_temporal_extent(start_datetime_one, end_datetime_one)

bbox_two = [174.917643, -41.211157, 174.922965, -41.205490]
start_datetime_two = "2021-02-01T00:00:00Z"
end_datetime_two = "2021-02-20T00:00:00Z"
collection.update_spatial_extent(bbox_two)
collection.update_temporal_extent(start_datetime_two, end_datetime_two)

assert collection.stac["extent"]["temporal"]["interval"] == [start_datetime_one, end_datetime_two]
assert collection.stac["extent"]["spatial"]["bbox"] == [174.889641, -41.217532, 174.922965, -41.203521]
8 changes: 4 additions & 4 deletions scripts/standardise_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
def main() -> None:

concurrency: int = 1
parser = argparse.ArgumentParser()
parser.add_argument("--preset", dest="preset", required=True)
parser.add_argument("--source", dest="source", nargs="+", required=True)
arguments = parser.parse_args()
parse_args = argparse.ArgumentParser()
parse_args.add_argument("--preset", dest="preset", required=True)
parse_args.add_argument("--source", dest="source", nargs="+", required=True)
arguments = parse_args.parse_args()

source = format_source(arguments.source)

Expand Down
49 changes: 49 additions & 0 deletions scripts/update_stac_collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import argparse
import json
from typing import List

from linz_logger import get_log

from scripts.cli.cli_helper import format_source
from scripts.files.files_helper import is_json
from scripts.files.fs import read, write
from scripts.logging.time_helper import time_in_ms
from scripts.stac.imagery.collection import ImageryCollection
from scripts.stac.imagery.item import ImageryItem


def update_imagery_collection(files: List[str], collection_path: str) -> None:
start_time = time_in_ms()
get_log().info("finalise_stac_collection_imagery_start", collection=collection_path)

collection = ImageryCollection(stac=json.loads(read(collection_path)))

for file in files:
if not is_json(file):
get_log().trace("create_stac_file_not_tiff_skipped", file=file)
item = ImageryItem(stac=json.loads(read(file)))
collection.add_link(href=file)
collection.update_temporal_extent(item.stac["properties"]["start_datetime"], item.stac["properties"]["end_datetime"])
collection.update_spatial_extent(item.stac["bbox"])

write(collection_path, json.dumps(collection.stac).encode("utf-8"))

get_log().info(
"update_stac_collection_imagery_complete", collection=collection.stac, source=files, duration=time_in_ms() - start_time
)


def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--source", dest="source", nargs="+", required=True)
parser.add_argument("--collection", dest="collection", help="path to collection.json", required=True)
arguments = parser.parse_args()

files = format_source(arguments.source)
collection_path = arguments.collection

update_imagery_collection(files, collection_path)


if __name__ == "__main__":
main()