4

I'm trying to set 'noData' values for a 3-band raster image, in a Python script. For this I am using ArcPy function "SetRasterProperties_management" with the following syntax: arcpy.SetRasterProperties_management(rasterImage,nodata="1 0;2 45;3 12"). As you can see I need to set different values for each band.

My problem is that the above syntax does not seem to work because when I check the raster image properties the no data value is set to "12" (last value specified), and this for all bands. I saw at Setting NoData for a multiband raster? that someone tried to do the same. I used the syntax that was advised (nodata="1 0;2 45;3 12") but it did not work. I also looked at "SetRasterProperties_management" function documentation but I could not find the right syntax to make it work.

Here is a code snippet:

rasterImage = "test-raster.tif"  
arcpy.SetRasterProperties_management(rasterImage,nodata="1 0;2 45;3 12")

Could someone help me?

  • Can you also describe what you mean by "it did not work", please? Was there an error message? – PolyGeo Sep 27 '16 at 10:34
  • There was no error message but when I checked the raster image properties the noData value was set to "12" (the last value provided) for all bands, whereas according to the documentation it should have been "Band 1: 0", "Band 2: 45", "Band 3: 12". – Flo Sep 27 '16 at 10:55
  • I just tried this out on a 3 band .tif on Arcmap - ArcGIS 10.4 and it behaved as you described above, with no error message. The last NoData value read in gets assigned to all the bands. The syntax you have in your question is correct. It appears the tool is not performing as described in the documentation – Nxaunxau Sep 27 '16 at 14:41
  • Thank you for your reply. This means I was not doing it wrong. But I still wonder how to perform this multiple noData value assignment properly, since the documentation says it can be done. – Flo Sep 27 '16 at 15:17
1

For me the syntax that it worked was the one which is in the ArcGIS Help for the tool:

[band index, nodata_value],...]

So, it should be something like:

arcpy.SetRasterProperties_management("multiband.tif", "GENERIC", "", "", [["1", 10], ["2", 20], ["3", 30]])

And that is working for me in ArcGIS 10.3. With this I am just saying which are the values that I want to exclude. But I am not sure if you want to do that, or if you want to change the NoData values already present in your bands (black frame in Landsat, for example) to any other different values, in that case you better do a Con or a Reclassify... Or even better work reading the raster bands as arrays (it could be done in arcpy but I find rasterio easier and faster for that kind of process).

  • I just tried the syntax you suggested ([["1", 10], ["2", 20], ["3", 30]]) but it unfortunately still did not work. NoData value is set to "30" (last value, for band 3, specified) for all bands. I am using ArcGIS 10.3 too and I still cannot understand why setting different noData values for a 3-band raster is so complicated. – Flo Sep 27 '16 at 19:41
0

Just to let you know the results of my investigation and give an alternative to set no data value for multiband image.

1/ I really think there is a bug in ArcGIS 10.3 and 10.3.1 (I tried with both versions) in the 'Set Raster Properties (Management)' tool because even the graphical tool does not work as expected.

2/ I found another way to set the noData value for a multiband image by using ArcObjects. Here is the corresponding code snippet if you need it.

Info: I am using Pierssen's Snippets module in order to access ArcObjects from Python. See Accessing ArcObjects from Python and Pierssen Snippet module for more information.

import os
import Snippets    
import comtypes.gen.esriGeoDatabase as esriGeoDatabase
import comtypes.gen.esriDataSourcesRaster as esriDataSourcesRaster


# Absolute path to the raster
raster = r'C:\Temp\myMultiBandRaster.tif'

# NoData values list for each of the 3 bands
noDataValuesList = [15, 0, 34]

# Open the workspace
pWSFactory = Snippets.NewObj(esriDataSourcesRaster.RasterWorkspaceFactory, esriGeoDatabase.IWorkspaceFactory2)
pWS = pWSFactory.OpenFromFile(os.path.dirname(raster), 0)

# Open the raster dataset
pRasterWS = pWS.QueryInterface(esriDataSourcesRaster.IRasterWorkspace)  # Cast to 'IRasterWorkspace' to call 'OpenRasterDataset' function
pRasterDataset = pRasterWS.OpenRasterDataset(os.path.basename(raster))

# Get access to bands
pRasterBands = pRasterDataset.QueryInterface(esriDataSourcesRaster.IRasterBandCollection)

for index,val in enumerate(noDataValuesList):
    # Get band
    pBand = pRasterBands.Item(index)
    # Get corresponding properties object
    pPropsBand = pBand.QueryInterface(esriDataSourcesRaster.IRasterProps)
    # Set noData value
    pPropsBand.NoDataValue = val

Hope this will help some of you who encountered the same problem.

Your Answer

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

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