Skip to content
This repository was archived by the owner on May 23, 2024. It is now read-only.

Commit 68102a2

Browse files
authored
Merge pull request #5 from johntruckenbrodt/master
restructuring into Python package
2 parents d53e0d2 + 5d57449 commit 68102a2

File tree

10 files changed

+91
-52
lines changed

10 files changed

+91
-52
lines changed

LICENSE.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright (c) 2017, Jonas Eberle
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4+
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
5+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
6+
persons to whom the Software is furnished to do so, subject to the following conditions:
7+
8+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9+
10+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
11+
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
12+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
13+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include sentinel_api/examples/*

README.md

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,38 +29,42 @@ https://scihub.copernicus.eu/twiki/do/view/SciHubUserGuide/3FullTextSearch#Searc
2929

3030
Example:
3131

32-
import sentinel_api as api
33-
34-
# use username and password for ESA DATA Hub authentication
35-
username = '****YOUR_ESA_DATA_HUB_USERNAME****'
36-
password = '****YOUR_ESA_DATA_HUB_PASSWORD****'
37-
38-
# please also specify the Hub URL:
39-
# All Sentinel-1 and -2 scenes beginning from 15th Nov. 2015: https://scihub.copernicus.eu/apihub/
40-
# All historic Sentinel-1 scenes: https://scihub.copernicus.eu/dhus/
41-
s1 = api.SentinelDownloader(username, password, api_url='https://scihub.copernicus.eu/apihub/')
42-
43-
# set directory for
44-
# - filter scenes list with existing files
45-
# - set directory path for data download
46-
s1.set_download_dir('./')
47-
48-
# load geometries from shapefile
49-
s1.load_sites('wetlands_v8.shp')
50-
51-
# search for scenes with some restrictions (e.g., minimum overlap 1%)
52-
s1.search('S1A*', min_overlap=0.01, start_date="2015-12-01", date_type="beginPosition", productType='GRD', sensoroperationalmode='IW')
53-
54-
# add another search query (e.g., for Sentinel-1B); both search results will be merged
55-
s1.search('S1B*', min_overlap=0.01, start_date="2015-12-01", date_type="beginPosition", productType='GRD', sensoroperationalmode='IW')
56-
57-
# you can either write results to a bash file for wget or download files directly in this script
58-
# s1.write_results('wget', 'sentinel_api_s1_download.sh')
59-
s1.download_all()
32+
```Python
33+
import sentinel_api as api
34+
35+
# use username and password for ESA DATA Hub authentication
36+
username = '****YOUR_ESA_DATA_HUB_USERNAME****'
37+
password = '****YOUR_ESA_DATA_HUB_PASSWORD****'
38+
39+
# please also specify the Hub URL:
40+
# All Sentinel-1 and -2 scenes beginning from 15th Nov. 2015: https://scihub.copernicus.eu/apihub/
41+
# All historic Sentinel-1 scenes: https://scihub.copernicus.eu/dhus/
42+
s1 = api.SentinelDownloader(username, password, api_url='https://scihub.copernicus.eu/apihub/')
43+
44+
# set directory for
45+
# - filter scenes list with existing files
46+
# - set directory path for data download
47+
s1.set_download_dir('./')
48+
49+
# load geometries from shapefile
50+
s1.load_sites('wetlands_v8.shp')
51+
52+
# search for scenes with some restrictions (e.g., minimum overlap 1%)
53+
s1.search('S1A*', min_overlap=0.01, start_date='2015-12-01', date_type='beginPosition', productType='GRD', sensoroperationalmode='IW')
54+
55+
# add another search query (e.g., for Sentinel-1B); both search results will be merged
56+
s1.search('S1B*', min_overlap=0.01, start_date='2015-12-01', date_type='beginPosition', productType='GRD', sensoroperationalmode='IW')
57+
58+
# you can either write results to a bash file for wget or download files directly in this script
59+
# s1.write_results('wget', 'sentinel_api_s1_download.sh')
60+
s1.download_all()
61+
```
6062

6163
Help
6264
-----------
6365
For now, please see the docstrings for each method within the code or within python
64-
65-
import sentinel_api as api
66-
help(api)
66+
67+
```Python
68+
import sentinel_api as api
69+
help(api)
70+
```

requirements.txt

Lines changed: 0 additions & 4 deletions
This file was deleted.

sentinel_api/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .sentinel_api import SentinelDownloader
File renamed without changes.
File renamed without changes.
File renamed without changes.

sentinel_api.py renamed to sentinel_api/sentinel_api.py

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ def search(self, platform, min_overlap=0, download_dir=None, start_date=None, en
147147
'ingestionDate') (Default: beginPosition)
148148
**keywords: Further OpenSearch arguments can be passed to the query according to the ESA Data Hub Handbook
149149
(please see https://scihub.copernicus.eu/twiki/do/view/SciHubUserGuide/3FullTextSearch#Search_Keywords)
150+
missing under this link:
151+
- slicenumber: the graticule along an orbit; particularly important for interferometric applications
152+
to identify overlapping scene pairs
150153
151154
Mandatory args:
152155
platform
@@ -200,15 +203,15 @@ def search(self, platform, min_overlap=0, download_dir=None, start_date=None, en
200203
if len(subscenes) < 100:
201204
break
202205

203-
print '%s scenes after initial search' % len(scenes)
206+
print('%s scenes after initial search' % len(scenes))
204207
if len(scenes) > 0:
205208
scenes = self._filter_existing(scenes)
206209
scenes = self._filter_overlap(scenes, geom, min_overlap)
207-
print '%s scenes after filtering before merging' % len(scenes)
210+
print('%s scenes after filtering before merging' % len(scenes))
208211
self.__scenes = self._merge_scenes(self.__scenes, scenes)
209212

210213
print('===========================================================')
211-
print '%s total scenes after merging' % len(self.__scenes)
214+
print('%s total scenes after merging' % len(self.__scenes))
212215
print('===========================================================')
213216

214217
def get_scenes(self):
@@ -221,7 +224,7 @@ def print_scenes(self):
221224
def sorter(x): return re.findall('[0-9T]{15}', x)[0]
222225

223226
titles = sorted([x['title'] for x in self.__scenes], key=sorter)
224-
print '\n'.join(titles)
227+
print('\n'.join(titles))
225228

226229
def write_results(self, file_type, filename, output=False):
227230
"""Write results to disk in different kind of formats
@@ -271,16 +274,16 @@ def download_all(self, download_dir=None):
271274
try:
272275
response = requests.get(url, auth=(self.__esa_username, self.__esa_password), stream=True)
273276
except requests.exceptions.ConnectionError:
274-
print 'Connection Error'
277+
print('Connection Error')
275278
continue
276279
if 'Content-Length' not in response.headers:
277-
print 'Content-Length not found'
278-
print url
280+
print('Content-Length not found')
281+
print(url)
279282
continue
280283
size = int(response.headers['Content-Length'].strip())
281284
if size < 1000000:
282-
print 'The found scene is to small: %s (%s)' % (scene['title'], size)
283-
print url
285+
print('The found scene is to small: %s (%s)' % (scene['title'], size))
286+
print(url)
284287
continue
285288

286289
print('Size of the scene: %s MB' % (size / 1024 / 1024)) # show in MegaBytes
@@ -305,7 +308,7 @@ def download_all(self, download_dir=None):
305308
sys.exit(0)
306309

307310
# Check if file is valid
308-
print "Check if file is valid: "
311+
print("Check if file is valid: ")
309312
valid = self._is_valid(path)
310313

311314
if not valid:
@@ -330,18 +333,20 @@ def _is_valid(self, zipfile, minsize=1000000):
330333
if not os.path.getsize(zipfile) > minsize:
331334
print('The downloaded scene is too small: {}'.format(os.path.basename(zipfile)))
332335
return False
333-
archive = zf.ZipFile(zipfile, 'r')
334336
try:
335-
corrupt = archive.testzip()
336-
except zlib.error:
337-
corrupt = zipfile
338-
archive.close()
337+
archive = zf.ZipFile(zipfile, 'r')
338+
try:
339+
corrupt = True if archive.testzip() else False
340+
except zlib.error:
341+
corrupt = True
342+
archive.close()
343+
except zf.BadZipfile:
344+
corrupt = True
339345
if corrupt:
340346
print('The downloaded scene is corrupt: {}'.format(os.path.basename(zipfile)))
341-
return False
342347
else:
343348
print('file seems to be valid.')
344-
return True
349+
return not corrupt
345350

346351
def _format_url(self, startindex, wkt_geometry, platform, date_filtering, **keywords):
347352
"""Format the search URL based on the arguments

setup.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from setuptools import setup, find_packages
2+
3+
setup(name='sentinel_api',
4+
packages=find_packages(),
5+
include_package_data=True,
6+
version='0.5.2',
7+
description='ESA Sentinel Search & Download API',
8+
classifiers=[
9+
'Programming Language :: Python :: 2.7',
10+
],
11+
install_requires=['GDAL>=1.11.3',
12+
'Shapely>=1.5.13',
13+
'progressbar==2.3',
14+
'requests>=2.8.1'],
15+
url='https://github.com/jonas-eberle/esa_sentinel.git',
16+
author='Jonas Eberle, John Truckenbrodt, Felix Cremer',
17+
18+
license='MIT',
19+
zip_safe=False)

0 commit comments

Comments
 (0)