Skip to content

Commit

Permalink
Merge pull request #9 from scottstanie/update-datasets-cli
Browse files Browse the repository at this point in the history
Update datasets hash and add first cli
  • Loading branch information
scottstanie authored Dec 3, 2023
2 parents 1a9aa69 + e9ab93b commit 80fc976
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 5 deletions.
2 changes: 2 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ dependencies:
- python>=3.8
- pip>=21.3 # https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/#editable-installation
- git # for pip install, due to setuptools_scm
- click>=7.0
- h5py>=1.10
- numpy>=1.20
- pooch>=1.7
- pyproj>=3.3
- shapely>=1.8
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Changelog = "https://github.com/opera-adt/opera-utils/releases"

# Entry points for the command line interface
[project.scripts]
opera_utils = "opera_utils.cli:main"
opera-utils = "opera_utils.cli:cli_app"

[tool.setuptools.dynamic]
dependencies = { file = ["requirements.txt"] }
Expand Down
12 changes: 12 additions & 0 deletions src/opera_utils/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from itertools import chain, combinations
from typing import Any, Iterable, Mapping

from ._types import Bbox


def flatten(list_of_lists: Iterable[Iterable[Any]]) -> chain[Any]:
"""Flatten one level of nesting."""
Expand All @@ -25,3 +27,13 @@ def powerset(iterable: Iterable[Any]) -> chain[tuple[Any, ...]]:
"""
s = list(iterable)
return flatten(combinations(s, r) for r in range(len(s) + 1))


def reproject_bounds(bounds: Bbox, src_epsg: int, dst_epsg: int) -> Bbox:
"""Reproject the (left, bottom, right top) from `src_epsg to `dst_epsg`."""
from pyproj import Transformer

t = Transformer.from_crs(src_epsg, dst_epsg, always_xy=True)
left, bottom, right, top = bounds
bbox: Bbox = (*t.transform(left, bottom), *t.transform(right, top)) # type: ignore
return bbox
4 changes: 2 additions & 2 deletions src/opera_utils/burst_frame_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ def get_burst_id_geojson(
def _form_where_in_query(values: Sequence[str], column_name):
# Example:
# "burst_id_jpl in ('t005_009471_iw2','t007_013706_iw2','t008_015794_iw1')"
burst_str = ",".join(f"'{b}'" for b in values)
return f"{column_name} IN ({burst_str})"
where_in_str = ",".join(f"'{b}'" for b in values)
return f"{column_name} IN ({where_in_str})"


def _get_geojson(
Expand Down
54 changes: 54 additions & 0 deletions src/opera_utils/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""Command-line interface for opera-utils."""
from __future__ import annotations

import json
import logging

import click

from .burst_frame_db import get_frame_bbox


@click.group()
@click.version_option()
@click.option("--debug", is_flag=True, default=False)
@click.pass_context
def cli_app(ctx, debug):
"""Orca command-line interface."""
level = logging.DEBUG if debug else logging.INFO
handler = logging.StreamHandler()
logging.basicConfig(level=level, handlers=[handler])


@cli_app.command()
@click.argument("frame_id")
@click.option(
"--latlon",
"-l",
is_flag=True,
help="Output the bounding box in latitude/longitude (EPSG:4326)",
)
@click.option(
"--bounds-only",
"-b",
is_flag=True,
help="Output only (left, bottom, right, top) and omit EPSG",
)
def frame_bbox(frame_id, latlon: bool, bounds_only: bool):
"""Look up the EPSG/bounding box for FRAME_ID.
Outputs as JSON string to stdout like
{"epsg": 32618, "bbox": [157140.0, 4145220.0, 440520.0, 4375770.0]}
Unless `--bounds-only` is given
"""
epsg, bounds = get_frame_bbox(frame_id=frame_id)
if latlon:
from opera_utils._helpers import reproject_bounds

bounds = reproject_bounds(bounds, epsg, 4326)
if bounds_only:
click.echo(list(bounds))
else:
obj = dict(epsg=epsg, bbox=bounds)
click.echo(json.dumps(obj))
4 changes: 2 additions & 2 deletions src/opera_utils/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
# are their respective SHA256 hashes. Files will be downloaded
# automatically when needed.
registry={
f"frame-geometries-simple-{BURST_DB_VERSION}.geojson.zip": "f0094f4cdc287d56d7a126a42f1e3075e50309afe8a431f49df1ecd8d8b26c8b",
f"burst-id-geometries-simple-{BURST_DB_VERSION}.geojson.zip": "d9cfe71ec836facd5a782ea82625c30a824b78f2b2689106c4d6808bbfce0898",
f"frame-geometries-simple-{BURST_DB_VERSION}.geojson.zip": "963f63577221a3baa20f3a2101c7a01eefb0cc853f6f111708a5bb35bebfc0ed",
f"burst-id-geometries-simple-{BURST_DB_VERSION}.geojson.zip": "e75cc27809448d7ace2164879626fb0b5616b16981a6b2d6d234e3b17cb615fa",
f"opera-s1-disp-burst-to-frame-{BURST_DB_VERSION}.json.zip": "436cce345378dc31e81ed661497bab2e744217a5d63c0bb92817dc837786cd22",
f"opera-s1-disp-frame-to-burst-{BURST_DB_VERSION}.json.zip": "a48382afcb89f0ff681982b0fc24476ec9c6c1b8a67ae1a26cf380a450ffadc0",
},
Expand Down
16 changes: 16 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from click.testing import CliRunner

from opera_utils.cli import cli_app


def test_cli_help():
runner = CliRunner()
result = runner.invoke(cli_app, ["--help"])
assert result.exit_code == 0
assert result.output.startswith("Usage:")


def test_frame_bbox_help():
runner = CliRunner()
result = runner.invoke(cli_app, ["frame-bbox", "--help"])
assert result.exit_code == 0

0 comments on commit 80fc976

Please sign in to comment.