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
-
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.Michael Stimson– Michael Stimson2019年10月22日 00:55:34 +00:00Commented 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 attributesJoe Ir– Joe Ir2019年10月22日 10:29:00 +00:00Commented Oct 22, 2019 at 10:29
1 Answer 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]))