Skip to content

Commit 226fced

Browse files
authored
s1_orbit.get_orbit_file_from_dir(): add auto_download arg (#71)
+ s1_orbit.get_orbit_file_from_dir(): add `auto_download` arg to automatically download the orbit file if not found + s1_orbit: remove the unused get_orbit_file_from_list() + utils.plot_bursts.py: switch to get_orbit_file_from_dir()
1 parent 71e2c9e commit 226fced

File tree

2 files changed

+65
-72
lines changed

2 files changed

+65
-72
lines changed

src/s1reader/s1_orbit.py

Lines changed: 53 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
scihub_password = 'gnssguest'
1616

1717

18-
def download_orbit(safe_file, orbit_dir):
18+
def download_orbit(safe_file: str, orbit_dir: str):
1919
'''
2020
Download orbits for S1-A/B SAFE "safe_file"
2121
@@ -25,6 +25,11 @@ def download_orbit(safe_file, orbit_dir):
2525
File path to SAFE file for which download the orbits
2626
orbit_dir: str
2727
File path to directory where to store downloaded orbits
28+
29+
Returns:
30+
--------
31+
orbit_file : str
32+
Path to the orbit file.
2833
'''
2934

3035
# Create output directory & check internet connection
@@ -42,9 +47,11 @@ def download_orbit(safe_file, orbit_dir):
4247
orbit_dict = get_orbit_dict(sensor_id, start_time,
4348
end_time, 'AUX_RESORB')
4449
# Download orbit file
45-
filename = os.path.join(orbit_dir, orbit_dict["orbit_name"])
46-
if not os.path.exists(filename):
47-
download_orbit_file(orbit_dir, orbit_dict['orbit_url'])
50+
orbit_file = os.path.join(orbit_dir, orbit_dict["orbit_name"] + '.EOF')
51+
if not os.path.exists(orbit_file):
52+
download_orbit_file(orbit_dir, orbit_dict['orbit_url'])
53+
54+
return orbit_file
4855

4956

5057
def check_internet_connection():
@@ -168,15 +175,22 @@ def download_orbit_file(output_folder, orbit_url):
168175
orbit_url: str
169176
Remote url of orbit file to download
170177
'''
171-
178+
print('downloading URL:', orbit_url)
172179
response = requests.get(url=orbit_url, auth=(scihub_user, scihub_password))
180+
173181
# Get header and find filename
174182
header = response.headers['content-disposition']
175-
_, header_params = cgi.parse_header(header)
183+
header_params = cgi.parse_header(header)[1]
176184
# construct orbit filename
177-
orbit_filename = os.path.join(output_folder, header_params['filename'])
185+
orbit_file = os.path.join(output_folder, header_params['filename'])
186+
178187
# Save orbits
179-
open(orbit_filename, 'wb').write(response.content)
188+
with open(orbit_file, 'wb') as f:
189+
for chunk in response.iter_content(chunk_size=1024):
190+
if chunk:
191+
f.write(chunk)
192+
f.flush()
193+
return orbit_file
180194

181195

182196
def get_file_name_tokens(zip_path: str) -> [str, list[datetime.datetime]]:
@@ -204,35 +218,43 @@ def get_file_name_tokens(zip_path: str) -> [str, list[datetime.datetime]]:
204218
# lambda to check if file exists if desired sat_id in basename
205219
item_valid = lambda item, sat_id: os.path.isfile(item) and sat_id in os.path.basename(item)
206220

207-
208-
def get_orbit_file_from_list(zip_path: str, orbit_file_list: list[str]) -> str:
221+
def get_orbit_file_from_dir(zip_path: str, orbit_dir: str, auto_download: bool = False) -> str:
209222
'''Get orbit state vector list for a given swath.
210223
211224
Parameters:
212225
-----------
213226
zip_path : string
214-
Path to Sentinel1 SAFE zip file. File names required to adhere to the
227+
Path to Sentinel1 SAFE zip file. Base names required to adhere to the
215228
format described here:
216229
https://sentinel.esa.int/web/sentinel/user-guides/sentinel-1-sar/naming-conventions
217-
orbit_file_list: list[str]
218-
List containing orbit files paths. Orbit files required to adhere to
219-
naming convention found here:
230+
orbit_dir : string
231+
Path to directory containing orbit files. Orbit files required to adhere
232+
to naming convention found here:
220233
https://s1qc.asf.alaska.edu/aux_poeorb/
234+
auto_download : bool
235+
Automatically download the orbit file if not exist in the orbit_dir.
221236
222237
Returns:
223238
--------
224-
orbit_path : str
225-
Path the orbit file.
239+
orbit_file : str
240+
Path to the orbit file.
226241
'''
242+
243+
# check the existence of input file path and directory
227244
if not os.path.exists(zip_path):
228245
raise FileNotFoundError(f"{zip_path} does not exist")
229246

230-
if not orbit_file_list:
231-
raise ValueError("no orbit paths provided")
247+
if not os.path.isdir(orbit_dir):
248+
raise NotADirectoryError(f"{orbit_dir} not found")
232249

233250
# extract platform id, start and end times from swath file name
234251
platform_id, t_swath_start_stop = get_file_name_tokens(zip_path)
235252

253+
# initiate output
254+
orbit_file = ''
255+
256+
# search for orbit file
257+
orbit_file_list = glob.glob(os.path.join(orbit_dir, 'S1*.EOF'))
236258
for orbit_file in orbit_file_list:
237259
# check if file validity
238260
if not item_valid(orbit_file, platform_id):
@@ -245,50 +267,23 @@ def get_orbit_file_from_list(zip_path: str, orbit_file_list: list[str]) -> str:
245267
t_orbit_start = datetime.datetime.strptime(t_orbit_start[1:], FMT)
246268

247269
# string '.EOF' from end of end time string
248-
t_orbit_end = datetime.datetime.strptime(t_orbit_end[:-4], FMT)
270+
t_orbit_stop = datetime.datetime.strptime(t_orbit_end[:-4], FMT)
249271

250272
# check if:
251273
# 1. swath start and stop time > orbit file start time
252274
# 2. swath start and stop time < orbit file stop time
253-
if all([t > t_orbit_start for t in t_swath_start_stop]) and \
254-
all([t < t_orbit_end for t in t_swath_start_stop]):
255-
return orbit_file
256-
257-
msg = f'No orbit file found for {os.path.basename(zip_path)}!'
258-
msg += f'\nOrbit directory: {os.path.dirname(orbit_file_list[0])}'
259-
warnings.warn(msg)
260-
261-
return ''
275+
if all([t_orbit_start < t < t_orbit_stop for t in t_swath_start_stop]):
276+
break
277+
else:
278+
orbit_file = ''
262279

263-
def get_orbit_file_from_dir(path: str, orbit_dir: str) -> str:
264-
'''Get orbit state vector list for a given swath.
265-
266-
Parameters:
267-
-----------
268-
path : string
269-
Path to Sentinel1 SAFE zip file. Base names required to adhere to the
270-
format described here:
271-
https://sentinel.esa.int/web/sentinel/user-guides/sentinel-1-sar/naming-conventions
272-
orbit_dir : string
273-
Path to directory containing orbit files. Orbit files required to adhere
274-
to naming convention found here:
275-
https://s1qc.asf.alaska.edu/aux_poeorb/
276-
277-
Returns:
278-
--------
279-
orbit_path : str
280-
Path the orbit file.
281-
'''
282-
if not os.path.exists(path):
283-
raise FileNotFoundError(f"{path} does not exist")
284-
285-
if not os.path.isdir(orbit_dir):
286-
raise NotADirectoryError(f"{orbit_dir} not found")
287-
288-
orbit_file_list = glob.glob(os.path.join(orbit_dir, 'S1*.EOF'))
289-
if not orbit_file_list:
290-
raise FileNotFoundError(f'No S1*.EOF file found in directory: {orbit_dir}')
280+
if not orbit_file:
281+
if auto_download:
282+
orbit_file = download_orbit(zip_path, orbit_dir)
291283

292-
orbit_path = get_orbit_file_from_list(path, orbit_file_list)
284+
else:
285+
msg = f'No orbit file found for {os.path.basename(zip_path)}!'
286+
msg += f'\nOrbit directory: {orbit_dir}'
287+
warnings.warn(msg)
293288

294-
return orbit_path
289+
return orbit_file

src/s1reader/utils/plot_bursts.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import argparse
2-
import glob
3-
from importlib import import_module
42
import os
53
import sys
4+
from importlib import import_module
65

76
named_libs = [('fiona', 'fiona'), ('geopandas', 'gpd'), ('pandas', 'pd')]
87

@@ -18,7 +17,7 @@
1817
from shapely.geometry import Polygon
1918
from shapely import wkt
2019

21-
from s1reader.s1_orbit import get_orbit_file_from_list
20+
from s1reader.s1_orbit import get_orbit_file_from_dir
2221
from s1reader.s1_reader import load_bursts
2322

2423

@@ -79,8 +78,7 @@ def burst_map(slc, orbit_dir, x_spacing,
7978
'border':[]}
8079
i_subswath = [1, 2, 3]
8180
pol = 'vv'
82-
orbit_list = glob.glob(f'{orbit_dir}/*EOF')
83-
orbit_path = get_orbit_file_from_list(slc, orbit_list)
81+
orbit_path = get_orbit_file_from_dir(slc, orbit_dir)
8482

8583
for subswath in i_subswath:
8684
ref_bursts = load_bursts(slc, orbit_path, subswath, pol)
@@ -116,15 +114,15 @@ def burst_map(slc, orbit_dir, x_spacing,
116114
tgt_y.append(dummy_y)
117115

118116
if epsg == 4326:
119-
x_min = x_spacing * (min(tgt_x) / x_spacing)
120-
y_min = y_spacing * (min(tgt_y) / y_spacing)
121-
x_max = x_spacing * (max(tgt_x) / x_spacing)
122-
y_max = y_spacing * (max(tgt_y) / y_spacing)
117+
x_min = x_spacing * (min(tgt_x) / x_spacing)
118+
y_min = y_spacing * (min(tgt_y) / y_spacing)
119+
x_max = x_spacing * (max(tgt_x) / x_spacing)
120+
y_max = y_spacing * (max(tgt_y) / y_spacing)
123121
else:
124-
x_min = x_spacing * round(min(tgt_x) / x_spacing)
125-
y_min = y_spacing * round(min(tgt_y) / y_spacing)
126-
x_max = x_spacing * round(max(tgt_x) / x_spacing)
127-
y_max = y_spacing * round(max(tgt_y) / y_spacing)
122+
x_min = x_spacing * round(min(tgt_x) / x_spacing)
123+
y_min = y_spacing * round(min(tgt_y) / y_spacing)
124+
x_max = x_spacing * round(max(tgt_x) / x_spacing)
125+
y_max = y_spacing * round(max(tgt_y) / y_spacing)
128126

129127
# Allocate coordinates inside the dictionary
130128
burst_map['min_x'].append(x_min)
@@ -148,7 +146,7 @@ def burst_map(slc, orbit_dir, x_spacing,
148146
# Save the GeoDataFrame as a kml
149147
kml_path = f'{output_filename}.kml'
150148
if os.path.isfile(kml_path):
151-
os.remove(kml_path)
149+
os.remove(kml_path)
152150

153151
fiona.supported_drivers['KML'] = 'rw'
154152
gdf.to_file(f'{output_filename}.kml', driver='KML')

0 commit comments

Comments
 (0)