weatherdb 1.1.0__tar.gz → 1.1.2__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {weatherdb-1.1.0 → weatherdb-1.1.2}/.gitlab-ci.yml +1 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/CHANGES.md +10 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/PKG-INFO +2 -2
- {weatherdb-1.1.0 → weatherdb-1.1.2}/README.md +1 -1
- weatherdb-1.1.2/weatherdb/_version.py +1 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/cli.py +18 -3
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/station/GroupStation.py +6 -3
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/station/StationBases.py +5 -3
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/utils/get_data.py +204 -40
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb.egg-info/PKG-INFO +2 -2
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb.egg-info/SOURCES.txt +6 -6
- weatherdb-1.1.0/weatherdb/_version.py +0 -1
- {weatherdb-1.1.0 → weatherdb-1.1.2}/.dockerignore +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/.github/workflows/cleanup-cache.yml +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/.github/workflows/python-publish.yml +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/.github/workflows/python-test.yml +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/.gitignore +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/.gitlab/merge_request_templates/new_version.md +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/.readthedocs.yaml +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/LICENSE +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/MANIFEST.in +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docker/Dockerfile +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docker/docker-compose.yaml +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docker/docker-compose_test.yaml +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docker/start-docker-test.sh +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/requirements.txt +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/Changelog.md +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/License.rst +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/Methode.md +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/_static/custom.css +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/_static/favicon.ico +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/_static/logo.png +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/api/api.rst +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/api/cli.rst +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/api/weatherDB.broker.rst +0 -0
- /weatherdb-1.1.0/docs/source/api/weatherDB.config.rst → /weatherdb-1.1.2/docs/source/api/weatherdb.config.rst +0 -0
- /weatherdb-1.1.0/docs/source/api/weatherDB.db.rst → /weatherdb-1.1.2/docs/source/api/weatherdb.db.rst +0 -0
- /weatherdb-1.1.0/docs/source/api/weatherDB.rst → /weatherdb-1.1.2/docs/source/api/weatherdb.rst +0 -0
- /weatherdb-1.1.0/docs/source/api/weatherDB.station.rst → /weatherdb-1.1.2/docs/source/api/weatherdb.station.rst +0 -0
- /weatherdb-1.1.0/docs/source/api/weatherDB.stations.rst → /weatherdb-1.1.2/docs/source/api/weatherdb.stations.rst +0 -0
- /weatherdb-1.1.0/docs/source/api/weatherDB.utils.rst → /weatherdb-1.1.2/docs/source/api/weatherdb.utils.rst +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/conf.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/index.rst +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/setup/Configuration.md +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/setup/Hosting.md +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/setup/Install.md +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/setup/Quickstart.md +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/docs/source/setup/setup.rst +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/pyproject.toml +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/setup.cfg +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherDB.egg-info/PKG-INFO +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherDB.egg-info/SOURCES.txt +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherDB.egg-info/dependency_links.txt +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherDB.egg-info/entry_points.txt +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherDB.egg-info/requires.txt +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherDB.egg-info/top_level.txt +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/__init__.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/alembic/README.md +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/alembic/alembic.ini +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/alembic/config.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/alembic/env.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/alembic/script.py.mako +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/alembic/versions/V1.0.0_initial_database_creation.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/alembic/versions/V1.0.2_more_charachters_for_settings+term_station_ma_raster.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/alembic/versions/V1.0.5_fix-ma-raster-values.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/alembic/versions/V1.0.6_update-views.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/broker.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/config/ConfigParser.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/config/__init__.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/config/config_default.ini +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/db/__init__.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/db/connections.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/db/fixtures/RichterParameters.json +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/db/models.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/db/queries/get_quotient.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/db/views.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/station/StationET.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/station/StationP.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/station/StationPD.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/station/StationT.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/station/__init__.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/station/constants.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/stations/GroupStations.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/stations/StationsBase.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/stations/StationsBaseTET.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/stations/StationsET.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/stations/StationsP.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/stations/StationsPD.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/stations/StationsT.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/stations/__init__.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/utils/TimestampPeriod.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/utils/__init__.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/utils/dwd.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/utils/geometry.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/utils/logging.py +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb.egg-info/dependency_links.txt +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb.egg-info/entry_points.txt +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb.egg-info/requires.txt +0 -0
- {weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb.egg-info/top_level.txt +0 -0
@@ -65,6 +65,7 @@ test_single:
|
|
65
65
|
WEATHERDB_TEST_ARTIFACT_DB_DUMP: ON_FAILURE
|
66
66
|
WEATHERDB_TEST_ARTIFACT_LIST_DATA_FILES: ON_FAILURE
|
67
67
|
WEATHERDB_TEST_ARTIFACT_COPY_USER_CONFIG: ON_FAILURE
|
68
|
+
WEATHERDB_OPENTOPO_API_KEY: $WEATHERDB_OPENTOPO_API_KEY
|
68
69
|
DOCKER_ENV: test
|
69
70
|
tags:
|
70
71
|
- docker
|
@@ -1,5 +1,15 @@
|
|
1
1
|
# Change-log
|
2
2
|
|
3
|
+
## Version 1.1.2
|
4
|
+
|
5
|
+
- add method to download DEM data from OpenTopography-API
|
6
|
+
- update StationBase._expand_timeserie_to_period to remove entries that are older than the min_date config to remove unnessecary database entries
|
7
|
+
- fix GroupStation.create_ts: don't throw period changed warning if the change was only due to the expand_to_timestamp output
|
8
|
+
|
9
|
+
## Version 1.1.1
|
10
|
+
|
11
|
+
- minor fixes to fix previous version
|
12
|
+
|
3
13
|
## Version 1.1.0
|
4
14
|
|
5
15
|
- !!rename module from weatherDB to weatherdb to be compliant with PEP 8!!
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: weatherdb
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.2
|
4
4
|
Summary: This is a package to work with and to create the Weather Database which handles, checks, fills and corrects DWD Weather Station data.
|
5
5
|
Author-email: Max Schmit <max.schmit@hydrology.uni-freiburg.de>
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
@@ -704,7 +704,7 @@ Author: [Max Schmit](https://github.com/maxschmi)
|
|
704
704
|
[![Documentation Status](https://readthedocs.org/projects/weatherdb/badge/?version=latest)](https://weatherdb.readthedocs.io/latest)
|
705
705
|
[![Pipeline status](https://gitlab.uni-freiburg.de/hydrology/weatherDB/badges/master/pipeline.svg?ignore_skipped=true)](https://gitlab.uni-freiburg.de/hydrology/weatherDB/-/pipelines)
|
706
706
|
|
707
|
-
The
|
707
|
+
The WeatherDB module offers an API to interact with the automatically filled weather Database.
|
708
708
|
|
709
709
|
Depending on the Database user privileges you can use more or less methods of the classes.
|
710
710
|
|
@@ -6,7 +6,7 @@ Author: [Max Schmit](https://github.com/maxschmi)
|
|
6
6
|
[![Documentation Status](https://readthedocs.org/projects/weatherdb/badge/?version=latest)](https://weatherdb.readthedocs.io/latest)
|
7
7
|
[![Pipeline status](https://gitlab.uni-freiburg.de/hydrology/weatherDB/badges/master/pipeline.svg?ignore_skipped=true)](https://gitlab.uni-freiburg.de/hydrology/weatherDB/-/pipelines)
|
8
8
|
|
9
|
-
The
|
9
|
+
The WeatherDB module offers an API to interact with the automatically filled weather Database.
|
10
10
|
|
11
11
|
Depending on the Database user privileges you can use more or less methods of the classes.
|
12
12
|
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "1.1.2"
|
@@ -103,10 +103,16 @@ def download_ma_rasters(which, overwrite, update_user_config):
|
|
103
103
|
"""
|
104
104
|
click.echo("starting downloading multi annual raster data")
|
105
105
|
from weatherdb.utils.get_data import download_ma_rasters
|
106
|
-
download_ma_rasters(
|
106
|
+
download_ma_rasters(
|
107
|
+
which=which,
|
108
|
+
overwrite=overwrite,
|
109
|
+
update_user_config=update_user_config)
|
107
110
|
|
108
111
|
|
109
112
|
@cli.command(short_help="Download the needed digital elevation model raster data from Copernicus to the data folder.")
|
113
|
+
@click.option('--out-dir', '-d',
|
114
|
+
type=click.Path(), default=None, show_default=False,
|
115
|
+
help="The directory to save the downloaded DEM data to.")
|
110
116
|
@click.option('--overwrite/--no-overwrite', '-o/-no-o',
|
111
117
|
type=bool, is_flag=True, default=None, show_default=False,
|
112
118
|
help="Should the digital elevation model raster be downloaded even if it already exists?")
|
@@ -116,7 +122,11 @@ def download_ma_rasters(which, overwrite, update_user_config):
|
|
116
122
|
@click.option("--update-user-config", "-u",
|
117
123
|
type=bool, default=False, show_default=True, is_flag=True,
|
118
124
|
help="Should the user configuration be updated with the path to the downloaded DEM?")
|
119
|
-
|
125
|
+
@click.option("--service", "-s",
|
126
|
+
type=str, default=["prism", "openTopography"], show_default=True, multiple=True,
|
127
|
+
help="The service to use to download the DEM. Options are 'prism' or 'openTopography'. " +\
|
128
|
+
"You can use this option muultiple times to test both in the given order until the file could be downloaded.")
|
129
|
+
def download_dem(out_dir, overwrite, extent, update_user_config, service="prism"):
|
120
130
|
"""Download the newest DEM data from the Copernicus Sentinel dataset.
|
121
131
|
|
122
132
|
Only the GLO-30 DEM, wich has a 30m resolution, is downloaded as it is freely available.
|
@@ -131,7 +141,12 @@ def download_dem(overwrite, extent):
|
|
131
141
|
"""
|
132
142
|
click.echo("Starting downloading digital elevation model from Copernicus")
|
133
143
|
from weatherdb.utils.get_data import download_dem
|
134
|
-
download_dem(
|
144
|
+
download_dem(
|
145
|
+
out_dir=out_dir,
|
146
|
+
overwrite=overwrite,
|
147
|
+
extent=extent,
|
148
|
+
service=service,
|
149
|
+
update_user_config=update_user_config)
|
135
150
|
|
136
151
|
|
137
152
|
# cli statements to update the database
|
@@ -526,7 +526,9 @@ class GroupStation(object):
|
|
526
526
|
period_new = period_filled.union(
|
527
527
|
period,
|
528
528
|
how="inner")
|
529
|
-
if period_new != period
|
529
|
+
if period_new != period and not (
|
530
|
+
(period.start == period_new.start) and
|
531
|
+
((period.end - period_new.end) <= pd.Timedelta(days=1))):
|
530
532
|
warnings.warn(
|
531
533
|
f"The Period for Station {self.id} got changed from {str(period)} to {str(period_new)}.")
|
532
534
|
period = period_new
|
@@ -599,8 +601,9 @@ class GroupStation(object):
|
|
599
601
|
|
600
602
|
# create header
|
601
603
|
if add_meta:
|
602
|
-
|
603
|
-
|
604
|
+
tabs = "\t" * (len(df.columns)-1)
|
605
|
+
header = f"Name: {name}{tabs}\n" +\
|
606
|
+
f"Lat: {y[0]} ,Lon: {x[0]}{tabs}\n"
|
604
607
|
else:
|
605
608
|
header = ""
|
606
609
|
|
@@ -504,10 +504,12 @@ class StationBase:
|
|
504
504
|
'{interval}'::INTERVAL)::{tstp_dtype} AS timestamp)
|
505
505
|
INSERT INTO timeseries."{stid}_{para}"(timestamp)
|
506
506
|
(SELECT wts.timestamp
|
507
|
-
|
508
|
-
|
507
|
+
FROM whole_ts wts
|
508
|
+
LEFT JOIN timeseries."{stid}_{para}" ts
|
509
509
|
ON ts.timestamp=wts.timestamp
|
510
|
-
|
510
|
+
WHERE ts.timestamp IS NULL);
|
511
|
+
DELETE FROM timeseries."{stid}_{para}"
|
512
|
+
WHERE timestamp < '{min_date} 00:00'::{tstp_dtype};
|
511
513
|
""".format(
|
512
514
|
stid=self.id,
|
513
515
|
para=self._para,
|
@@ -6,9 +6,19 @@ from pathlib import Path
|
|
6
6
|
from distutils.util import strtobool
|
7
7
|
import hashlib
|
8
8
|
import progressbar as pb
|
9
|
+
import keyring
|
10
|
+
import os
|
11
|
+
import getpass
|
12
|
+
import logging
|
9
13
|
|
10
14
|
from ..config import config
|
11
15
|
|
16
|
+
__all__ = ["download_ma_rasters", "download_dem"]
|
17
|
+
|
18
|
+
log = logging.getLogger(__name__)
|
19
|
+
|
20
|
+
# Multi annual rasters
|
21
|
+
# --------------------
|
12
22
|
def download_ma_rasters(which="all", overwrite=None, update_user_config=False):
|
13
23
|
"""Get the multi annual rasters on which bases the regionalisation is done.
|
14
24
|
|
@@ -60,7 +70,7 @@ def download_ma_rasters(which="all", overwrite=None, update_user_config=False):
|
|
60
70
|
if file_key in which:
|
61
71
|
# check if file is in config
|
62
72
|
if f"data:rasters:{file_key}" not in config:
|
63
|
-
|
73
|
+
log.debug(f"Skipping {file_key} as it is not in your configuration.\nPlease add a section 'data:rasters:{file_key}' to your configuration file.")
|
64
74
|
continue
|
65
75
|
|
66
76
|
# check if file already exists
|
@@ -75,7 +85,7 @@ def download_ma_rasters(which="all", overwrite=None, update_user_config=False):
|
|
75
85
|
"Do you want to overwrite it? [y/n] "))
|
76
86
|
|
77
87
|
if skip:
|
78
|
-
|
88
|
+
log.debug(f"Skipping {file_key} as overwriting is not allowed.")
|
79
89
|
continue
|
80
90
|
|
81
91
|
# check if the directory exists
|
@@ -126,24 +136,42 @@ def download_ma_rasters(which="all", overwrite=None, update_user_config=False):
|
|
126
136
|
if config.has_user_config:
|
127
137
|
config.update_user_config(f"data:rasters:{file_key}", "file", str(file_path))
|
128
138
|
else:
|
129
|
-
|
139
|
+
log.error(f"No user configuration file found, therefor the raster '{file_key}' is not set in the user configuration file.")
|
130
140
|
|
141
|
+
# DEM data
|
142
|
+
# --------
|
143
|
+
def _check_write_fp(fp, overwrite):
|
144
|
+
"""Check if a file exists and if it should be overwritten.
|
131
145
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
146
|
+
Parameters
|
147
|
+
----------
|
148
|
+
fp : str or Path
|
149
|
+
The path to the file to check.
|
150
|
+
overwrite : bool
|
151
|
+
Should the file be overwritten?
|
152
|
+
|
153
|
+
Returns
|
154
|
+
-------
|
155
|
+
bool
|
156
|
+
Should the file be written?
|
157
|
+
"""
|
158
|
+
fp = Path(fp)
|
159
|
+
if fp.exists():
|
160
|
+
log.info(f"The file already exists at {fp}.")
|
161
|
+
if overwrite is None:
|
162
|
+
overwrite = strtobool(input(f"{fp} already exists. Do you want to overwrite it? [y/n] "))
|
163
|
+
if not overwrite:
|
164
|
+
log.info("Skipping, because overwritting was turned of.")
|
165
|
+
return False
|
166
|
+
return True
|
141
167
|
|
142
|
-
|
143
|
-
|
168
|
+
def _download_dem_prism(out_dir, overwrite=None, extent=(5.3, 46.1, 15.6, 55.4)):
|
169
|
+
"""Download the DEM data from the Copernicus PRISM service.
|
144
170
|
|
145
171
|
Parameters
|
146
172
|
----------
|
173
|
+
out_dir: str or Path
|
174
|
+
The directory to save the DEM data to.
|
147
175
|
overwrite : bool, optional
|
148
176
|
Should the DEM data be downloaded even if it already exists?
|
149
177
|
If None the user will be asked.
|
@@ -151,9 +179,11 @@ def download_dem(overwrite=None, extent=(5.3, 46.1, 15.6, 55.4), update_user_con
|
|
151
179
|
extent : tuple, optional
|
152
180
|
The extent in WGS84 of the DEM data to download.
|
153
181
|
The default is the boundary of germany + ~40km = (5.3, 46.1, 15.6, 55.4).
|
154
|
-
|
155
|
-
|
156
|
-
|
182
|
+
|
183
|
+
Returns
|
184
|
+
-------
|
185
|
+
fp : Path
|
186
|
+
The path to the downloaded DEM file.
|
157
187
|
"""
|
158
188
|
# import necessary modules
|
159
189
|
import rasterio as rio
|
@@ -164,10 +194,8 @@ def download_dem(overwrite=None, extent=(5.3, 46.1, 15.6, 55.4), update_user_con
|
|
164
194
|
import re
|
165
195
|
import json
|
166
196
|
|
167
|
-
#
|
168
|
-
|
169
|
-
dem_dir = base_dir / "DEM"
|
170
|
-
dem_dir.mkdir(parents=True, exist_ok=True)
|
197
|
+
# check dir
|
198
|
+
out_dir = Path(out_dir)
|
171
199
|
|
172
200
|
# get available datasets
|
173
201
|
prism_url = "https://prism-dem-open.copernicus.eu/pd-desk-open-access/publicDemURLs"
|
@@ -191,20 +219,12 @@ def download_dem(overwrite=None, extent=(5.3, 46.1, 15.6, 55.4), update_user_con
|
|
191
219
|
)[-1]["id"]
|
192
220
|
|
193
221
|
# check if dataset already exists
|
194
|
-
dem_file =
|
195
|
-
if dem_file
|
196
|
-
|
197
|
-
if overwrite is None:
|
198
|
-
overwrite = strtobool(input("Do you want to overwrite it? [y/n] "))
|
199
|
-
if not overwrite:
|
200
|
-
print("Skipping, because overwritting was turned of.")
|
201
|
-
return
|
202
|
-
else:
|
203
|
-
print("Overwriting the dataset.")
|
204
|
-
dem_dir.mkdir(exist_ok=True)
|
222
|
+
dem_file = out_dir / f'{ds_id.replace("/", "__")}.tif'
|
223
|
+
if not _check_write_fp(dem_file, overwrite):
|
224
|
+
return
|
205
225
|
|
206
226
|
# selecting DEM tiles
|
207
|
-
|
227
|
+
log.info(f"getting available tiles for Copernicus dataset '{ds_id}'")
|
208
228
|
ds_files_req = json.loads(
|
209
229
|
requests.get(
|
210
230
|
f"{prism_url}/{ds_id.replace('/', '__')}",
|
@@ -225,13 +245,13 @@ def download_dem(overwrite=None, extent=(5.3, 46.1, 15.6, 55.4), update_user_con
|
|
225
245
|
ds_files_all))
|
226
246
|
|
227
247
|
# download DEM tiles
|
228
|
-
|
248
|
+
log.info("downloading tiles")
|
229
249
|
with TemporaryDirectory() as tmp_dir:
|
230
250
|
tmp_dir_fp = Path(tmp_dir)
|
231
251
|
for f in pb.progressbar(ds_files):
|
232
252
|
with open(tmp_dir_fp / Path(f["nativeDemUrl"]).name, "wb") as d:
|
233
253
|
d.write(requests.get(f["nativeDemUrl"]).content)
|
234
|
-
|
254
|
+
log.info("downloaded all files")
|
235
255
|
|
236
256
|
# extracting tifs from tars
|
237
257
|
for i, f in pb.progressbar(list(enumerate(tmp_dir_fp.glob("*.tar")))):
|
@@ -269,17 +289,161 @@ def download_dem(overwrite=None, extent=(5.3, 46.1, 15.6, 55.4), update_user_con
|
|
269
289
|
tmp_eula_fp = next(tmp_dir_fp.glob("*.pdf"))
|
270
290
|
shutil.copyfile(
|
271
291
|
tmp_eula_fp,
|
272
|
-
|
292
|
+
out_dir / tmp_eula_fp.name
|
273
293
|
)
|
274
294
|
|
275
|
-
|
295
|
+
log.info(f"created DEM at '{dem_file}'.")
|
296
|
+
return dem_file
|
297
|
+
|
298
|
+
def _download_dem_opentopo(
|
299
|
+
out_dir,
|
300
|
+
overwrite=None,
|
301
|
+
extent=(5.3, 46.1, 15.6, 55.4),
|
302
|
+
api_key=os.environ.get(
|
303
|
+
"WEATHERDB_OPENTOPO_API_KEY",
|
304
|
+
fallback=keyring.get_password("weatherdb", "opentopo_api_key"))):
|
305
|
+
"""Download the DEM data from the OpenTopography service.
|
306
|
+
|
307
|
+
Get an API key from (OpenTopography)[https://portal.opentopography.org/] to use this service.
|
308
|
+
|
309
|
+
Parameters
|
310
|
+
----------
|
311
|
+
out_dir : str or Path
|
312
|
+
The directory to save the DEM data to.
|
313
|
+
overwrite : bool, optional
|
314
|
+
Should the DEM data be downloaded even if it already exists?
|
315
|
+
If None the user will be asked.
|
316
|
+
The default is None.
|
317
|
+
extent : tuple, optional
|
318
|
+
The extent in WGS84 of the DEM data to download.
|
319
|
+
Should be in the format (south, west, north, east).
|
320
|
+
The default is the boundary of germany + ~40km = (5.3, 46.1, 15.6, 55.4).
|
321
|
+
api_key : str, optional
|
322
|
+
The API key for the OpenTopography service.
|
323
|
+
If None the user will be asked.
|
324
|
+
The default is to check if the environment variable "WEATHERDB_OPENTOPO_API_KEY" is set or if the keyring has a password for "weatherdb" and "opentopo_api_key".
|
325
|
+
|
326
|
+
Returns
|
327
|
+
-------
|
328
|
+
fp : Path
|
329
|
+
The path to the downloaded DEM file.
|
330
|
+
"""
|
331
|
+
# check api key
|
332
|
+
if api_key is None:
|
333
|
+
print("No API key for OpenTopography was given or found in the keyring or environment variable.")
|
334
|
+
api_key = getpass("Please enter your API key for OpenTopography: ")
|
335
|
+
|
336
|
+
# make query
|
337
|
+
w, s, e, n = extent
|
338
|
+
url = f"https://portal.opentopography.org/API/globaldem?demtype=COP30&west={w}&south={s}&east={e}&north={n}&outputFormat=GTiff&API_Key={api_key}"
|
339
|
+
r = requests.get(url)
|
340
|
+
if r.status_code == 200:
|
341
|
+
# store api key
|
342
|
+
if api_key != keyring.get_password("weatherdb", "opentopo_api_key"):
|
343
|
+
keyring.set_password("weatherdb", "opentopo_api_key", api_key)
|
344
|
+
|
345
|
+
# get dem file
|
346
|
+
out_fp = out_dir / "OpenTopo_COP30.tif"
|
347
|
+
|
348
|
+
# check if file already exists
|
349
|
+
if not _check_write_fp(out_fp, overwrite):
|
350
|
+
return
|
351
|
+
|
352
|
+
# download file
|
353
|
+
with open(out_fp, "wb") as f:
|
354
|
+
for chunk in r.iter_content(chunk_size=1024):
|
355
|
+
f.write(chunk)
|
356
|
+
log.info(f"Downloaded DEM data from OpenTopography to '{out_fp}'.")
|
357
|
+
return out_fp
|
358
|
+
|
359
|
+
log.error(f"Request to openTopography API with url {r.url.replace(api_key, "[MASKED]")} returned status code {r.status_code}")
|
360
|
+
|
361
|
+
def download_dem(out_dir=None,
|
362
|
+
overwrite=None,
|
363
|
+
extent=(5.3, 46.1, 15.6, 55.4),
|
364
|
+
update_user_config=False,
|
365
|
+
service=["prism", "openTopography"], **kwargs):
|
366
|
+
"""Download the newest DEM data from the Copernicus Sentinel dataset.
|
367
|
+
|
368
|
+
Only the GLO-30 DEM, which has a 30m resolution, is downloaded as it is freely available.
|
369
|
+
If you register as a scientific researcher also the EEA-10, with 10 m resolution, is available.
|
370
|
+
You will have to download the data yourself and define it in the configuration file.
|
371
|
+
|
372
|
+
After downloading the data, the files are merged and saved as a single tif file in the data directory in a subfolder called 'DEM'.
|
373
|
+
To use the DEM data in the WeatherDB, you will have to define the path to the tif file in the configuration file.
|
374
|
+
|
375
|
+
Source:
|
376
|
+
Copernicus DEM - Global and European Digital Elevation Model. Digital Surface Model (DSM) provided in 3 different resolutions (90m, 30m, 10m) with varying geographical extent (EEA: European and GLO: global) and varying format (INSPIRE, DGED, DTED). DOI:10.5270/ESA-c5d3d65.
|
377
|
+
|
378
|
+
Parameters
|
379
|
+
----------
|
380
|
+
out_dir : str or Path, optional
|
381
|
+
The directory to save the DEM data to.
|
382
|
+
If None the data is saved in the data directory in a subfolder called 'DEM'.
|
383
|
+
The default is None.
|
384
|
+
overwrite : bool, optional
|
385
|
+
Should the DEM data be downloaded even if it already exists?
|
386
|
+
If None the user will be asked.
|
387
|
+
The default is None.
|
388
|
+
extent : tuple, optional
|
389
|
+
The extent in WGS84 of the DEM data to download.
|
390
|
+
The default is the boundary of germany + ~40km = (5.3, 46.1, 15.6, 55.4).
|
391
|
+
update_user_config : bool, optional
|
392
|
+
Should the downloaded DEM be set as the used DEM in the user configuration file?
|
393
|
+
The default is False.
|
394
|
+
service : str or list of str, optional
|
395
|
+
The service to use to download the DEM data.
|
396
|
+
Options are "prism" and "openTopography".
|
397
|
+
If Both are given they are executed in the order they are given.
|
398
|
+
If OpenTopography is selected, you will have to provide an API key.
|
399
|
+
The default is ["prism", "openTopography"].
|
400
|
+
"""
|
401
|
+
# check service
|
402
|
+
if isinstance(service, str):
|
403
|
+
service = [service]
|
404
|
+
|
405
|
+
# check dir
|
406
|
+
if out_dir is None:
|
407
|
+
out_dir = Path(config.get("data", "base_dir")) / "DEM"
|
408
|
+
else:
|
409
|
+
out_dir = Path(out_dir)
|
410
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
411
|
+
|
412
|
+
# download data
|
413
|
+
fp=None
|
414
|
+
for s in service:
|
415
|
+
if s == "prism":
|
416
|
+
try:
|
417
|
+
fp = _download_dem_prism(
|
418
|
+
out_dir=out_dir,
|
419
|
+
overwrite=overwrite,
|
420
|
+
extent=extent,
|
421
|
+
**kwargs)
|
422
|
+
break
|
423
|
+
except Exception as e:
|
424
|
+
log.debug(f"Error while downloading DEM from PRISM: {e}")
|
425
|
+
elif s == "openTopography":
|
426
|
+
try:
|
427
|
+
fp = _download_dem_opentopo(
|
428
|
+
out_dir=out_dir,
|
429
|
+
overwrite=overwrite,
|
430
|
+
extent=extent,
|
431
|
+
**kwargs)
|
432
|
+
break
|
433
|
+
except Exception as e:
|
434
|
+
log.debug(f"Error while downloading DEM from OpenTopography: {e}")
|
435
|
+
|
436
|
+
# check if file was downloaded
|
437
|
+
if fp is None:
|
438
|
+
log.error("No DEM data was downloaded.")
|
439
|
+
return
|
276
440
|
|
277
441
|
# update user config
|
278
442
|
if update_user_config:
|
279
443
|
if config.has_user_config:
|
280
|
-
config.update_user_config("data:rasters", "dems", str(
|
444
|
+
config.update_user_config("data:rasters", "dems", str(fp))
|
281
445
|
return
|
282
446
|
else:
|
283
|
-
|
447
|
+
log.info("No user configuration file found, therefor the DEM is not set in the user configuration file.")
|
284
448
|
|
285
|
-
|
449
|
+
log.info("To use the DEM data in the WeatherDB, you will have to define the path to the tif file in the user configuration file.")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: weatherdb
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.2
|
4
4
|
Summary: This is a package to work with and to create the Weather Database which handles, checks, fills and corrects DWD Weather Station data.
|
5
5
|
Author-email: Max Schmit <max.schmit@hydrology.uni-freiburg.de>
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
@@ -704,7 +704,7 @@ Author: [Max Schmit](https://github.com/maxschmi)
|
|
704
704
|
[![Documentation Status](https://readthedocs.org/projects/weatherdb/badge/?version=latest)](https://weatherdb.readthedocs.io/latest)
|
705
705
|
[![Pipeline status](https://gitlab.uni-freiburg.de/hydrology/weatherDB/badges/master/pipeline.svg?ignore_skipped=true)](https://gitlab.uni-freiburg.de/hydrology/weatherDB/-/pipelines)
|
706
706
|
|
707
|
-
The
|
707
|
+
The WeatherDB module offers an API to interact with the automatically filled weather Database.
|
708
708
|
|
709
709
|
Depending on the Database user privileges you can use more or less methods of the classes.
|
710
710
|
|
@@ -27,12 +27,12 @@ docs/source/_static/logo.png
|
|
27
27
|
docs/source/api/api.rst
|
28
28
|
docs/source/api/cli.rst
|
29
29
|
docs/source/api/weatherDB.broker.rst
|
30
|
-
docs/source/api/
|
31
|
-
docs/source/api/
|
32
|
-
docs/source/api/
|
33
|
-
docs/source/api/
|
34
|
-
docs/source/api/
|
35
|
-
docs/source/api/
|
30
|
+
docs/source/api/weatherdb.config.rst
|
31
|
+
docs/source/api/weatherdb.db.rst
|
32
|
+
docs/source/api/weatherdb.rst
|
33
|
+
docs/source/api/weatherdb.station.rst
|
34
|
+
docs/source/api/weatherdb.stations.rst
|
35
|
+
docs/source/api/weatherdb.utils.rst
|
36
36
|
docs/source/setup/Configuration.md
|
37
37
|
docs/source/setup/Hosting.md
|
38
38
|
docs/source/setup/Install.md
|
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = "1.1.0"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
/weatherdb-1.1.0/docs/source/api/weatherDB.rst → /weatherdb-1.1.2/docs/source/api/weatherdb.rst
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/alembic/versions/V1.0.0_initial_database_creation.py
RENAMED
File without changes
|
File without changes
|
{weatherdb-1.1.0 → weatherdb-1.1.2}/weatherdb/alembic/versions/V1.0.5_fix-ma-raster-values.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|