3

I have a numpy array which I would like to open as a raster in GDAL. Currently the only way I can find to do this is to save the raster as an image to the file system and then open it again. I was hoping that there would be a way that I could just create an in-memory raster from a numpy array and then set its transformation and coordinate system manually.

The closest thing I can find is here: https://gis.stackexchange.com/a/37431/48798

And came up with this solution:

        nrows, ncols = self.paths_array.shape

        # Explanation for this mess: https://rasterio.readthedocs.io/en/latest/topics/migrating-to-v1.html
        top_left = (self.ref_img.meta["transform"][2], self.ref_img.meta["transform"][5])
        geotransform = (self.ref_img.meta["transform"][2],
                        self.ref_img.meta["transform"][0],
                        self.ref_img.meta["transform"][1],
                        self.ref_img.meta["transform"][5],
                        self.ref_img.meta["transform"][3],
                        self.ref_img.meta["transform"][4])

        driver = gdal.GetDriverByName("GTiff")
        raster = driver.Create("myraster", ncols, nrows, 1, gdal.GDT_Int16)
        raster.SetGeoTransform(geotransform)
        srs = osr.SpatialReference()
        srs.ImportFromEPSG(self.srid)  # My SRID
        raster.SetProjection(srs.ExportToWkt())
        raster.GetRasterBand(1).WriteArray(self.paths_array) # My Numpy array with data

By the way, I realize that it is sort of odd that I am taking the result of a rasterio raster and turning it into a gdal raster. The reason for this is that there is a very good algorithm that we found that is written using the Python GDAL bindings, and so we have to switch from rasterio to pure GDAL for this part

But it seems to be written for using the GTiff driver, which will create the file on disk. I thought I could avoid this by using the Memory driver:

    nrows, ncols = self.paths_array.shape

    # Explanation for this mess: https://rasterio.readthedocs.io/en/latest/topics/migrating-to-v1.html
    top_left = (self.ref_img.meta["transform"][2], self.ref_img.meta["transform"][5])
    geotransform = (self.ref_img.meta["transform"][2],
                    self.ref_img.meta["transform"][0],
                    self.ref_img.meta["transform"][1],
                    self.ref_img.meta["transform"][5],
                    self.ref_img.meta["transform"][3],
                    self.ref_img.meta["transform"][4])

    driver = gdal.GetDriverByName("Memory")
    raster = driver.Create("myraster", ncols, nrows, 1, gdal.GDT_Int16)
    raster.SetGeoTransform(geotransform)
    srs = osr.SpatialReference()
    srs.ImportFromEPSG(self.srid)
    raster.SetProjection(srs.ExportToWkt())
    raster.GetRasterBand(1).WriteArray(self.paths_array)

However, no luck. When I use the Memory as input to gdal.GetDriverByName(), then the result of driver.Create("myraster", ncols, nrows, 1, gdal.GDT_Int16) is None.

2
  • When you use the MEM raster format, what you get at the end is a pointer to an open GDAL dataset, in effect what you get from gdal.Open().
    – Jose
    Apr 28, 2020 at 14:26
  • Thanks, Jose, I was posting an answer just as you commented, if you want to post that as an answer I will accept that one instead.
    – wfgeo
    Apr 28, 2020 at 14:27

1 Answer 1

4

It turns out it was a rather simple goof. Memory is the keyword for an in-memory vector dataset, while MEM is the keyword for an in-memory raster dataset. I even linked the page for vector datasets in my question, the correct link is here:

https://gdal.org/drivers/raster/mem.html

Replacing Memory with MEM works.

Your Answer

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

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