Skip to content

Commit 2eb10b5

Browse files
committed
[JTH] little reformat to keep consistency across files
1 parent 375c4c1 commit 2eb10b5

File tree

1 file changed

+47
-13
lines changed

1 file changed

+47
-13
lines changed

bluemath_tk/core/plotting/WMS_USGSTopo.py

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
import math
2-
import requests
32
from io import BytesIO
4-
from PIL import Image
5-
import matplotlib.pyplot as plt
3+
from typing import Tuple
4+
65
import cartopy.crs as ccrs
76
import cartopy.feature as cfeature
7+
import matplotlib.pyplot as plt
8+
import requests
9+
from PIL import Image
10+
11+
from ..constants import EARTH_RADIUS
12+
13+
EARTH_RADIUS_M = EARTH_RADIUS * 1000 # Convert km to m
814

915

10-
def deg2num(lat: float, lon: float, zoom: int) -> tuple[int, int]:
16+
def deg2num(lat: float, lon: float, zoom: int) -> Tuple[int, int]:
1117
"""
1218
Converts geographic coordinates to tile numbers for a given zoom level.
1319
@@ -27,16 +33,18 @@ def deg2num(lat: float, lon: float, zoom: int) -> tuple[int, int]:
2733
ytile : int
2834
Tile number in y-direction.
2935
"""
36+
3037
lat_rad = math.radians(lat)
3138
n = 2.0**zoom
3239
xtile = int((lon + 180.0) / 360.0 * n)
3340
ytile = int(
3441
(1.0 - math.log(math.tan(lat_rad) + 1 / math.cos(lat_rad)) / math.pi) / 2.0 * n
3542
)
43+
3644
return xtile, ytile
3745

3846

39-
def num2deg(xtile: int, ytile: int, zoom: int) -> tuple[float, float]:
47+
def num2deg(xtile: int, ytile: int, zoom: int) -> Tuple[float, float]:
4048
"""
4149
Converts tile numbers back to geographic coordinates.
4250
@@ -56,14 +64,16 @@ def num2deg(xtile: int, ytile: int, zoom: int) -> tuple[float, float]:
5664
lon : float
5765
Longitude in degrees.
5866
"""
67+
5968
n = 2.0**zoom
6069
lon = xtile / n * 360.0 - 180.0
6170
lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
6271
lat = math.degrees(lat_rad)
72+
6373
return lat, lon
6474

6575

66-
def lonlat_to_webmercator(lon: float, lat: float) -> tuple[float, float]:
76+
def lonlat_to_webmercator(lon: float, lat: float) -> Tuple[float, float]:
6777
"""
6878
Converts lon/lat to Web Mercator projection coordinates in meters.
6979
@@ -81,15 +91,16 @@ def lonlat_to_webmercator(lon: float, lat: float) -> tuple[float, float]:
8191
y : float
8292
Y coordinate in meters.
8393
"""
84-
R = 6378137.0
85-
x = R * math.radians(lon)
86-
y = R * math.log(math.tan((math.pi / 4) + math.radians(lat) / 2))
94+
95+
x = EARTH_RADIUS_M * math.radians(lon)
96+
y = EARTH_RADIUS_M * math.log(math.tan((math.pi / 4) + math.radians(lat) / 2))
97+
8798
return x, y
8899

89100

90101
def tile_bounds_meters(
91102
x_start: int, y_start: int, x_end: int, y_end: int, zoom: int
92-
) -> tuple[float, float, float, float]:
103+
) -> Tuple[float, float, float, float]:
93104
"""
94105
Computes the bounding box of the tile region in Web Mercator meters.
95106
@@ -98,10 +109,12 @@ def tile_bounds_meters(
98109
xmin, ymin, xmax, ymax : float
99110
Bounding box in meters (Web Mercator projection).
100111
"""
112+
101113
lat1, lon1 = num2deg(x_start, y_start, zoom)
102114
lat2, lon2 = num2deg(x_end + 1, y_end + 1, zoom)
103115
x1, y1 = lonlat_to_webmercator(lon1, lat2)
104116
x2, y2 = lonlat_to_webmercator(lon2, lat1)
117+
105118
return x1, y1, x2, y2
106119

107120

@@ -116,12 +129,14 @@ def calculate_zoom(
116129
zoom : int
117130
Estimated zoom level.
118131
"""
119-
WORLD_MAP_WIDTH = 2 * math.pi * 6378137
132+
133+
WORLD_MAP_WIDTH = 2 * math.pi * EARTH_RADIUS_M
120134
x1, _ = lonlat_to_webmercator(lon_min, 0)
121135
x2, _ = lonlat_to_webmercator(lon_max, 0)
122136
region_width_m = abs(x2 - x1)
123137
meters_per_pixel_desired = region_width_m / display_width_px
124138
zoom = math.log2(WORLD_MAP_WIDTH / (tile_size * meters_per_pixel_desired))
139+
125140
return int(round(zoom))
126141

127142

@@ -139,6 +154,7 @@ def get_cartopy_scale(zoom: int) -> str:
139154
scale : str
140155
One of '110m', '50m', or '10m'.
141156
"""
157+
142158
if zoom >= 9:
143159
return "10m"
144160
elif zoom >= 6:
@@ -157,7 +173,7 @@ def plot_usgs_raster_map(
157173
mask_ocean: bool = False,
158174
add_features: bool = True,
159175
display_width_px: int = 1024,
160-
) -> tuple[plt.Figure, plt.Axes]:
176+
) -> Tuple[plt.Figure, plt.Axes]:
161177
"""
162178
Downloads and displays a USGS raster map for the given bounding box.
163179
@@ -174,6 +190,7 @@ def plot_usgs_raster_map(
174190
display_width_px : int, optional
175191
Approximate pixel width for display (default is 1024).
176192
"""
193+
177194
tile_size = 256
178195
if zoom is None:
179196
zoom = calculate_zoom(lon_min, lon_max, display_width_px, tile_size)
@@ -221,4 +238,21 @@ def plot_usgs_raster_map(
221238

222239
if mask_ocean:
223240
ax.add_feature(cfeature.OCEAN.with_scale(scale), facecolor="w", zorder=3)
224-
return fig, ax
241+
242+
return fig, ax
243+
244+
245+
if __name__ == "__main__":
246+
lat_min, lat_max = 35.406, 54.372
247+
lon_min, lon_max = -13.148, 12.325
248+
fig, ax = plot_usgs_raster_map(
249+
lat_min,
250+
lat_max,
251+
lon_min,
252+
lon_max,
253+
zoom=None,
254+
verbose=True,
255+
add_features=False,
256+
mask_ocean=True,
257+
)
258+
fig.show()

0 commit comments

Comments
 (0)