ne-loader 0.3__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ne_loader-0.3 → ne_loader-0.3.2}/PKG-INFO +12 -2
- {ne_loader-0.3 → ne_loader-0.3.2}/README.md +11 -1
- {ne_loader-0.3 → ne_loader-0.3.2}/pyproject.toml +1 -1
- ne_loader-0.3.2/src/ne_loader/__init__.py +4 -0
- {ne_loader-0.3 → ne_loader-0.3.2}/src/ne_loader/cli.py +9 -4
- {ne_loader-0.3 → ne_loader-0.3.2}/src/ne_loader/map_loader.py +44 -28
- {ne_loader-0.3 → ne_loader-0.3.2}/src/ne_loader.egg-info/PKG-INFO +12 -2
- {ne_loader-0.3 → ne_loader-0.3.2}/tests/test_map_loader.py +9 -0
- ne_loader-0.3/src/ne_loader/__init__.py +0 -1
- {ne_loader-0.3 → ne_loader-0.3.2}/setup.cfg +0 -0
- {ne_loader-0.3 → ne_loader-0.3.2}/src/ne_loader/cacher.py +0 -0
- {ne_loader-0.3 → ne_loader-0.3.2}/src/ne_loader/error_handler.py +0 -0
- {ne_loader-0.3 → ne_loader-0.3.2}/src/ne_loader.egg-info/SOURCES.txt +0 -0
- {ne_loader-0.3 → ne_loader-0.3.2}/src/ne_loader.egg-info/dependency_links.txt +0 -0
- {ne_loader-0.3 → ne_loader-0.3.2}/src/ne_loader.egg-info/entry_points.txt +0 -0
- {ne_loader-0.3 → ne_loader-0.3.2}/src/ne_loader.egg-info/requires.txt +0 -0
- {ne_loader-0.3 → ne_loader-0.3.2}/src/ne_loader.egg-info/top_level.txt +0 -0
- {ne_loader-0.3 → ne_loader-0.3.2}/tests/test_error_handler.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ne-loader
|
|
3
|
-
Version: 0.3
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: A simple loader for Natural Earth map data.
|
|
5
5
|
Author-email: Eric Tunn <erictunn@icloud.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/erictunn/ne-loader
|
|
@@ -32,6 +32,16 @@ from ne_loader import map_loader
|
|
|
32
32
|
world = map_loader.get_natural_earth('cultural', 'admin_0_countries')
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
Errors are raised by default. To return the caught exception instead:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
result = map_loader.get_natural_earth(
|
|
39
|
+
'cultural',
|
|
40
|
+
'admin_0_countries',
|
|
41
|
+
error_mode='return',
|
|
42
|
+
)
|
|
43
|
+
```
|
|
44
|
+
|
|
35
45
|
## CLI
|
|
36
46
|
|
|
37
47
|
```bash
|
|
@@ -47,7 +57,7 @@ export NATURAL_EARTH_CACHE_DIR="..."
|
|
|
47
57
|
## Tests
|
|
48
58
|
|
|
49
59
|
```bash
|
|
50
|
-
python3 -m pytest tests
|
|
60
|
+
python3 -m pytest tests
|
|
51
61
|
```
|
|
52
62
|
|
|
53
63
|
## License
|
|
@@ -20,6 +20,16 @@ from ne_loader import map_loader
|
|
|
20
20
|
world = map_loader.get_natural_earth('cultural', 'admin_0_countries')
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
Errors are raised by default. To return the caught exception instead:
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
result = map_loader.get_natural_earth(
|
|
27
|
+
'cultural',
|
|
28
|
+
'admin_0_countries',
|
|
29
|
+
error_mode='return',
|
|
30
|
+
)
|
|
31
|
+
```
|
|
32
|
+
|
|
23
33
|
## CLI
|
|
24
34
|
|
|
25
35
|
```bash
|
|
@@ -35,7 +45,7 @@ export NATURAL_EARTH_CACHE_DIR="..."
|
|
|
35
45
|
## Tests
|
|
36
46
|
|
|
37
47
|
```bash
|
|
38
|
-
python3 -m pytest tests
|
|
48
|
+
python3 -m pytest tests
|
|
39
49
|
```
|
|
40
50
|
|
|
41
51
|
## License
|
|
@@ -12,16 +12,20 @@ def main() -> None:
|
|
|
12
12
|
parser: argparse.ArgumentParser = argparse.ArgumentParser(
|
|
13
13
|
description="Download and load Natural Earth data."
|
|
14
14
|
)
|
|
15
|
-
parser.add_argument(
|
|
15
|
+
parser.add_argument(
|
|
16
|
+
"category",
|
|
17
|
+
choices=["cultural", "physical"],
|
|
18
|
+
help="Data category",
|
|
19
|
+
)
|
|
16
20
|
parser.add_argument("name", help="Dataset name (e.g., admin_0_countries)")
|
|
17
21
|
parser.add_argument("--res", default="10m", help="Resolution (default: 10m)")
|
|
18
22
|
parser.add_argument("--out", help="Output file to save as GeoJSON (optional)")
|
|
19
23
|
args: argparse.Namespace = parser.parse_args()
|
|
20
24
|
|
|
21
25
|
gdf: gpd.GeoDataFrame = map_loader.get_natural_earth(
|
|
22
|
-
args.category,
|
|
23
|
-
args.name,
|
|
24
|
-
args.res,
|
|
26
|
+
category=args.category,
|
|
27
|
+
name=args.name,
|
|
28
|
+
res=args.res,
|
|
25
29
|
)
|
|
26
30
|
if args.out:
|
|
27
31
|
gdf.to_file(args.out, driver="GeoJSON")
|
|
@@ -29,5 +33,6 @@ def main() -> None:
|
|
|
29
33
|
else:
|
|
30
34
|
print(gdf.head())
|
|
31
35
|
|
|
36
|
+
|
|
32
37
|
if __name__ == "__main__":
|
|
33
38
|
main()
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"""Handles downloading and fetching of NE data."""
|
|
2
2
|
|
|
3
|
+
import contextlib
|
|
3
4
|
import logging
|
|
5
|
+
import shutil
|
|
4
6
|
import zipfile
|
|
5
7
|
from pathlib import Path
|
|
6
8
|
from typing import Literal, Optional, Union, overload
|
|
@@ -22,7 +24,7 @@ def build_ne_filename(name: str, res: str = "10m", suffix: str = ".zip") -> str:
|
|
|
22
24
|
return f"ne_{res}_{name}{suffix}"
|
|
23
25
|
|
|
24
26
|
|
|
25
|
-
def build_ne_url(category: str, name: str, res:
|
|
27
|
+
def build_ne_url(category: str, name: str, res: Resolution) -> str:
|
|
26
28
|
"""Build the download URL for a Natural Earth vector dataset."""
|
|
27
29
|
return (
|
|
28
30
|
f"https://naciscdn.org/naturalearth/{res}/{category}/"
|
|
@@ -30,17 +32,17 @@ def build_ne_url(category: str, name: str, res: str = "10m") -> str:
|
|
|
30
32
|
)
|
|
31
33
|
|
|
32
34
|
|
|
33
|
-
def build_ne_zip_path(data_dir: PathLike, name: str, res:
|
|
35
|
+
def build_ne_zip_path(data_dir: PathLike, name: str, res: Resolution) -> Path:
|
|
34
36
|
"""Build the local cache path for a Natural Earth zip file."""
|
|
35
37
|
return Path(data_dir) / build_ne_filename(name, res)
|
|
36
38
|
|
|
37
39
|
|
|
38
|
-
def build_ne_extract_dir(data_dir: PathLike, name: str, res:
|
|
40
|
+
def build_ne_extract_dir(data_dir: PathLike, name: str, res: Resolution) -> Path:
|
|
39
41
|
"""Build the local extraction directory for a Natural Earth dataset."""
|
|
40
42
|
return Path(data_dir) / build_ne_filename(name, res, suffix="")
|
|
41
43
|
|
|
42
44
|
|
|
43
|
-
def build_ne_shp_path(data_dir: PathLike, name: str, res:
|
|
45
|
+
def build_ne_shp_path(data_dir: PathLike, name: str, res: Resolution) -> Path:
|
|
44
46
|
"""Build the local shapefile path for an extracted Natural Earth dataset."""
|
|
45
47
|
extract_dir: Path = build_ne_extract_dir(data_dir, name, res)
|
|
46
48
|
return extract_dir / build_ne_filename(name, res, suffix=".shp")
|
|
@@ -51,19 +53,9 @@ def get_natural_earth(
|
|
|
51
53
|
category: str,
|
|
52
54
|
name: str,
|
|
53
55
|
res: Resolution = "10m",
|
|
56
|
+
*,
|
|
54
57
|
dir_override: Optional[PathLike] = None,
|
|
55
|
-
error_mode: Literal["
|
|
56
|
-
user_logger: Optional[logging.Logger] = None,
|
|
57
|
-
) -> gpd.GeoDataFrame: ...
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
@overload
|
|
61
|
-
def get_natural_earth(
|
|
62
|
-
category: str,
|
|
63
|
-
name: str,
|
|
64
|
-
res: Resolution = "10m",
|
|
65
|
-
dir_override: Optional[PathLike] = None,
|
|
66
|
-
error_mode: Literal["ignore"] = "ignore",
|
|
58
|
+
error_mode: Literal["ignore"],
|
|
67
59
|
user_logger: Optional[logging.Logger] = None,
|
|
68
60
|
) -> Optional[gpd.GeoDataFrame]: ...
|
|
69
61
|
|
|
@@ -73,10 +65,11 @@ def get_natural_earth(
|
|
|
73
65
|
category: str,
|
|
74
66
|
name: str,
|
|
75
67
|
res: Resolution = "10m",
|
|
68
|
+
*,
|
|
76
69
|
dir_override: Optional[PathLike] = None,
|
|
77
|
-
error_mode: Literal["
|
|
70
|
+
error_mode: Literal["raise"] = "raise",
|
|
78
71
|
user_logger: Optional[logging.Logger] = None,
|
|
79
|
-
) ->
|
|
72
|
+
) -> gpd.GeoDataFrame: ...
|
|
80
73
|
|
|
81
74
|
|
|
82
75
|
@overload
|
|
@@ -84,16 +77,18 @@ def get_natural_earth(
|
|
|
84
77
|
category: str,
|
|
85
78
|
name: str,
|
|
86
79
|
res: Resolution = "10m",
|
|
80
|
+
*,
|
|
87
81
|
dir_override: Optional[PathLike] = None,
|
|
88
|
-
error_mode:
|
|
82
|
+
error_mode: Literal["return"],
|
|
89
83
|
user_logger: Optional[logging.Logger] = None,
|
|
90
|
-
) -> Union[gpd.GeoDataFrame, Exception
|
|
84
|
+
) -> Union[gpd.GeoDataFrame, Exception]: ...
|
|
91
85
|
|
|
92
86
|
|
|
93
87
|
def get_natural_earth(
|
|
94
88
|
category: str,
|
|
95
89
|
name: str,
|
|
96
90
|
res: Resolution = "10m",
|
|
91
|
+
*,
|
|
97
92
|
dir_override: Optional[PathLike] = None,
|
|
98
93
|
error_mode: ErrorMode = "raise",
|
|
99
94
|
user_logger: Optional[logging.Logger] = None,
|
|
@@ -107,6 +102,8 @@ def get_natural_earth(
|
|
|
107
102
|
"admin_0_countries".
|
|
108
103
|
res: Natural Earth resolution. "10m", "50m" and "110m" are accepted.
|
|
109
104
|
However, not all datasets will have all 3 resolutions available.
|
|
105
|
+
|
|
106
|
+
Keyword Args:
|
|
110
107
|
dir_override: Optional cache directory override. This takes precedence over the
|
|
111
108
|
``NATURAL_EARTH_CACHE_DIR`` environment variable.
|
|
112
109
|
error_mode: Error handling mode. Default is raise. Upon error:
|
|
@@ -122,6 +119,7 @@ def get_natural_earth(
|
|
|
122
119
|
logger = user_logger or fallback_logger
|
|
123
120
|
try:
|
|
124
121
|
validate_error_mode(error_mode)
|
|
122
|
+
validate_res(res)
|
|
125
123
|
|
|
126
124
|
data_dir: Path = get_cache_dir(dir_override)
|
|
127
125
|
data_dir.mkdir(parents=True, exist_ok=True)
|
|
@@ -143,10 +141,10 @@ def get_natural_earth(
|
|
|
143
141
|
|
|
144
142
|
return gpd.read_file(shp_file)
|
|
145
143
|
except Exception as error:
|
|
146
|
-
logger.error(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
144
|
+
logger.error(
|
|
145
|
+
"ne-loader: error caught fetching data with get_natural_earth():\n",
|
|
146
|
+
error,
|
|
147
|
+
)
|
|
150
148
|
return error_handler(error, error_mode)
|
|
151
149
|
|
|
152
150
|
|
|
@@ -163,7 +161,7 @@ def _download_ne_data(
|
|
|
163
161
|
if shp_file.exists():
|
|
164
162
|
return
|
|
165
163
|
|
|
166
|
-
|
|
164
|
+
logger.info(f"ne-loader: Downloading {name} ({res})...")
|
|
167
165
|
|
|
168
166
|
try:
|
|
169
167
|
response: requests.Response = requests.get(url, stream=True, timeout=10)
|
|
@@ -176,7 +174,6 @@ def _download_ne_data(
|
|
|
176
174
|
|
|
177
175
|
with zipfile.ZipFile(zip_path, "r") as zip_ref:
|
|
178
176
|
zip_ref.extractall(extract_dir)
|
|
179
|
-
zip_path.unlink()
|
|
180
177
|
return None
|
|
181
178
|
|
|
182
179
|
except requests.exceptions.HTTPError as error:
|
|
@@ -186,7 +183,6 @@ def _download_ne_data(
|
|
|
186
183
|
"This may cause an error when attempting to load the data.",
|
|
187
184
|
error,
|
|
188
185
|
)
|
|
189
|
-
print(f"A HTTP error occurred while attempting to fetch data: {error}")
|
|
190
186
|
raise
|
|
191
187
|
except requests.exceptions.RequestException as error:
|
|
192
188
|
logger.error(
|
|
@@ -195,5 +191,25 @@ def _download_ne_data(
|
|
|
195
191
|
"This may cause an error when attempting to load the data.",
|
|
196
192
|
error,
|
|
197
193
|
)
|
|
198
|
-
print(f"A request error occurred while attempting to fetch data: {error}")
|
|
199
194
|
raise
|
|
195
|
+
|
|
196
|
+
finally:
|
|
197
|
+
with contextlib.suppress(FileNotFoundError):
|
|
198
|
+
zip_path.unlink()
|
|
199
|
+
if (not shp_file.exists() and
|
|
200
|
+
extract_dir.name == build_ne_filename(name, res, suffix="")):
|
|
201
|
+
shutil.rmtree(extract_dir, ignore_errors=True)
|
|
202
|
+
|
|
203
|
+
def validate_res(res: str) -> None:
|
|
204
|
+
"""Validate the resolution against "10m", "50m", "110m".
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
res (Resolution): The resolution to be validated.
|
|
208
|
+
|
|
209
|
+
Raises:
|
|
210
|
+
ValueError: If res is invalid, raises ValueError.
|
|
211
|
+
|
|
212
|
+
"""
|
|
213
|
+
if res not in ("10m", "50m", "110m"):
|
|
214
|
+
raise ValueError(f"Invalid resolution: {res}.\
|
|
215
|
+
\nResolution must be one of (\"10m\", \"50m\", \"110m\")")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ne-loader
|
|
3
|
-
Version: 0.3
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: A simple loader for Natural Earth map data.
|
|
5
5
|
Author-email: Eric Tunn <erictunn@icloud.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/erictunn/ne-loader
|
|
@@ -32,6 +32,16 @@ from ne_loader import map_loader
|
|
|
32
32
|
world = map_loader.get_natural_earth('cultural', 'admin_0_countries')
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
Errors are raised by default. To return the caught exception instead:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
result = map_loader.get_natural_earth(
|
|
39
|
+
'cultural',
|
|
40
|
+
'admin_0_countries',
|
|
41
|
+
error_mode='return',
|
|
42
|
+
)
|
|
43
|
+
```
|
|
44
|
+
|
|
35
45
|
## CLI
|
|
36
46
|
|
|
37
47
|
```bash
|
|
@@ -47,7 +57,7 @@ export NATURAL_EARTH_CACHE_DIR="..."
|
|
|
47
57
|
## Tests
|
|
48
58
|
|
|
49
59
|
```bash
|
|
50
|
-
python3 -m pytest tests
|
|
60
|
+
python3 -m pytest tests
|
|
51
61
|
```
|
|
52
62
|
|
|
53
63
|
## License
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
"""Basic tests for map_loader.py constructors."""
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
+
import re
|
|
5
|
+
import pytest
|
|
4
6
|
|
|
5
7
|
from ne_loader.map_loader import (
|
|
6
8
|
build_ne_filename,
|
|
7
9
|
build_ne_shp_path,
|
|
8
10
|
build_ne_url,
|
|
9
11
|
build_ne_zip_path,
|
|
12
|
+
validate_res
|
|
10
13
|
)
|
|
11
14
|
|
|
12
15
|
|
|
@@ -45,3 +48,9 @@ def test_build_ne_shp_path() -> None:
|
|
|
45
48
|
"/tmp/natural-earth-cache/ne_10m_admin_0_countries/"
|
|
46
49
|
"ne_10m_admin_0_countries.shp"
|
|
47
50
|
)
|
|
51
|
+
|
|
52
|
+
def test_validate_res() -> None:
|
|
53
|
+
"""Tests that validate_res(res=kaboom) raises the correct ValueError."""
|
|
54
|
+
with pytest.raises(ValueError, match=re.escape(f"Invalid resolution: kaboom.\
|
|
55
|
+
\nResolution must be one of (\"10m\", \"50m\", \"110m\")")):
|
|
56
|
+
validate_res("kaboom")
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# Natural Earth Loader package
|
|
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
|