I am developing a workflow to perform a variety of operations on raster dataset using rasterio. My previous workflow involved lots of I/O when performing such operations on raster files. I would like to change the workflow so to process raster data in-memory. I am using rasterio.MemoryFile() class to achieve that. Here some of my code:

def mem_file(arr, metadata, *to_del_arr):
    Create and yield a Datareader using a numpy array
    and raster metadata
    with rasterio.MemoryFile() as memfile:
        with memfile.open(**metadata) as src: # Open as DatasetWriter
            if arr.ndim == 2:
                src.write_band(1, arr)
            for arr in to_del_arr:
                del arr

        with memfile.open() as src:  # Reopen as DatasetReader
            yield src

def resample_raster(src, scale=2):
    resample raster
    t = src.transform

    # rescale the metadata
    transform = rasterio.Affine(t.a / scale, t.b, t.c, t.d, t.e / scale, t.f)
    height = src.height * scale
    width = src.width * scale

    new_meta = copy.deepcopy(src.meta)
    new_meta.update(transform=transform, driver='GTiff', height=height,

    # resampling
    arr = src.read(resampling=rasterio.enums.Resampling.nearest)
    return mem_file(arr, new_meta, arr)

def create_raster_mask(src, vals):
    create a raster mask

    arr = src.read()
    mask_arr = np.ma.MaskedArray(arr, np.in1d(arr, vals))
    new_meta = copy.deepcopy(src.meta)
    new_meta.update(driver='GTiff', nbits=1)
    return mem_file(mask_arr.mask, new_meta, arr, mask_arr)

def another_operation(src):

The idea is to chain this operations together to build a workflow. Right now I can do that like so:

if __name__ == "__main__":
    with rasterio.open("tests/T37MBN_20190628T073621_SCL_20m.jp2") as src:
        with resample_raster(src) as resampled:
            with create_raster_mask(resampled, [3,7,8,9,10]) as mask:

But I would like to avoid such nested structure and have something more like:

if __name__ == "__main__":
    with rasterio.open("tests/T37MBN_20190628T073621_SCL_20m.jp2") as src:
        final = create_raster_mask(resample_raster(src))

Is there a way I can achieve that? Thanks


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.