0

I have a lot of output land cover raster files in .tif and want to only select the .tif files and change color map of all of them by taking a script that has attributes for Red, Green, Blue and LC Type. I have a list of raster values for colors and the associated land cover type; however, I know I am supposed to take the proportion of each RGB value out of 255 to properly assign the new color. I want to loop through each .tif file create the fields (Red, Green, Blue, and LC Type) and assign the appropriate value using a dictionary in ArcPy.

filepath = 'C:/directory'
env.workspace =filepath
for filename in os.listdir(filepath):
 if filename.endswith('.tif')
dictionary = {
 1: [255,0,0 'water'],
 2: [209, 255, 115 'Evergreen Needleleaf Forest'],
 3: [85,255,0 'Evergreen Broadleaf Forest'],
 4: [112,168,0 'Deciduous Needleleaf Forest'],
 5: [190,255,232 'Deciduous Broadleaf Forest'],
 6: [255,211,127 'Mixed Forest'],
 7: [0,255,0'Woodland'],
 8: [0,99,0 'Wooded Grassland'],
 9: [214,157,188 'Closed Shrubland'],
 10: [197, 0, 255'Open Shrubland'],
 11: [0,77,168 'Grassland'],
 12: [0,132,168 'Cropland'],
 13: [190,210,255 'Bare Ground'],
 14: [255,170,0 'Urban and Built-up'],
 17: [255,170,0 'Urban and Built-up']}
#create the four attributes, R,G,B, and LC
#create an update cursor
#loop through each .tif file create fields and assign values to records
PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Oct 22, 2019 at 0:34
2
  • Related : gis.stackexchange.com/questions/123606/… however there is a process of applying a color table desktop.arcgis.com/en/arcmap/10.3/manage-data/raster-and-images/… that might help with what you're trying to do. Commented Oct 22, 2019 at 0:55
  • I am aware that is an option, but that won't really work given number of raster files I have and would be more efficient if I could just loop through the ones in my folder and apply it in this tabular format where I can later add more attributes Commented Oct 22, 2019 at 10:29

1 Answer 1

1

I really think a colour table is what you're after, it's just a text file with the same base name as the TIFF image with '.clr' as the extension, when loaded into ArcMap the symbology is automatically imported from the colour file.. From your existing code I have extended to create a color file, build the raster attribute table and then apply the dictionary values to the RAT.

import os, sys, arcpy
filepath = 'C:/directory'
arcpy.env.workspace = filepath
# note that you need more commas in your dictionary def
# to separate LC code from the blue value
dictionary = {
 1: [255,0,0,'water'],
 2: [209, 255, 115,'Evergreen Needleleaf Forest'],
 3: [85,255,0,'Evergreen Broadleaf Forest'],
 4: [112,168,0,'Deciduous Needleleaf Forest'],
 5: [190,255,232,'Deciduous Broadleaf Forest'],
 6: [255,211,127,'Mixed Forest'],
 7: [0,255,0,'Woodland'],
 8: [0,99,0,'Wooded Grassland'],
 9: [214,157,188,'Closed Shrubland'],
 10: [197, 0, 255,'Open Shrubland'],
 11: [0,77,168,'Grassland'],
 12: [0,132,168,'Cropland'],
 13: [190,210,255,'Bare Ground'],
 14: [255,170,0,'Urban and Built-up'],
 17: [255,170,0,'Urban and Built-up']}
for filename in os.listdir(filepath):
 fN,fE = os.path.splitext(filename) # break the name and extension
 if fE.lower == '.tif': # more reliable than endswith
 if arcpy.Describe(filename).isInteger: # can't build RAT on non-integer rasters
 arcpy.AddMessage('Bulding for {}'.format(filename))
 # add a new RAT and required attributes
 arcpy.BuildRasterAttributeTable_management(filename,'OVERWRITE') 
 arcpy.AddField_management(filename,'R','SHORT') # add the R,G and B fields
 arcpy.AddField_management(filename,'G','SHORT') # as data type 'short' which
 arcpy.AddField_management(filename,'B','SHORT') # is the smallest int type
 arcpy.AddField_management(filename,'LC_Type','TEXT') # Land cover type as text, field names can't have spaces
 # build a colour file to symbolize
 CLRfilename = os.path.join(filepath,fN + '.clr')
 with open (CLRfilename, 'w') as CLR:
 for Detail in dictionary.iterkeys():
 R,G,B,LC = dictionary[Detail] #unpack this element in the dictionary
 CLR.write('{} {} {} {}\n'.format(Detail,R,G,B))
 arcpy.AddMessage('Created or overwritten colour file')
 # Iterate the rows in the raster attribute table
 with arcpy.da.UpdateCursor(filename,['value','R','G','B','LC_Type']) as UCur:
 for URow in UCur:
 ThisIndex = URow[0] # the value for this pixel
 if ThisIndex in dictionary: # only use values that exist in the dictionary
 R,G,B,LC = dictionary[ThisIndex] # unpack this element in the dictionary
 URow[1] = R 
 URow[2] = G 
 URow[3] = B 
 URow[4] = LC
 UCur.updateRow(URow)
 else:
 arcpy.AddWarning("Cannot do {}, it's not an integer type".format(filename))

Then if you need to export any changes to your R,G,B values in your raster dataset you can reexport the colour table like this:

desc = arcpy.Describe(yourRaster)
cPath = desc.catalogPath # the full path your your raster dataset
CLRfilename = fN + '.clr'# fN already contains the path
with (CLRfilename, 'w') as CLR:
 with arcpy.da.SearchCursor(InRas,['value','R','G','B']) as SCur:
 for SRow in SCur:
 CLR.write('{} {} {} {}\n'.format(SRow[0],SRow[1],SRow[2],SRow[3]))
answered Oct 28, 2019 at 3:38

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.