python – Clipping a Raster with a Multipolygon Using Rasterio in Python

clipgeojsonpythonrasterio

I'm trying to write a function to clip rasters by a multi-polygon shapefile or GeoJSON in Python using rasterio.

So far, I found a good article that I've implemented, but it doesn't seem to work on clipping all polygons within a multi-polygon layer. Perhaps it is in this function below that prepares the GeoDataFrame for use in rasterio, which seems to only take the first feature geometry?


def getFeatures(gdf):
    """Function to parse features from GeoDataFrame in such a manner that rasterio wants them"""
    import json
    return [json.loads(gdf.to_json())['features'][0]['geometry']]

How would I clip a raster using a multi-polygon GeoJSON or shapefile in Python using rasterio?

Best Answer

Is this what you are looking for? I used this example integrated with a for loop.

Note that rasterio.mask.mask(src, shape, crop=True) needs to be changed to [shape] due to shapes (iterable object) – The values must be a GeoJSON-like dict or an object that implements the Python geo interface protocol (such as a Shapely Polygon).

import rasterio
import rasterio.mask
import fiona


shapefile = "C:/Users/user/Desktop/grid.shp"
image = "C:/Users/user/Desktop/image.tif"


def rasterio_clip(shapefile_path, raster_path):
    with fiona.open(shapefile_path, "r") as shapefile:
        shapes = [feature["geometry"] for feature in shapefile]

    for i, shape in enumerate(shapes):
        with rasterio.open(raster_path) as src:
            out_image, out_transform = rasterio.mask.mask(src, [shape], crop=True)
            out_meta = src.meta

        out_meta.update({"driver": "GTiff",
                    "height": out_image.shape[1],
                    "width": out_image.shape[2],
                    "transform": out_transform})

        with rasterio.open(f"C:/Users/user/Desktop/CLIPPED/clipped_{i}.tif", "w", **out_meta) as dest:
            dest.write(out_image)

rasterio_clip(shapefile, image)

enter image description here