From 2a38415181908f976e731d7be303795a28f7c12c Mon Sep 17 00:00:00 2001 From: kim Date: Wed, 14 Feb 2024 16:41:32 -0900 Subject: [PATCH 1/3] passed unwrapped wkt through when passed a rectangular aoi for bbox calculation --- asf_search/WKT/validate_wkt.py | 4 ++-- asf_search/search/search_generator.py | 26 ++++++++++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/asf_search/WKT/validate_wkt.py b/asf_search/WKT/validate_wkt.py index 6a8f7681..cad67b24 100644 --- a/asf_search/WKT/validate_wkt.py +++ b/asf_search/WKT/validate_wkt.py @@ -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 @@ -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: diff --git a/asf_search/search/search_generator.py b/asf_search/search/search_generator.py index 090182db..82ebb132 100644 --- a/asf_search/search/search_generator.py +++ b/asf_search/search/search_generator.py @@ -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 @@ -82,7 +83,17 @@ def search_generator( if opts.dataset is not None and opts.platform is not None: raise ValueError("Cannot use dataset along with platform keyword in search.") - + + # if opts.dataset is not None and opts.platform is not None: + # raise ValueError("Cannot use dataset along with platform keyword in search.") + if opts.intersectsWith is not None: + wrapped, unwrapped = fix_wkt(opts=opts) + if should_use_bbox(wrapped): + opts.intersectsWith = unwrapped.wkt + else: + opts.intersectsWith = wrapped.wkt + + preprocess_opts(opts) url = '/'.join(s.strip('/') for s in [f'https://{opts.host}', f'{INTERNAL.CMR_GRANULE_PATH}']) @@ -170,7 +181,7 @@ def get_page(session: ASFSession, url: str, translated_opts: List) -> Response: def preprocess_opts(opts: ASFSearchOptions): # Repair WKT here so it only happens once, and you can save the result to the new Opts object: - wrap_wkt(opts=opts) + # wrap_wkt(opts=opts) # Date/Time logic, convert "today" to the literal timestamp if needed: set_default_dates(opts=opts) @@ -178,11 +189,14 @@ def preprocess_opts(opts: ASFSearchOptions): # Platform Alias logic: set_platform_alias(opts=opts) +def fix_wkt(opts: ASFSearchOptions): + wrapped, unwrapped, _ = validate_wkt(opts.intersectsWith) + return wrapped, unwrapped +# def wrap_wkt(opts: ASFSearchOptions): +# if opts.intersectsWith is not None: +# wrapped, _, __ = validate_wkt(opts.intersectsWith) +# opts.intersectsWith = wrapped.wkt -def wrap_wkt(opts: ASFSearchOptions): - if opts.intersectsWith is not None: - wrapped, _, __ = validate_wkt(opts.intersectsWith) - opts.intersectsWith = wrapped.wkt def set_default_dates(opts: ASFSearchOptions): From fbe26c65d84fbdc11478941e11e40125fddaf5f7 Mon Sep 17 00:00:00 2001 From: kim Date: Thu, 15 Feb 2024 09:55:44 -0900 Subject: [PATCH 2/3] updates changelog, wkt test case uses unwrapped wkt when bbox optimzation used --- CHANGELOG.md | 5 +++++ tests/ASFSearchResults/test_ASFSearchResults.py | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4526737..6a91a523 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,11 @@ 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 +- Use unwrapped wkt when rectangular AOI provided for bbox calculation + ------ ## [v7.0.4](https://github.com/asfadmin/Discovery-asf_search/compare/v7.0.3...v7.0.4) ### Changed diff --git a/tests/ASFSearchResults/test_ASFSearchResults.py b/tests/ASFSearchResults/test_ASFSearchResults.py index 357d6607..33f40ff5 100644 --- a/tests/ASFSearchResults/test_ASFSearchResults.py +++ b/tests/ASFSearchResults/test_ASFSearchResults.py @@ -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}" From 08b94901323f4fddf792eb52a1267139881f1571 Mon Sep 17 00:00:00 2001 From: kim Date: Fri, 16 Feb 2024 14:02:44 -0900 Subject: [PATCH 3/3] cleans up some opts processing logic, updates changelog --- CHANGELOG.md | 4 ++- asf_search/search/search_generator.py | 37 ++++++++++----------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a91a523..4e4ac620 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,9 @@ 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 -- Use unwrapped wkt when rectangular AOI provided for bbox calculation +- 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) diff --git a/asf_search/search/search_generator.py b/asf_search/search/search_generator.py index 82ebb132..5632ade4 100644 --- a/asf_search/search/search_generator.py +++ b/asf_search/search/search_generator.py @@ -81,19 +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.") - - # if opts.dataset is not None and opts.platform is not None: - # raise ValueError("Cannot use dataset along with platform keyword in search.") - if opts.intersectsWith is not None: - wrapped, unwrapped = fix_wkt(opts=opts) - if should_use_bbox(wrapped): - opts.intersectsWith = unwrapped.wkt - else: - opts.intersectsWith = wrapped.wkt - - preprocess_opts(opts) url = '/'.join(s.strip('/') for s in [f'https://{opts.host}', f'{INTERNAL.CMR_GRANULE_PATH}']) @@ -180,23 +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 fix_wkt(opts: ASFSearchOptions): - wrapped, unwrapped, _ = validate_wkt(opts.intersectsWith) - return wrapped, unwrapped -# def wrap_wkt(opts: ASFSearchOptions): -# if opts.intersectsWith is not None: -# wrapped, _, __ = validate_wkt(opts.intersectsWith) -# opts.intersectsWith = wrapped.wkt - +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, 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):