I am building a relatively simple python tool for ArcGIS 10.3 which will automate the process of generating summary statistics for multiple raster datasets, for polygons in a polygon dataset, using ESRI's Zonal Statistics tool. The key component of the tool is a multi-column value table that will allow the user to input:
- a raster dataset (to be summarized)
- summary statistic that will be calculated (i.e. mean, range, max, etc.)
- name of the column that will be added to the polygon dataset (which will contain the summary statistic values)
Because I need to use a value table, I decided to use a Python Toolbox as the interface for my python script. I've tested the code that performs the geoprocessing, and it works. The problem I'm having now is that when the value table is passed to my python script from the toolbox, it's being sent as unicode, and my script doesn't recognize that variable as a being a value table. I assume this is because the parameters are being sent using this code (which is recommended by ESRI):
parameters[2].valueAsText
which results in this error:
line 14, in main
param_count = param_tbl.rowCount
AttributeError: 'unicode' object has no attribute 'rowCount'
I've tried changing how the parameter is sent, i.e.
parameters[2].values
however, this results in:
AttributeError: 'list' object has no attribute 'rowCount'
How exactly should a value table be sent from the Python Tool execute function or do I need to convert the variable from a string back into a value table in my geoprocessing script?
Here's the relevant code from the Python Toolbox (.pyt):
param2 = arcpy.Parameter(
displayName='Summary data list',
name='stat_list',
datatype='GPValueTable',
parameterType='Required',
direction='Input')
param2.columns = [['Raster Dataset','Raster Dataset'], ['GPString','Statistic Type'], ['GPString', 'Summary Field Name']]
param2.filters[1].type = 'ValueList'
param2.filters[1].list = ['ALL', 'MEAN', 'MAXIMUM', 'MINIMUM', 'RANGE', 'STD', 'SUM']
def execute(self, parameters, messages):
"""The source code of the tool."""
ps.main(parameters[0].valueAsText,
parameters[1].valueAsText,
parameters[2].valueAsText,
parameters[3].valueAsText,
parameters[4].valueAsText)
return
and here's the relevant code from the Python script that performs the statistical summary and geoprocessing:
import arcpy
from arcpy.sa import *
import polystat_util as u
arcpy.CheckOutExtension("SPATIAL")
arcpy.env.overwriteOutput = True
def main(in_fc, in_fc_join_field, param_tbl, out_path, out_fc):
arcpy.MakeFeatureLayer_management(in_fc, "in_fc_lyr")
param_count = param_tbl.rowCount
# add new fields to polygon feature class that will contain summarized stats
param_names = []
zone_field = "ZONE_INDEX"
for i in range(param_count):
param_val = param_tbl.getValue(i,2)
param_names.append(param_val)
arcpy.AddField_management("in_fc_lyr", zone_field, "TEXT")
arcpy.CalculateField_management("in_fc_lyr", zone_field, "!" + in_fc_join_field + "!", "Python_9.3")
ply_tmp = u.AddStatFields("in_fc_lyr", zone_field, param_names)
for j in range(param_count):
raster_name = param_tbl.getValue(j,0)
stat_name = param_tbl.getValue(j,1)
field_name = param_tbl.getValue(j,2)
ras_lyr = arcpy.MakeRasterLayer_management(raster_name, "ras_lyr")
zstat_result = ZonalStatisticsAsTable(ply_tmp, zone_field, ras_lyr, "in_memory\\zstat", "DATA", stat_name)
u.JoinCalc(ply_tmp, zone_field, field_name, zstat_result, stat_name)
arcpy.FeatureClassToFeatureClass_conversion(ply_tmp, out_path, out_fc)
return
Here's my revised code snippet, based on Farid's answer:
def main(in_fc, in_fc_join_field, param_tbl, out_path, out_fc):
# extract values from value table
param_rows = param_tbl.split(';')
vt_array = []
for r in param_rows:
vt_array.append(r.split())
param_count = len(param_rows)
for j in range(param_count):
raster_name = vt_array[j][0]
stat_name = vt_array[j][1]
field_name = vt_array[j][2]
ras_lyr = arcpy.MakeRasterLayer_management(raster_name, "ras_lyr")
zstat_result = ZonalStatisticsAsTable(ply_tmp, zone_field, ras_lyr, "in_memory\\zstat", "DATA", stat_name)