Skip to content

Commit 75c0f89

Browse files
Merge pull request #42 from asfadmin/test
v1.0.4
2 parents 53ff6b1 + 4683cc2 commit 75c0f89

5 files changed

Lines changed: 120 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,50 @@ and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
2727
-->
2828
------
2929
## [1.0.4](https://github.com/asfadmin/Discovery-SearchAPI-v3/compare/v1.0.3...v1.0.4)
30+
### Added
31+
- Added experimental ARIA S1 GUNW baseline stacking support
32+
- requires: `dataset` keyword be set to "ARIA S1 GUNW" and using the desired frame as the `reference`
33+
- returns json object list partially formatted for submitting jobs to ASF's On Demand processing.
34+
``` json
35+
[
36+
{
37+
"date": "2025-06-04T00:26:25Z",
38+
"products": [
39+
"S1A_IW_SLC__1SDV_20250604T002649_20250604T002716_059489_076290_7E0F",
40+
"S1A_IW_SLC__1SDV_20250604T002625_20250604T002651_059489_076290_7FE0"
41+
],
42+
"group_granule_idx": 0,
43+
"perpendicularBaseline": 0,
44+
"temporalBaseline": 0
45+
},
46+
{
47+
"date": "2025-05-23T00:26:25Z",
48+
"products": [
49+
"S1A_IW_SLC__1SDV_20250523T002650_20250523T002717_059314_075C80_5A5D",
50+
"S1A_IW_SLC__1SDV_20250523T002625_20250523T002652_059314_075C80_BBE7"
51+
],
52+
"group_granule_idx": 0,
53+
"perpendicularBaseline": 47,
54+
"temporalBaseline": -12
55+
},
56+
57+
...
58+
59+
{
60+
"date": "2014-10-12T00:25:42Z",
61+
"products": [
62+
"S1A_IW_SLC__1SSV_20141012T002607_20141012T002634_002789_00323B_2DB9",
63+
"S1A_IW_SLC__1SSV_20141012T002542_20141012T002609_002789_00323B_0E9F"
64+
],
65+
"group_granule_idx": 0,
66+
"perpendicularBaseline": -160,
67+
"temporalBaseline": -3888
68+
}
69+
]
70+
```
3071
### Changed
31-
- bumped asf-search to 9.0.0 for nisar search types, browse images, and UAT collections
72+
- bumped asf-search to 9.0.2 for nisar search types, browse images, and UAT collections, `productionConfiguration` list support, bbox validation, opera-disp jsonlite outputs
73+
3274

3375
------
3476
## [1.0.3](https://github.com/asfadmin/Discovery-SearchAPI-v3/compare/v1.0.2...v1.0.3)

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ ujson==5.7.0
2222
uvicorn==0.21.1
2323
watchfiles==0.19.0
2424

25-
asf_search==9.0.0
25+
asf_search==9.0.2
2626
python-json-logger==2.0.7
2727

2828
pyshp==2.1.3

src/SearchAPI/application/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
from .output import *
33
from .logger import *
44
from .log_router import *
5+
from .search import *
56
from .application import *

src/SearchAPI/application/application.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
from .asf_opts import process_baseline_request, process_search_request, process_wkt_request
1616
from .health import get_cmr_health
1717
from .models import BaselineSearchOptsModel, SearchOptsModel
18-
from .output import as_output, get_asf_search_script
18+
from .output import as_output, get_asf_search_script, make_filename
1919
from .files_to_wkt import FilesToWKT
2020
from . import constants
21+
from .search import stack_aria_gunw
2122
import time
2223

2324

@@ -93,8 +94,19 @@ async def query_baseline(searchOptions: BaselineSearchOptsModel = Depends(proces
9394
output = searchOptions.output
9495
reference = searchOptions.reference
9596
request_method = searchOptions.request_method
96-
# Load the reference scene:
9797

98+
if searchOptions.opts.dataset is not None:
99+
if searchOptions.opts.dataset[0] == asf.DATASET.ARIA_S1_GUNW:
100+
return JSONResponse(
101+
content=stack_aria_gunw(reference),
102+
status_code=200,
103+
headers= {
104+
**constants.DEFAULT_HEADERS,
105+
'Content-Disposition': f"attachment; filename={make_filename('json')}",
106+
}
107+
)
108+
# Load the reference scene:
109+
98110
if output.lower() == 'python':
99111
file_name, search_script = get_asf_search_script(opts, reference=reference, search_endpoint='baseline')
100112

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from collections import defaultdict
2+
3+
import dateparser
4+
import asf_search as asf
5+
from shapely.wkt import dumps as dump_to_wkt
6+
from shapely import Polygon
7+
8+
def stack_aria_gunw(frame: str):
9+
reference = asf.search(frame=int(frame), dataset=asf.DATASET.ARIA_S1_GUNW, maxResults=1)[0]
10+
11+
opts = asf.ASFSearchOptions(
12+
relativeOrbit=reference.properties['pathNumber'],
13+
processingLevel=asf.PRODUCT_TYPE.SLC,
14+
dataset=asf.DATASET.SENTINEL1,
15+
beamMode='IW',
16+
polarization=['VV','VV+VH'],
17+
flightDirection=reference.properties['flightDirection'],
18+
intersectsWith=dump_to_wkt(Polygon(reference.geometry['coordinates'][0]))
19+
)
20+
21+
slc_stack = asf.search(opts=opts)
22+
23+
groups = defaultdict(list)
24+
for product in slc_stack:
25+
group_id = product.properties['platform'] + '_' + str(product.properties['orbit'])
26+
groups[group_id].append(product)
27+
# dateparser.parse(str(value))
28+
aria_groups = [
29+
{
30+
'date': min(dateparser.parse(product.properties['startTime']) for product in group),
31+
'products': [product for product in group],
32+
}
33+
for group in groups.values()
34+
]
35+
36+
# track group index on each product, naively choose first granule available
37+
for idx, group in enumerate(aria_groups):
38+
group_granule_idx = None
39+
for idy, product in enumerate(group['products']):
40+
product.properties['groupIDX'] = idx
41+
if group_granule_idx is None:
42+
if product.has_baseline():
43+
group_granule_idx = idy
44+
45+
group['group_granule_idx'] = group_granule_idx
46+
47+
48+
49+
stack = asf.ASFSearchResults([group['products'][group['group_granule_idx']] for group in aria_groups if group['group_granule_idx'] is not None])
50+
target_stack, warnings = asf.baseline.get_baseline_from_stack(reference, stack)
51+
for product in target_stack:
52+
group_idx = product.properties.pop('groupIDX')
53+
aria_groups[group_idx]['perpendicularBaseline'] = product.properties['perpendicularBaseline']
54+
aria_groups[group_idx]['temporalBaseline'] = product.properties['temporalBaseline']
55+
56+
for group in aria_groups:
57+
for idx, product in enumerate(group['products']):
58+
group['products'][idx] = product.properties['sceneName']
59+
group['date'] = group['date'].strftime('%Y-%m-%dT%H:%M:%SZ')
60+
61+
return aria_groups

0 commit comments

Comments
 (0)