Rasterio – Creating an In-Memory Raster for Efficient Processing

rasterio

Note that this is not the same as Creating an in memory rasterio Dataset from numpy array.

Currently I have a workflow which creates a "template raster" from which other rasters are derived. However, this template raster is written to disk, which is not very efficient:

import rasterio

rst = rasterio.open("test.tif", 'w+', driver='GTiff',
                    height=5, width=5,
                    count=1, dtype=rasterio.float32,
                    crs='+proj=utm +zone=36 +south +ellps=WGS84 +towgs84=0,0,0,-0,-0,-0,0 +units=m +no_defs',
                    transform=rasterio.transform.from_origin(0, 0, 5, 5))

I'm trying to figure out a way to initialize this raster purely in memory but in such a way that I can still access its properties and methods like:

  • rst.index(0, 0)
  • rst.meta
  • rst.shape

I am trying to use MemoryFile, but I can't find any examples of creating such a memory-based file directly, rather it is usually used for opening an existing disk file or a numpy array, like in the question I linked at the beginning.

Is there a way to be able to open a MemoryFile using the same parameters as rasterio.open(...)? So far the closest I can get is:

rst = rasterio.open("test.tif", 'w+', driver='GTiff',
                    height=5, width=5,
                    count=1, dtype=rasterio.float32,
                    crs='+proj=utm +zone=36 +south +ellps=WGS84 +towgs84=0,0,0,-0,-0,-0,0 +units=m +no_defs',
                    transform=rasterio.transform.from_origin(0, 0, 5, 5))

profile = rst.profile

memfile = MemoryFile()
memfile.open(**profile)

But this still requires making a file on disk.

Best Answer

I should have looked harder, it turns out it is just as simple as passing almost the same parameters to memfile.open():

memfile = MemoryFile()
rst = memfile.open(driver='GTiff', height=5, width=5, count=1, dtype=rasterio.float32,
                   proj=utm +zone=36 +south +ellps=WGS84 +towgs84=0,0,0,-0,-0,-0,0 +units=m +no_defs', transform=rasterio.transform.from_origin(0, 0, 5, 5)

It then behaves (as far as I can tell, just like a typical raster dataset object.