2

I get the following error when trying to clip a GeoTiff to a shapefile: "No data found in bounds."

Steps to reproduce:

import rioxarray as riox

rain = riox.open_rasterio(
    "https://s3-ap-southeast-2.amazonaws.com/silo-open-data/daily/daily_rain/2001/20010101.daily_rain.tif"
)
rain
<xarray.DataArray (band: 1, y: 681, x: 841)>
[572721 values with dtype=float32]
Coordinates:
  * band         (band) int64 1
  * y            (y) float64 -10.0 -10.05 -10.1 -10.15 ... -43.9 -43.95 -44.0
  * x            (x) float64 112.0 112.0 112.1 112.1 ... 153.8 153.9 153.9 154.0
    spatial_ref  int64 0
Attributes:
    _FillValue:    -32767.0
    scale_factor:  1.0
    add_offset:    0.0
    long_name:     Daily rainfall
    units:         mm
    grid_mapping:  spatial_ref
rain.rio.crs
CRS.from_epsg(4326)
geom = [{'type': 'Polygon',
  'coordinates': [[[149.8422409924085, -30.2606878927815],
    [149.8432272914562, -30.260198054517836],
    [149.84674418853774, -30.258451413106968],
    [149.84699580073607, -30.25832645173489],
    [149.86067125124407, -30.25522463855303],
    [149.86064473604847, -30.255375372072535],
    [149.86158897369342, -30.255160332512734],
    [149.87138973091908, -30.25358008629615],
    [149.8749496072403, -30.25278056138403],
    [149.87751267502404, -30.25210408302803],
    [149.88000469636745, -30.250997066023213],
    [149.88698199640032, -30.249275066568426],
    [149.88897543361065, -30.248906051660306],
    [149.89260653623649, -30.25025904775652],
    [149.89267758267692, -30.252473085924183],
    [149.89832667009966, -30.2588351623366],
    [149.90122866864897, -30.262103431198284],
]]}]

rain.rio.clip(geom)
NoDataInBounds                            Traceback (most recent call last)
<ipython-input-64-9fe38157f4ee> in <module>
----> 1 rain.rio.clip(geom)

/opt/conda/lib/python3.8/site-packages/rioxarray/raster_array.py in clip(self, geometries, crs, all_touched, drop, invert, from_disk)
    729             or cropped_ds.coords[self.y_dim].size < 1
    730         ):
--> 731             raise NoDataInBounds(
    732                 f"No data found in bounds.{_get_data_var_message(self._obj)}"
    733             )

NoDataInBounds: No data found in bounds.

NOTE: the geometry x and y max and min are within the max and min x, y of the GeoTiff!

0

2 Answers 2

5

Your polygon is very small compared to the pixel size and it doesn't contain the centre of any pixels.

Just to demonstrate, here's an image showing the outlines of the pixels of your raster with their centres shown as points and your polygon overlaid.

enter image description here

If you pass all_touched=True then you'll get two pixels returned.

all_touched (boolean, optional) – If True, all pixels touched by geometries will be burned in. If false, only pixels whose center is within the polygon or that are selected by Bresenham’s line algorithm will be burned in.

rain.rio.clip(geom, all_touched=True)

Output:

<xarray.DataArray (band: 1, y: 1, x: 2)>
array([[[0., 0.]]], dtype=float32)
Coordinates:
  * y            (y) float64 -30.25
  * x            (x) float64 149.8 149.9
  * band         (band) int64 1
    spatial_ref  int64 0
Attributes:
    scale_factor:  1.0
    add_offset:    0.0
    long_name:     Daily rainfall
    units:         mm
    grid_mapping:  spatial_ref
    _FillValue:    -32767.0
1

I got the same error but with a polygon of the size of a country on a european-wide dataset. But if I crop the dataset before applying the function, then it works.

bounds = polygons_wgs84_gdf.bounds
min_lat = bounds.miny.values[0]
max_lat = bounds.maxy.values[0]
min_lon = bounds.minx.values[0]
max_lon = bounds.maxx.values[0]
ds = ds.where((ds.latitude > min_lat) & (ds.latitude < max_lat), drop=True)
ds = ds.where((ds.longitude > min_lon) & (ds.longitude < max_lon), drop=True)

maybe using rio.clip_box() would work too

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.