Skip to content

Commit 6f06f76

Browse files
add second function to compute grid area with projections
1 parent ec4a819 commit 6f06f76

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

climada/util/coordinates.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import shapely.vectorized
4747
import shapely.wkt
4848
from cartopy.io import shapereader
49+
from pyproj import Geod
4950
from shapely.geometry import MultiPolygon, Point, Polygon, box
5051
from sklearn.neighbors import BallTree
5152

@@ -526,6 +527,59 @@ def compute_grid_cell_area(res: float) -> tuple[np.ndarray]:
526527
return grid_area, [lat_bins, lon_bins]
527528

528529

530+
def compute_grid_cell_area_(
531+
res: float = 1.0, projection: str = "WGS84", units: str = "km^2"
532+
) -> np.ndarray:
533+
"""
534+
Compute the area of each grid cell in a latitude-longitude grid.
535+
536+
Parameters:
537+
-----------
538+
res: float
539+
Grid resolution in degrees (default is 1° x 1°)
540+
projection: str
541+
Ellipsoid or spherical projection to approximate Earth. To get the complete list of
542+
projections call :py:meth:`pyproj.get_ellps_map()`. Widely used projections:
543+
- "WGS84": Uses the WGS84 ellipsoid (default)
544+
- "GRS80"
545+
- "IAU76"
546+
- "sphere": Uses a perfect sphere with Earth's mean radius (6371 km)
547+
units: str (optional) Default "km^2"
548+
units of the area. Either km^2 or m^2.
549+
550+
Returns:
551+
--------
552+
area: np.ndarray
553+
A 2D numpy array of grid cell areas in km²
554+
Example:
555+
--------
556+
>>> area = compute_grid_areas(res = 1, projection ="sphere", units = "m^2")
557+
"""
558+
geod = Geod(ellps=projection) # Use specified ellipsoid model
559+
560+
lat_edges = np.linspace(-90, 90, int(180 / res)) # Latitude edges
561+
lon_edges = np.linspace(-180, 180, int(360 / res)) # Longitude edges
562+
563+
area = np.zeros((len(lat_edges) - 1, len(lon_edges) - 1)) # Create an empty grid
564+
565+
# Iterate over consecutive latitude and longitude edges
566+
for i, (lat1, lat2) in enumerate(zip(lat_edges[:-1], lat_edges[1:])):
567+
for j, (lon1, lon2) in enumerate(zip(lon_edges[:-1], lon_edges[1:])):
568+
569+
# 5th point to close the loop
570+
poly_lons = [lon1, lon2, lon2, lon1, lon1]
571+
poly_lats = [lat1, lat1, lat2, lat2, lat1]
572+
573+
# Compute the area of the grid cell
574+
poly_area, _ = geod.polygon_area_perimeter(poly_lons, poly_lats)
575+
area[i, j] = abs(poly_area) # Convert from m² to km²
576+
577+
if units == "km^2":
578+
area = area / 1e6
579+
580+
return area
581+
582+
529583
def grid_is_regular(coord):
530584
"""Return True if grid is regular. If True, returns height and width.
531585

0 commit comments

Comments
 (0)