9

I was trying to get Rasterio to save a 3 band raster to a TIFF file. For some reason, the example in the documentation only shows how to save raster with only 1 band. Now when I tried to save a 3 band raster, I get a really uninformative error message.

The code is below. I opened a raster to collect some of the metadata. Then I created a new downsampled version of the raster and was trying to save that to a new file. The raster has 3 bands.

dat = rasterio.open('image_original.tif')

with rasterio.open('image_original.tif') as dataset:
    data = dataset.read(
        out_shape=(int(dataset.height / 3.75), int(dataset.width / 3.75), dataset.count),
        resampling=Resampling.cubic
    )

with rasterio.open(
    'image_15cm.tif',
    'w',
    driver='GTiff',
    height=data.shape[0],
    width=data.shape[1],
    count=data.shape[2],
    dtype=data.dtype,
    crs=dat.crs,
    transform=dat.transform,
) as dst:
    dst.write(data, 3) //PROBLEM LINE

So this last line creates problems. I wrote dst.write(data,3) and get an error:

ValueError: Source shape (1, 11404, 15902, 3) is inconsistent with given indexes 1

Alternatively if I use the code dst.write(data) then I get the message

ValueError: Source shape (11404, 15902, 3) is inconsistent with given indexes 3

which still does not indicate what the problem is or how to solve it.

Vince
  • 20,017
  • 15
  • 45
  • 64
krishnab
  • 909
  • 1
  • 12
  • 23

1 Answers1

7

dst.write(data) is the way to write a 3D array to raster. However, rasterio is expecting data in (bands, rows, cols) order and you are passing a (rows, cols, bands) order array.

Try

data = dataset.read(
    out_shape=(dataset.count, int(dataset.height / 3.75), int(dataset.width / 3.75)),
    resampling=Resampling.cubic
)

Also note that your transform is incorrect, it needs to be changed to include the resampled pixel sizes. I suggest you have a look at how I modify the transform in this answer - "Creating an in memory rasterio Dataset from numpy array"

user2856
  • 65,736
  • 6
  • 115
  • 196
  • 1
    Haha, is it that simple. I really wish the documentation would have some better examples to avoid this confusion. I will see if I can submit a pull request to them or at least submit an issue. Thanks so much. – krishnab Jul 25 '19 at 00:35
  • yep, I will start by opening an issue and proposing some new examples. If the developers are amenable, I can create a pull request for the documentation. – krishnab Jul 25 '19 at 00:41
  • @krishnab your transform will also be incorrect. I suggest you have a look at how I modify the transform in this answer - creating-an-in-memory-rasterio-dataset-from-numpy-array – user2856 Jul 25 '19 at 00:58
  • Oh man, thanks for anticipating my next issue. I really do appreciate your assistance. I will look at the link that you posted and try and adjust accordingly. – krishnab Jul 25 '19 at 01:04