-
Notifications
You must be signed in to change notification settings - Fork 4
/
__init__.py
363 lines (295 loc) · 12.2 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
"""geesarfetcher"""
__version__ = "0.3.7"
# LIBRARY IMPORTS
import ee
import warnings
from datetime import datetime, date, timedelta
import os
# LOCAL IMPORTS
from .api import generate_image
from .api import get_pixel_values
from .api import get_point_pixel_values
from .api import get_timestamps_from_pixel_values
from .api import per_date_saving
from .assertions import _fetch_assertions
from .assertions import _fetch_point_assertions
warnings.simplefilter(action="ignore")
warnings.filterwarnings("ignore")
if os.environ.get("READTHEDOCS") == None:
ee.Initialize()
def fetch(
top_left=None,
bottom_right=None,
coords=None,
start_date: datetime = date.today() - timedelta(days=365),
end_date: datetime = date.today(),
ascending: bool = True,
orbit_number: object = None,
scale: int = 20,
n_jobs: int = 8,
verbose: int = 0,
):
"""Fetches SAR data in the form of a dictionnary with image data as well as timestamps
Parameters
----------
top_left : tuple of float, optional
Top left coordinates (lon, lat) of the Region
bottom_right : tuple of float, optional
Bottom right coordinates (lon, lat) of the Region
coords : tuple of tuple of float or list of list of float, optional
If `top_left` and `bottom_right` are not specified, we expect `coords`
to be a list (resp. tuple) of the form ``[top_left, bottom_right]``
(resp. ``(top_left, bottom_right)``)
start_date : datetime.datetime, optional
First date of the time interval
end_date : datetime.datetime, optional
Last date of the time interval
ascending : boolean, optional
The trajectory to use when selecting data
orbit_number : int or str, optional
The orbit number to restrict the download to. If provided with an integer, the S1 temporal stack is filtered using the provided orbit number.
If provided with a string value, we expect one of these keywords:
- "max" for the orbit number with the highest number of image in the stack
- "min" for the orbit number with the smallest number of image in the stack
If ``None``, then no filter over the orbit number is applied.
scale : int, optional
Scale parameters of the getRegion() function. Defaulting at ``20``,
change it to change the scale of the final data points. The highest,
the lower the spatial resolution. Should be at least ``10``.
n_jobs : int, optional
Set the parallelisation factor (number of threads) for the GEE data
access process. Set to 1 if no parallelisation required.
verbose : int, optional
Verbosity mode (0: No info, 1: Info, 2: Detailed info, with added timestamp)
Returns
-------
`dict`
Dictionnary with four keys:
``"stacks"``
4-D array containing db intensity measure (`numpy.ndarray`),
``(height, width, pol_count, time_series_length)``
``"coordinates"``
3-D array containg coordinates where ``[:,:,0]`` provides
access to latitude and ``[:,:,1]`` provides access to
longitude, (`numpy.ndarray`), ``(height, width, 2)``
``"timestamps"``
list of acquisition timestamps of size (time_series_length,)
(`list of str`)
``"metadata"``
Dictionnary describing data for each axis of the stack and the
coordinates as well as the properties (orbit number, slice,
acquisition time...) of each image of the temporal stack
"""
_fetch_assertions(
top_left, bottom_right, coords, start_date, end_date, ascending, scale, n_jobs
)
pixel_values, properties = get_pixel_values(
top_left=top_left,
bottom_right=bottom_right,
coords=coords,
start_date=start_date,
end_date=end_date,
ascending=ascending,
orbit_number=orbit_number,
scale=scale,
n_jobs=n_jobs,
verbose=verbose,
)
timestamps = get_timestamps_from_pixel_values(pixel_values)
img, coordinates, properties = generate_image(
timestamps, pixel_values, properties, verbose=verbose
)
return {
"stack": img,
"timestamps": timestamps,
"coordinates": coordinates,
"metadata": {
"stack": {
"axis_0": "height",
"axis_1": "width",
"axis_2": "polarisations (0:VV, 1:VH)",
"axis_3": "timestamps",
},
"coordinates": {
"axis_0": "height",
"axis_1": "width",
"axis_2": "0:latitude; 1:longitude",
},
"properties": properties,
},
}
def fetch_point(
coords,
start_date: datetime = date.today() - timedelta(days=365),
end_date: datetime = date.today(),
ascending: bool = True,
orbit_number: object = None,
scale: int = 20,
n_jobs: int = 8,
verbose: int = 0,
):
"""Fetches SAR data from a single coordinate point in the form of a dictionnary with image data as well as timestamps
Parameters
----------
coords : tuple of float
Coordinates (lon, lat) of the point of interest
start_date : datetime.datetime, optional
First date of the time interval
end_date : datetime.datetime, optional
Last date of the time interval
ascending : boolean, optional
The trajectory to use when selecting data
orbit_number : int or str, optional
The orbit number to restrict the download to. If provided with an integer, the S1 temporal stack is filtered using the provided orbit number.
If provided with a string value, we expect one of these keywords:
- "max" for the orbit number with the highest number of image in the stack
- "min" for the orbit number with the smallest number of image in the stack
If ``None``, then no filter over the orbit number is applied.
scale : int, optional
Scale parameters of the getRegion() function. Defaulting at ``20``,
change it to change the scale of the final data points. The highest,
the lower the spatial resolution. Should be at least ``10``.
n_jobs : int, optional
Set the parallelisation factor (number of threads) for the GEE data
access process. Set to 1 if no parallelisation required.
verbose : int, optional
Verbosity mode (0: No info, 1: Info, 2: Detailed info, with added timestamp)
Returns
-------
`dict`
Dictionnary with four keys:
``"stack"``
4-D array containing db intensity measure (`numpy.ndarray`),
``(1, 1, pol_count, time_series_length)``
``"coordinates"``
3-D array containg coordinates where ``[:,:,0]`` provides
access to latitude and ``[:,:,1]`` provides access to
longitude, (`numpy.ndarray`), ``(1, 1, 2)``
``"timestamps"``
list of acquisition timestamps of size (time_series_length,)
(`list of str`)
``"metadata"``
Dictionnary describing data for each axis of the stack and the
coordinates as well as the properties (orbit number, slice,
acquisition tim....) of each point of the temporal stack
"""
_fetch_point_assertions(
coords, start_date, end_date, ascending, orbit_number, scale, n_jobs
)
pixel_values, properties = get_point_pixel_values(
coords=coords,
start_date=start_date,
end_date=end_date,
ascending=ascending,
orbit_number=orbit_number,
scale=scale,
n_jobs=n_jobs,
verbose=verbose,
)
timestamps = get_timestamps_from_pixel_values(pixel_values)
img, coordinates, properties = generate_image(timestamps, pixel_values, properties)
return {
"stack": img,
"timestamps": timestamps,
"coordinates": coordinates,
"metadata": {
"stack": {
"axis_0": "height",
"axis_1": "width",
"axis_2": "polarisations (0:VV, 1:VH)",
"axis_3": "timestamps",
},
"coordinates": {
"axis_0": "height",
"axis_1": "width",
"axis_2": "0:latitude; 1:longitude",
},
"properties": properties,
},
}
def fetch_and_save(
save_dir: str = None,
top_left=None,
bottom_right=None,
coords=None,
start_date: datetime = date.today() - timedelta(days=365),
end_date: datetime = date.today(),
ascending: bool = True,
orbit_number: object = None,
scale: int = 20,
n_jobs: int = 8,
verbose: int = 0,
):
"""Fetches SAR data by looping other each timestep and each generated subregion and saves extracted images as GeoTIFF in the supplied `save_dir` folder
Parameters
----------
save_dir: str
Path toward an *existing* directory where to save the images. If non-existing, an Exception is raised.
top_left : tuple of float, optional
Top left coordinates (lon, lat) of the Region
bottom_right : tuple of float, optional
Bottom right coordinates (lon, lat) of the Region
coords : tuple of tuple of float or list of list of float, optional
If `top_left` and `bottom_right` are not specified, we expect `coords`
to be a list (resp. tuple) of the form ``[top_left, bottom_right]``
(resp. ``(top_left, bottom_right)``)
start_date : datetime.datetime, optional
First date of the time interval
end_date : datetime.datetime, optional
Last date of the time interval
ascending : boolean, optional
The trajectory to use when selecting data
orbit_number : int or str, optional
The orbit number to restrict the download to. If provided with an integer, the S1 temporal stack is filtered using the provided orbit number.
If provided with a string value, we expect one of these keywords:
- "max" for the orbit number with the highest number of image in the stack
- "min" for the orbit number with the smallest number of image in the stack
If ``None``, then no filter over the orbit number is applied.
scale : int, optional
Scale parameters of the getRegion() function. Defaulting at ``20``,
change it to change the scale of the final data points. The highest,
the lower the spatial resolution. Should be at least ``10``.
n_jobs : int, optional
Set the parallelisation factor (number of threads) for the GEE data
access process. Set to 1 if no parallelisation required.
verbose : int, optional
Verbosity mode (0: No info, 1: Info, 2: Detailed info, with added timestamp)
Returns
-------
`dict`
Dictionnary with four keys:
``"stack"``
4-D array containing db intensity measure (`numpy.ndarray`),
``(height, width, pol_count, time_series_length)``
``"coordinates"``
3-D array containg coordinates where ``[:,:,0]`` provides
access to latitude and ``[:,:,1]`` provides access to
longitude, (`numpy.ndarray`), ``(height, width, 2)``
``"timestamps"``
list of acquisition timestamps of size (time_series_length,)
(`list of str`)
``"metadata"``
Dictionnary describing data for each axis of the stack, the
coordinates as well as the properties (orbit number, slice,
acquisition time....) of each image of the temporal stack
"""
if save_dir is None or os.path.exists(save_dir) == False:
raise ValueError(
"Unknown directory. If you do not want to save data as geotiff, please consider using the fetch method"
)
_fetch_assertions(
top_left, bottom_right, coords, start_date, end_date, ascending, scale, n_jobs
)
per_date_saving(
save_dir,
top_left,
bottom_right,
coords,
start_date,
end_date,
ascending,
orbit_number,
scale,
n_jobs,
verbose,
)