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

Unwrapped WKT for BBOX, Dataset+Platform Keyword Support #275

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-

-->
------
## [v7.0.5](https://github.com/asfadmin/Discovery-asf_search/compare/v7.0.4...v7.0.5)
### Fixed
- Unwrapped WKT used in bounding box calculation when searching rectangular AOI
### Changed
- `dataset` and `platform` search keywords can now be used at the same time

------
## [v7.0.4](https://github.com/asfadmin/Discovery-asf_search/compare/v7.0.3...v7.0.4)
### Changed
Expand Down
4 changes: 2 additions & 2 deletions asf_search/WKT/validate_wkt.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from asf_search.exceptions import ASFWKTError


def validate_wkt(aoi: Union[str, BaseGeometry]) -> Tuple[BaseGeometry, List[RepairEntry]]:
def validate_wkt(aoi: Union[str, BaseGeometry]) -> Tuple[BaseGeometry, BaseGeometry, List[RepairEntry]]:
"""
Param aoi: the WKT string or Shapely Geometry to validate and prepare for the CMR query
Validates the given area of interest, and returns a validated and simplified WKT string
Expand Down Expand Up @@ -52,7 +52,7 @@ def _search_wkt_prep(shape: BaseGeometry):
if isinstance(shape, Polygon):
return orient(Polygon(shape.exterior), sign=1.0)

def _simplify_geometry(geometry: BaseGeometry) -> Tuple[BaseGeometry, List[RepairEntry]]:
def _simplify_geometry(geometry: BaseGeometry) -> Tuple[BaseGeometry, BaseGeometry, List[RepairEntry]]:
"""
param geometry: AOI Shapely Geometry to be prepped for CMR
prepares geometry for CMR by:
Expand Down
23 changes: 14 additions & 9 deletions asf_search/search/search_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from asf_search.ASFSession import ASFSession
from asf_search.ASFProduct import ASFProduct
from asf_search.CMR.translate import should_use_bbox
from asf_search.exceptions import ASFSearch4xxError, ASFSearch5xxError, ASFSearchError, CMRIncompleteError
from asf_search.constants import INTERNAL
from asf_search.WKT.validate_wkt import validate_wkt
Expand Down Expand Up @@ -80,9 +81,6 @@ def search_generator(
(getattr(opts, 'granule_list', False) or getattr(opts, 'product_list', False)):
raise ValueError("Cannot use maxResults along with product_list/granule_list.")

if opts.dataset is not None and opts.platform is not None:
raise ValueError("Cannot use dataset along with platform keyword in search.")

preprocess_opts(opts)

url = '/'.join(s.strip('/') for s in [f'https://{opts.host}', f'{INTERNAL.CMR_GRANULE_PATH}'])
Expand Down Expand Up @@ -169,20 +167,27 @@ def get_page(session: ASFSession, url: str, translated_opts: List) -> Response:


def preprocess_opts(opts: ASFSearchOptions):
"""Sets the appropriate WKT to pass along, sets default timezones + start/end order check, and transforms platform aliases to actual values"""
# Repair WKT here so it only happens once, and you can save the result to the new Opts object:
wrap_wkt(opts=opts)

select_wkt(opts=opts)
# Date/Time logic, convert "today" to the literal timestamp if needed:
set_default_dates(opts=opts)

# Platform Alias logic:
set_platform_alias(opts=opts)


def wrap_wkt(opts: ASFSearchOptions):
def select_wkt(opts: ASFSearchOptions):
"""Validates the provided WKT, and chooses the appropriate version to use (wrapped or unwrapped)
- If we should use the bbox, we pass the unwrapped wkt (this will be used when building the bounding box)
- Otherwise, we pass the wrapped wkt
"""
if opts.intersectsWith is not None:
wrapped, _, __ = validate_wkt(opts.intersectsWith)
opts.intersectsWith = wrapped.wkt
wrapped, unwrapped, _ = validate_wkt(opts.intersectsWith)
if should_use_bbox(wrapped):
opts.intersectsWith = unwrapped.wkt
else:
opts.intersectsWith = wrapped.wkt


def set_default_dates(opts: ASFSearchOptions):
Expand Down
5 changes: 4 additions & 1 deletion tests/ASFSearchResults/test_ASFSearchResults.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,7 @@ def overlap_check(s1: BaseGeometry, s2: BaseGeometry):
product_geom_wrapped, product_geom_unwrapped, _ = asf.validate_wkt(shape(product.geometry))
original_shape = unchanged_aoi

assert overlap_check(product_geom_wrapped, wrapped) or overlap_check(product_geom_wrapped, original_shape), f"OVERLAP FAIL: {product.properties['sceneName']}, {product.geometry} \nproduct: {product_geom_wrapped.wkt} \naoi: {wrapped.wkt}"
if asf.translate.should_use_bbox(original_shape):
assert overlap_check(product_geom_unwrapped, unwrapped) or overlap_check(product_geom_unwrapped, original_shape), f"OVERLAP FAIL: {product.properties['sceneName']}, {product.geometry} \nproduct: {product_geom_wrapped.wkt} \naoi: {wrapped.wkt}"
else:
assert overlap_check(product_geom_wrapped, wrapped) or overlap_check(product_geom_wrapped, original_shape), f"OVERLAP FAIL: {product.properties['sceneName']}, {product.geometry} \nproduct: {product_geom_wrapped.wkt} \naoi: {wrapped.wkt}"
Loading