-
Notifications
You must be signed in to change notification settings - Fork 41
Add grid_bounds_to_polygons #478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 10 commits
9c3c5b6
d26bf4a
0370b53
83f8349
8a6b79f
96a00d8
efd423d
53cc744
0db0b96
d33610e
c048410
98be7c1
1f7ceae
25d8224
459365c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -438,3 +438,66 @@ | |
geoms = np.where(np.diff(offset2) == 1, lines[offset2[:-1]], multilines) | ||
|
||
return xr.DataArray(geoms, dims=part_node_count.dims, coords=part_node_count.coords) | ||
|
||
|
||
def grid_to_polygons(ds: xr.Dataset) -> xr.DataArray: | ||
dcherian marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
Converts a regular 2D lat/lon grid to a 2D array of shapely polygons. | ||
dcherian marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Modified from https://notebooksharing.space/view/c6c1f3a7d0c260724115eaa2bf78f3738b275f7f633c1558639e7bbd75b31456. | ||
|
||
Parameters | ||
---------- | ||
ds : xr.Dataset | ||
Dataset with "latitude" and "longitude" variables as well as their bounds variables. | ||
1D "latitude" and "longitude" variables are supported. This function will automatically | ||
broadcast them against each other. | ||
dcherian marked this conversation as resolved.
Show resolved
Hide resolved
dcherian marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Returns | ||
------- | ||
DataArray | ||
DataArray with shapely polygon per grid cell. | ||
""" | ||
import shapely | ||
|
||
grid = ds.cf[["latitude", "longitude"]].load() | ||
bounds = grid.cf.bounds | ||
dims = grid.cf.dims | ||
|
||
if "latitude" in dims or "longitude" in dims: | ||
# for 1D lat, lon, this allows them to be | ||
# broadcast against each other | ||
grid = grid.reset_coords() | ||
|
||
assert "latitude" in bounds | ||
assert "longitude" in bounds | ||
(lon_bounds,) = bounds["longitude"] | ||
(lat_bounds,) = bounds["latitude"] | ||
|
||
with xr.set_options(keep_attrs=True): | ||
(points,) = xr.broadcast(grid) | ||
|
||
bounds_dim = grid.cf.get_bounds_dim_name("latitude") | ||
points = points.transpose(..., bounds_dim) | ||
lonbnd = points[lon_bounds].data | ||
latbnd = points[lat_bounds].data | ||
|
||
if points.sizes[bounds_dim] == 2: | ||
lonbnd = lonbnd[..., [0, 0, 1, 1]] | ||
latbnd = latbnd[..., [0, 1, 1, 0]] | ||
|
||
elif points.sizes[bounds_dim] != 4: | ||
raise ValueError( | ||
f"The size of the detected bounds or vertex dimension {bounds_dim} is not 2 or 4." | ||
) | ||
|
||
# geopandas needs this | ||
mask = lonbnd[..., 0] >= 180 | ||
lonbnd[mask, :] = lonbnd[mask, :] - 360 | ||
Comment on lines
+1023
to
+1025
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the reason for this is that most geographic data is given in WGS84 which is -180...180 (I may be wrong here). So if you want to compare it to regional polygons it is probably a good idea to wrap the data. Still, it may be confusing to users. Maybe this could be optional. However, I am not sure what a good name is (In regionmask I call it |
||
|
||
polyarray = shapely.polygons(shapely.linearrings(lonbnd, latbnd)) | ||
|
||
# 'geometry' is a blessed name in geopandas. | ||
boxes = points[lon_bounds][..., 0].copy(data=polyarray).rename("geometry") | ||
|
||
return boxes | ||
Uh oh!
There was an error while loading. Please reload this page.