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

Implicit rectangle -> bbox substitution #740

Open
wants to merge 1 commit into
base: test
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions SearchAPI/CMR/Translate/translate_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import requests
from SearchAPI.asf_env import get_config

from shapely import wkt
from shapely.geometry import Polygon
from shapely.geometry.base import BaseGeometry
def translate_params(p):
"""
Translate supported params into CMR params
Expand All @@ -28,6 +31,14 @@ def translate_params(p):
if 'errors' in response:
raise ValueError(f'Could not repair WKT: {val}')
val = response['wkt']['wrapped']
shape = wkt.loads(response['wkt']['unwrapped'])
if _should_use_bbox(shape):
bbox = _get_bbox(shape)
try:
params['bbox'] = input_map()['bbox'][2](bbox)
continue
except ValueError as exc:
raise ValueError(f'{key}: {exc}') from exc
try:
params[key] = input_map()[key][2](val)
except ValueError as exc:
Expand All @@ -52,3 +63,35 @@ def translate_params(p):
del params['maxresults']

return params, output, max_results

def _get_bbox(aoi: BaseGeometry):
# If a wide rectangle is provided, make sure to use the bounding box
# instead of the wkt for better responses from CMR
# This will provide better results with AOI's near poles
bounds = aoi.boundary.bounds
if bounds[0] > 180 or bounds[2] > 180:
bounds = [(x + 180) % 360 - 180 if idx % 2 == 0 and abs(x) > 180 else x for idx, x in enumerate(bounds)]

bottom_left = [str(coord) for coord in bounds[:2]]
top_right = [str(coord) for coord in bounds[2:]]

bbox = ','.join([*bottom_left, *top_right])
return bbox


def _should_use_bbox(shape: BaseGeometry):
"""
If the passed shape is a polygon, and if that polygon
is equivalent to it's bounding box (if it's a rectangle),
we should use the bounding box to search instead
"""
if isinstance(shape, Polygon):
coords = [
[shape.bounds[0], shape.bounds[1]],
[shape.bounds[2], shape.bounds[1]],
[shape.bounds[2], shape.bounds[3]],
[shape.bounds[0], shape.bounds[3]],
]
return shape.equals(Polygon(shell=coords))

return False
Loading