-
Notifications
You must be signed in to change notification settings - Fork 1
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
Grid changes when resampling after clip #12
Comments
Claude says:
import xarray as xr
import rioxarray
def align_and_resample(
da: xr.DataArray,
target_resolution: float,
bounds: tuple,
align_pixels: bool = True
) -> xr.DataArray:
"""
Properly aligns and resamples a DataArray while maintaining pixel alignment.
Parameters
----------
da : xarray.DataArray
Input DataArray with spatial coordinates
target_resolution : float
Desired resolution in units of the input data's CRS
bounds : tuple
(minx, miny, maxx, maxy) in the input data's CRS
align_pixels : bool, default True
If True, ensures pixels are aligned to the target resolution grid
Returns
-------
xarray.DataArray
Resampled and aligned DataArray
"""
# Extract bounds
minx, miny, maxx, maxy = bounds
if align_pixels:
# Align bounds to target resolution grid
minx = round(minx / target_resolution) * target_resolution
maxx = round(maxx / target_resolution) * target_resolution
miny = round(miny / target_resolution) * target_resolution
maxy = round(maxy / target_resolution) * target_resolution
# Calculate number of pixels
nx = int(round((maxx - minx) / target_resolution))
ny = int(round((maxy - miny) / target_resolution))
# Create target coordinates
new_x = np.linspace(minx + target_resolution/2,
maxx - target_resolution/2,
nx)
new_y = np.linspace(maxy - target_resolution/2,
miny + target_resolution/2,
ny)
# Create template DataArray with desired grid
template = xr.DataArray(
np.zeros((ny, nx)),
coords={
'y': new_y,
'x': new_x
},
dims=['y', 'x']
)
# Add CRS if present in original
if hasattr(da, 'rio'):
template.rio.write_crs(da.rio.crs, inplace=True)
# Reproject input data to match template
result = da.rio.reproject_match(template)
return result The difference you're seeing occurs because:
To solve this, I've provided a function that:
You can use it like this: # Define your target resolution and bounds
target_resolution = 0.05
bounds = (minx, miny, maxx, maxy)
# Process your data
result = align_and_resample(da_seas5, target_resolution, bounds) This approach will give you consistent results regardless of the order of operations. The key benefits are:
|
Looks like @zackarno found the solution here! #13 (comment) |
After a bunch of testing, I've noticed that some pcodes have slightly different raster stats outputs based on whether resampling to a 0.05 degree grid is done before or after clipping to a given bounding box.
So for example:
vs
We can see the impact of this when we take a look at the rasterized admin boundaries from the two separate grids:
Screen.Recording.2024-10-31.at.3.50.05.PM.mov
The text was updated successfully, but these errors were encountered: