Repository: corteva/rioxarray

Issue:
BUG: Clip with disjoint geometries drops parts not desired
Problem: https://gis.stackexchange.com/questions/361896/how-to-keep-the-cell-size-fixed-when-clipping-a-netcdf-tiff-with-a-shapefile-usi

Potential solution: Replace `drop=True` in the `where` method and instead use: https://rasterio.readthedocs.io/en/latest/api/rasterio.windows.html#rasterio.windows.get_data_window

Discussion:

Patch:
diff --git a/docs/history.rst b/docs/history.rst
index cf5c4702..da9c0abd 100644
--- a/docs/history.rst
+++ b/docs/history.rst
@@ -3,7 +3,8 @@ History
 
 Latest
 -------
-
+- BUG: Fix order of axis in `rio.isel_window` (pull #133)
+- BUG: Allow clipping with disjoint geometries (issue #132)
 
 0.0.28
 -------
diff --git a/rioxarray/rioxarray.py b/rioxarray/rioxarray.py
index 139555b1..6bf2a6be 100644
--- a/rioxarray/rioxarray.py
+++ b/rioxarray/rioxarray.py
@@ -23,6 +23,7 @@ from affine import Affine
 from rasterio.crs import CRS
 from rasterio.enums import Resampling
 from rasterio.features import geometry_mask
+from rasterio.windows import get_data_window
 from scipy.interpolate import griddata
 
 from rioxarray.crs import crs_to_wkt
@@ -592,7 +593,7 @@ class XRasterBase(object):
         row_slice = slice(int(math.floor(row_start)), int(math.ceil(row_stop)))
         col_slice = slice(int(math.floor(col_start)), int(math.ceil(col_stop)))
         return self._obj.isel(
-            {self.x_dim: row_slice, self.y_dim: col_slice}
+            {self.y_dim: row_slice, self.x_dim: col_slice}
         ).rio.set_spatial_dims(x_dim=self.x_dim, y_dim=self.y_dim, inplace=True)
 
 
@@ -1186,7 +1187,14 @@ class RasterArray(XRasterBase):
             },
             dims=(self.y_dim, self.x_dim),
         )
-        cropped_ds = self._obj.where(clip_mask_xray, drop=drop)
+        cropped_ds = self._obj.where(clip_mask_xray)
+        if drop:
+            cropped_ds.rio.set_spatial_dims(
+                x_dim=self.x_dim, y_dim=self.y_dim, inplace=True
+            )
+            cropped_ds = cropped_ds.rio.isel_window(
+                get_data_window(np.ma.masked_array(clip_mask_arr, ~clip_mask_arr))
+            )
         if self.nodata is not None and not np.isnan(self.nodata):
             cropped_ds = cropped_ds.fillna(self.nodata)
 


Test patch:
diff --git a/test/integration/test_integration_rioxarray.py b/test/integration/test_integration_rioxarray.py
index eccaf22c..76c35847 100644
--- a/test/integration/test_integration_rioxarray.py
+++ b/test/integration/test_integration_rioxarray.py
@@ -1448,8 +1448,8 @@ def test_isel_window():
         os.path.join(TEST_INPUT_DATA_DIR, "MODIS_ARRAY.nc")
     ) as mda:
         assert (
-            mda.rio.isel_window(Window.from_slices(slice(10, 12), slice(10, 12)))
-            == mda.isel(x=slice(10, 12), y=slice(10, 12))
+            mda.rio.isel_window(Window.from_slices(slice(9, 12), slice(10, 12)))
+            == mda.isel(x=slice(10, 12), y=slice(9, 12))
         ).all()
 
 
@@ -1597,9 +1597,9 @@ def test_nonstandard_dims_isel_window():
     ) as xds:
         reprojected = xds.rio.set_spatial_dims(
             x_dim="lon", y_dim="lat"
-        ).rio.isel_window(Window.from_slices(slice(5), slice(5)))
+        ).rio.isel_window(Window.from_slices(slice(4), slice(5)))
         assert reprojected.rio.width == 5
-        assert reprojected.rio.height == 5
+        assert reprojected.rio.height == 4
 
 
 def test_nonstandard_dims_error_msg():