Hi Guys,
I want to calculate the counts of each landuse type based on the unique landuse code from each raster datasets.
Raster dataset consists of six major landuse and their unique codes are below:
1) Agriculture : Landuse code(2100, 2200, 2300, 2400)
2) Barren Land: Landuse code( 7100,7200,7300,7400, 7500, 7600)
3)Forest: Landuse code(4110, 4120, 4210,4220, 4230, 4311, 4312,4321,4322, 4410)
4)Urban: Landuse code(1110,1120,1130,1140,1150,1200,1211,1214,1300,1400,1410,1411,1420,1440,1462,1463,1499,1500,1600,1700,1710,1741)
5)Water: Landuse code(1419,5100,5190)
6)Wetlands Landuse code (1461,1711,1750,1850)
Also, I want to divide the Urban area further into 4 categories.
I have the code only for agricultural area to simply test whether the code is working or not for one category of landuse. When I ran the code neither did I get any error message nor the result for agricultural land. I know it's a pretty big description, sorry for that. Thank you very much for your time and help!
I am providing the code below:
import arcpy, os from arcpy import env #To overwrite output arcpy.env.overwriteOutput = True #Set environment settings env.workspace = "C:/Subhasis/Project-06-02-14/Landuse/New folder/Merged/Landuse_raster" outws="C:/Subhasis/Project-06-02-14/Landuse/New folder/Merged/Landuse_raster/Table" inraster = arcpy.ListRasters("*", "GRID") for i in inraster: flds = ("VALUE", "COUNT") dct = {row[0]:row[1] for row in arcpy.da.SearchCursor(i, flds)} Agriculture=[] Barrenland=[] Forest=[] Urban=[] Water=[] Wetland=[] for j in dct: if (dct.keys()==2100) & (dct.keys()==2200) & (dct.keys()==2300) & (dct.keys()==2400): ag=Agriculture.append(dct.values()) print ag else: break
Solved! Go to Solution.
Hi Ian Murray and Inception Woznicki,
I would probably still use dictionaries. They provide a flexible way of processing this kind of problems. Take a look at the code below (please note that I did not test the code, so I am sure there will still be some errors in it).
import arcpy, os
#Set environment settings
arcpy.env.overwriteOutput = True
arcpy.env.workspace = "C:/Subhasis/Project-06-02-14/Landuse/New folder/Merged/Landuse_raster"
# you're not use this workspace in your code, but I suppose you eventually will.
# outws="C:/Subhasis/Project-06-02-14/Landuse/New folder/Merged/Landuse_raster/Table"
# configuration of lists of values
lst_agr = [2100, 2200, 2300, 2400] # agriculture
lst_bar = [7100, 7200, 7300, 7400, 7500, 7600] # Barren Land
lst_for = [4110, 4120, 4210, 4220, 4230, 4311, 4312, 4321, 4322, 4410] # Forest
lst_urb = [1110, 1120, 1130, 1140, 1150, 1200, 1211, 1214, 1300, 1400,
1410, 1411, 1420, 1440, 1462, 1463, 1499, 1500, 1600, 1700,
1710, 1741] # Urban
lst_wat = [1419, 5100, 5190] # Water
lst_wet = [1461, 1711, 1750, 1850] # Wetlands
# Create a dictionary with the classname vs the lists
dct_lsts = {"Agriculture": lst_agr, "Barren Land": lst_bar,
"Forest": lst_for, "Urban": lst_urb,
"Water": lst_wat, "Wetlands": lst_wet}
# optionally, divide the Urban area further into 4 categories.
# instead of creating 1 list, create 4 separate lists, like this:
##lst_urb1 = [1110, 1120, 1130, 1140, 1150, 1200]
##lst_urb2 = [1211, 1214, 1300, 1400, 1410, 1411]
##lst_urb3 = [1420, 1440, 1462, 1463, 1499, 1500]
##lst_urb4 = [1600, 1700, 1710, 1741]
##dct_lsts = {"Agriculture": lst_agr, "Barren Land": lst_bar,
## "Forest": lst_for, "Urban 1": lst_urb1,
## "Urban 2": lst_urb2, "Urban 3": lst_urb3,
## "Urban 4": lst_urb4, "Water": lst_wat,
## "Wetlands": lst_wet }
# loop through rasters
flds = ("VALUE", "COUNT")
lst_ras = arcpy.ListRasters("*", "GRID")
for ras in lst_ras:
# create dct with value vs count for this raster:
dct = {row[0]:row[1] for row in arcpy.da.SearchCursor(ras, flds)}
# now create an initial dictionay that will hold the resulting counts per LU class
dct_res = {lu: 0 for lu in dct_lsts.keys()}
# now fill the resulting dictionary
for val, cnt in dct.items():
# determine the lu class and add count
for lu, lst in dct_lsts.items():
if val in lst:
dct_res[lu] += cnt
break
# now print the result:
print "\nLanduse statistics for raster: '{0}'".format(ras)
for lu, cnt in dct_res:
print " - {0}: {1}".format(lu, cnt)
This is what happens (if the code works):
Writing this down, I think you could also create a reference table with the pixelvalues on each row and the corresponding landuse classname in another column and join this table to the attribute table of the raster and perform a summerize on the landuse class column, summing the count...
Kind regards,
Xander
A raster cell can only have a single value, currently you are using and statements, not or statements and it would be impossible for your value to be 2100, 2200, 2300, and 2400 simultaneously. Try replacing your &'s with or's
Thank you very much Ian! I ran the code replacing &'s by or's . still didn't get any error or the result.
Looking at it again I see another problem.
ag = Agriculture.append(dct.values()))
append it used to add a value or string to a list, so making a new variable equal to an append will do nothing to the variable, though it will actually append your value to the list append is being called on(in this case Agriculture).
try
Agriculture.append(dct.values())
print Agriculture
Thanks again Ian!. Changed the code, but don't know still I didn't get anything.
Doesn't help I'm not very good with dictionaries. If I was doing this, I'd probably convert my raster to an ASCII file, so I could run my script without ArcGIS. Then I'd would just iterate over each line and value in the ascii and check the value against your values, and append to a list.
Xander Bakker, you mind taking a look at this?
Thank You very much Ian! Yeah, that's a good idea.
Hi Ian Murray and Inception Woznicki,
I would probably still use dictionaries. They provide a flexible way of processing this kind of problems. Take a look at the code below (please note that I did not test the code, so I am sure there will still be some errors in it).
import arcpy, os
#Set environment settings
arcpy.env.overwriteOutput = True
arcpy.env.workspace = "C:/Subhasis/Project-06-02-14/Landuse/New folder/Merged/Landuse_raster"
# you're not use this workspace in your code, but I suppose you eventually will.
# outws="C:/Subhasis/Project-06-02-14/Landuse/New folder/Merged/Landuse_raster/Table"
# configuration of lists of values
lst_agr = [2100, 2200, 2300, 2400] # agriculture
lst_bar = [7100, 7200, 7300, 7400, 7500, 7600] # Barren Land
lst_for = [4110, 4120, 4210, 4220, 4230, 4311, 4312, 4321, 4322, 4410] # Forest
lst_urb = [1110, 1120, 1130, 1140, 1150, 1200, 1211, 1214, 1300, 1400,
1410, 1411, 1420, 1440, 1462, 1463, 1499, 1500, 1600, 1700,
1710, 1741] # Urban
lst_wat = [1419, 5100, 5190] # Water
lst_wet = [1461, 1711, 1750, 1850] # Wetlands
# Create a dictionary with the classname vs the lists
dct_lsts = {"Agriculture": lst_agr, "Barren Land": lst_bar,
"Forest": lst_for, "Urban": lst_urb,
"Water": lst_wat, "Wetlands": lst_wet}
# optionally, divide the Urban area further into 4 categories.
# instead of creating 1 list, create 4 separate lists, like this:
##lst_urb1 = [1110, 1120, 1130, 1140, 1150, 1200]
##lst_urb2 = [1211, 1214, 1300, 1400, 1410, 1411]
##lst_urb3 = [1420, 1440, 1462, 1463, 1499, 1500]
##lst_urb4 = [1600, 1700, 1710, 1741]
##dct_lsts = {"Agriculture": lst_agr, "Barren Land": lst_bar,
## "Forest": lst_for, "Urban 1": lst_urb1,
## "Urban 2": lst_urb2, "Urban 3": lst_urb3,
## "Urban 4": lst_urb4, "Water": lst_wat,
## "Wetlands": lst_wet }
# loop through rasters
flds = ("VALUE", "COUNT")
lst_ras = arcpy.ListRasters("*", "GRID")
for ras in lst_ras:
# create dct with value vs count for this raster:
dct = {row[0]:row[1] for row in arcpy.da.SearchCursor(ras, flds)}
# now create an initial dictionay that will hold the resulting counts per LU class
dct_res = {lu: 0 for lu in dct_lsts.keys()}
# now fill the resulting dictionary
for val, cnt in dct.items():
# determine the lu class and add count
for lu, lst in dct_lsts.items():
if val in lst:
dct_res[lu] += cnt
break
# now print the result:
print "\nLanduse statistics for raster: '{0}'".format(ras)
for lu, cnt in dct_res:
print " - {0}: {1}".format(lu, cnt)
This is what happens (if the code works):
Writing this down, I think you could also create a reference table with the pixelvalues on each row and the corresponding landuse classname in another column and join this table to the attribute table of the raster and perform a summerize on the landuse class column, summing the count...
Kind regards,
Xander
Hi Xander,
Thanks a lot for all your help! I really appreciate it! Specially, the way you explain each line in the code and its corresponding role. Have a good day!
Regards,
Subhasis