Rasterio: Writing per-band masks

Created on 31 Mar 2020  路  2Comments  路  Source: mapbox/rasterio

I'm trying to write out a multi-band masked numpy array, and can't find a way to preserve each band's mask.

Steps to reproduce the problem.

import rasterio as rio
import numpy as np
from affine import Affine

ma3d = np.ma.array([
    [
        [1, 2],
        [3, 4]
    ],
    [
        [5, 6],
        [7, 8]
    ]
], mask=[
    [
        [True, False],
        [False, True]
    ],
    [
        [False, False],
        [True, True]
    ]
], dtype=np.uint8)

meta = {
    'driver': 'GTiff',
    'height': ma3d.shape[1],
    'width': ma3d.shape[2],
    'count': ma3d.shape[0],
    'dtype': ma3d.dtype,
    'transform': Affine.identity(),
}
>>> ma3d

masked_array(
  data=[[[--, 2],
         [3, --]],

        [[5, 6],
         [--, --]]],
  mask=[[[ True, False],
         [False,  True]],

        [[False, False],
         [ True,  True]]],
  fill_value=999999,
  dtype=uint8)



md5-2c382e623e33ef7b6a6061214bc6e9e8



with rio.open('temp.tif', 'w+', **meta) as dataset:
    dataset.write(ma3d)
    dataset.write_mask(~ma3d.mask)
    ma3d_out = dataset.read(masked=True)



md5-8ed9f343d8723028b35a4ff4600b4842



>>> ma3d_out

masked_array(
  data=[[[--, 2],
         [3, --]],

        [[5, 6],
         [7, 8]]],
  mask=[[[ True, False],
         [False,  True]],

        [[False, False],
         [False, False]]],
  fill_value=999999,
  dtype=uint8)

The mask is preserved for the first band, but the second band has no masked values.

What's the proper way to do this? Am I doing something wrong? It doesn't look like there's an option to write masks one band at a time.

Operating system

Ubuntu 18.04

Rasterio version and provenance

rasterio 1.0.28 py36hdff7cfa_1 conda-forge

Most helpful comment

Hi @khornlund
Thanks for opening this issue. We usually use https://rasterio.groups.io/ when facing this kind of problem.

The GDAL Mask specification (described in https://gdal.org/development/rfc/rfc15_nodatabitmask.html) says that there can be only one mask layer per dataset and is shared with all the data band. Thus you cannot save per band mask.

GMF_PER_DATASET(0x02): The mask band is shared between all bands on the dataset.

I suggest to use nodata value.

All 2 comments

Hi @khornlund
Thanks for opening this issue. We usually use https://rasterio.groups.io/ when facing this kind of problem.

The GDAL Mask specification (described in https://gdal.org/development/rfc/rfc15_nodatabitmask.html) says that there can be only one mask layer per dataset and is shared with all the data band. Thus you cannot save per band mask.

GMF_PER_DATASET(0x02): The mask band is shared between all bands on the dataset.

I suggest to use nodata value.

Thanks @vincentsarago ! That's right, there's only one per-dataset mask.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sgillies picture sgillies  路  3Comments

astrojuanlu picture astrojuanlu  路  4Comments

sgillies picture sgillies  路  5Comments

atorch picture atorch  路  3Comments

vincentsarago picture vincentsarago  路  3Comments