Skip to content

Commit 541937e

Browse files
move grid area function to util
1 parent 6016af5 commit 541937e

File tree

2 files changed

+68
-69
lines changed

2 files changed

+68
-69
lines changed

climada/hazard/tc_tracks.py

Lines changed: 1 addition & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
from matplotlib.collections import LineCollection
4949
from matplotlib.colors import BoundaryNorm, ListedColormap
5050
from matplotlib.lines import Line2D
51-
from scipy.sparse import csr_matrix
5251
from shapely.geometry import LineString, MultiLineString, Point
5352
from sklearn.metrics import DistanceMetric
5453
from tqdm import tqdm
@@ -2957,74 +2956,7 @@ def compute_track_density(
29572956
hist_count += hist_new
29582957

29592958
if density:
2960-
grid_area, _ = compute_grid_cell_area(res=res)
2959+
grid_area, _ = u_coord.compute_grid_cell_area(res=res)
29612960
hist_count = hist_count / grid_area
29622961

29632962
return hist_count, lat_bins, lon_bins
2964-
2965-
2966-
def compute_grid_cell_area(res) -> tuple[np.ndarray]:
2967-
"""
2968-
This function computes the area of each grid cell on a sphere (Earth), using latitude and
2969-
longitude bins based on the given resolution. The area is computed using the spherical cap
2970-
approximation for each grid cell. The function return a 2D matrix with the corresponding area.
2971-
2972-
The formula used to compute the area of each grid cell is derived from the integral of the
2973-
surface area of a spherical cap between squared latitude and longitude bins:
2974-
2975-
A = R**2 * (Δλ) * (sin(ϕ2) - sin(ϕ1))
2976-
2977-
Where:
2978-
- R is the radius of the Earth (in km).
2979-
- Δλ is the width of the grid cell in terms of longitude (in radians).
2980-
- sin(ϕ2) - sin(ϕ1) is the difference in the sine of the latitudes, which
2981-
accounts for the varying horizontal distance between longitudinal lines at different latitudes.
2982-
2983-
This formula is the direct integration over λ and ϕ2 of:
2984-
2985-
A = R**2 * Δλ * Δϕ * cos(ϕ1)
2986-
2987-
which approximate the grid cell area as a square computed by the multiplication of two
2988-
arc legths, with the logitudal arc length ajdusted by latitude.
2989-
2990-
Parameters:
2991-
----------
2992-
res: int
2993-
The resolution of the grid in degrees. The grid will have cells of size `res x res` in
2994-
terms of latitude and longitude.
2995-
2996-
Returns:
2997-
-------
2998-
grid_area: np.ndarray
2999-
A 2D array of shape `(len(lat_bins)-1, len(lon_bins)-1)` containing the area of each grid
3000-
cell, in square kilometers. Each entry in the array corresponds to the area of the
3001-
corresponding grid cell on Earth.
3002-
3003-
Example:
3004-
--------
3005-
>>> res = 10 #10° resolution
3006-
>>> area = compute_grid_cell_area(res = res)
3007-
>>> print(area.shape) # (180/10, 360/10)
3008-
(18, 36)
3009-
"""
3010-
3011-
lat_bins = np.linspace(-90, 90, int(180 / res)) # lat bins
3012-
lon_bins = np.linspace(-180, 180, int(360 / res))
3013-
3014-
R = 6371 # Earth's radius [km]
3015-
# Convert to radians
3016-
lat_bin_edges = np.radians(lat_bins)
3017-
lon_res_rad = np.radians(res)
3018-
3019-
# Compute area
3020-
areas = (
3021-
R**2
3022-
* lon_res_rad
3023-
* np.abs(np.sin(lat_bin_edges[1:]) - np.sin(lat_bin_edges[:-1]))
3024-
)
3025-
# Broadcast to create a full 2D grid of areas
3026-
grid_area = np.tile(
3027-
areas[:, np.newaxis], (1, len(lon_bins) - 1)
3028-
) # each row as same area
3029-
3030-
return grid_area, [lat_bins, lon_bins]

climada/util/coordinates.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,73 @@ def get_gridcellarea(lat, resolution=0.5, unit="ha"):
459459
return area
460460

461461

462+
def compute_grid_cell_area(res: float) -> tuple[np.ndarray]:
463+
"""
464+
This function computes the area of each grid cell on a sphere (Earth), using latitude and
465+
longitude bins based on the given resolution. The area is computed using the spherical cap
466+
approximation for each grid cell. The function return a 2D matrix with the corresponding area.
467+
468+
The formula used to compute the area of each grid cell is derived from the integral of the
469+
surface area of a spherical cap between squared latitude and longitude bins:
470+
471+
A = R**2 * (Δλ) * (sin(ϕ2) - sin(ϕ1))
472+
473+
Where:
474+
- R is the radius of the Earth (in km).
475+
- Δλ is the width of the grid cell in terms of longitude (in radians).
476+
- sin(ϕ2) - sin(ϕ1) is the difference in the sine of the latitudes, which
477+
accounts for the varying horizontal distance between longitudinal lines at different latitudes.
478+
479+
This formula is the direct integration over λ and ϕ2 of:
480+
481+
A = R**2 * Δλ * Δϕ * cos(ϕ1)
482+
483+
which approximate the grid cell area as a square computed by the multiplication of two
484+
arc legths, with the logitudal arc length ajdusted by latitude.
485+
486+
Parameters:
487+
----------
488+
res: int
489+
The resolution of the grid in degrees. The grid will have cells of size `res x res` in
490+
terms of latitude and longitude.
491+
492+
Returns:
493+
-------
494+
grid_area: np.ndarray
495+
A 2D array of shape `(len(lat_bins)-1, len(lon_bins)-1)` containing the area of each grid
496+
cell, in square kilometers. Each entry in the array corresponds to the area of the
497+
corresponding grid cell on Earth.
498+
499+
Example:
500+
--------
501+
>>> res = 10 #10° resolution
502+
>>> area = compute_grid_cell_area(res = res)
503+
>>> print(area.shape) # (180/10, 360/10)
504+
(18, 36)
505+
"""
506+
507+
lat_bins = np.linspace(-90, 90, int(180 / res)) # lat bins
508+
lon_bins = np.linspace(-180, 180, int(360 / res))
509+
510+
R = 6371 # Earth's radius [km]
511+
# Convert to radians
512+
lat_bin_edges = np.radians(lat_bins)
513+
lon_res_rad = np.radians(res)
514+
515+
# Compute area
516+
areas = (
517+
R**2
518+
* lon_res_rad
519+
* np.abs(np.sin(lat_bin_edges[1:]) - np.sin(lat_bin_edges[:-1]))
520+
)
521+
# Broadcast to create a full 2D grid of areas
522+
grid_area = np.tile(
523+
areas[:, np.newaxis], (1, len(lon_bins) - 1)
524+
) # each row as same area
525+
526+
return grid_area, [lat_bins, lon_bins]
527+
528+
462529
def grid_is_regular(coord):
463530
"""Return True if grid is regular. If True, returns height and width.
464531

0 commit comments

Comments
 (0)