AnsweredAssumed Answered

Calculating geometry using pyscripting: failed to read polygon input feature

Question asked by GoldenJiang on Oct 3, 2016
Latest reply on Oct 14, 2016 by rvburton

I'm following an ESRI online learning tutorial: Creating Python Toolboxes Using ArcGIS 10.1.

I copy the script and test on my data but the new tool only recognises 'Street' as an input feature. 

Can anyone tell me where is wrong with the codes below? 

import arcpy

class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""

self.label = "Calculate Geometry"
self.alias = "geometry"
# List of tool classes associated with this toolbox
self.tools = [CalculateGeometry]

class CalculateGeometry(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "CalculateGeometry"
self.description = ""
self.canRunInBackground = True
def getParameterInfo(self):
# first parameter
"""Define parameter definitions"""
in_features = arcpy.Parameter(
displayName = 'Input Feature',
name = 'in_features',
datatype = 'Feature Layer',
parameterType = 'Required',
direction = 'Input')
in_features.filter.list = ['Point','Polyline','Polygon']
# second parameter
field = arcpy.Parameter(
displayName = 'Field name',
name = 'field_name',
datatype = 'Field',
parameterType = 'Required',
direction = 'Input')
field.parameterDependencies = [in_features.name]
# only show field belongs to the input feature
in_features.filter.list = ['Short','Long','Double','Float','Text']
# third parameter
geomProperty = arcpy.Parameter(
displayName = 'Property',
name = 'geomProperty',
datatype = 'String',
parameterType = 'Required',
direction = 'Input')
# fourth parameter
units = arcpy.Parameter(
displayName = 'Units',
name = 'units',
datatype = 'String',
parameterType = 'optional',
direction = 'Input',
enabled = False)
# fifth parameter
out_features = arcpy.Parameter(
displayName = 'Output Features',
name = 'out_features',
datatype = 'Feature Layer',
parameterType = 'Derived',
direction = 'Output')
field.parameterDependencies = [in_features.name]
out_features.schema.clone = True
params = [in_features, field, geomProperty, units, out_features]
return params

def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""

# Get Inputs
in_features = parameters[0]
geomProperty = parameters[2]
units = parameters[3]
# Geometry Property Filter Lists
pointPropertyList = ['X Coordinate of Point',
'Y Coordinate of Point']
linePropertyList = ['Length', 'X Coordinate of Line Start',
'Y Coordinate of Line Start',
'X Coordinate of Line End',
'Y Coordinate of Line End']
polygonPropertyList = ['Area','Perimeter',
'X Coordinate of Centroid',
'Y Coordinate of Centroid']
# Get shape type of input to determine
# filter list for geometry property parameter
if in_features.value:
    desc = arcpy.Describe(in_features.valueAsText)
    if desc.shapeType == 'Point':
       geomProperty.filter.list = pointPropertyList
    elif desc.shapeType == 'Polyline':
       geomProperty.filter.list = linePropertyList
    elif desc.shapeType == 'Polygon':
       geomProperty.filter.list = polygonPropertyList
# Unit Filter Lists
areaUnitList = ['Acres','Ares','Hectares','Square Centimeters','Square Inches','Square Feet','Square Kilometers','Square Meters','Square Miles','Square Millimeters','Square Yard','Square Decimeters']
lengthUnitList = ['Centimeters','Feet','Inches','Kilometers','Meters','Miles','Millimeters','Nautical Miles','Yards','Decimal Degrees']
# Get geometry property input to determine filter list for unit parameter
if geomProperty.value:
    if geomProperty.valueAsText == 'Area':
       units.enabled = True
       units.filter.list = areaUnitList
    elif geomProperty.valueAsText in ['Length','Perimeter']:
       units.enabled =True
       units.filter.list = lengthUnitList
    else:
       units.value = ''
       units.filter.list = []
       units.enabled = False
    return

def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""

in_features = parameters[0]
geomProperty= parameters[2]
units = parameters[3]
# Check is input is Multipoint or Multipatch and if so set an error
if in_features.value:
    desc = arcpy.Describe(in_features.valueAsText)
    if desc.shapeType in ['Multipoint','Multipatch']:
      in_features.setErrorMessage('{0} features are not supported.'.format(desc.shapeType))
# Check if certain geometry property value is set with no units and add error
if geomProperty.valueAsText in ['Length','Perimeter','Area']:
    if not units.value:
       units.setErrorMessage('Units required for {0} property'.format(geomProperty.valueAsText))
return

def execute(self, parameters, messages):
"""The source code of the tool."""
# Get Input
in_features = parameters[0].valueAsText
field = parameters[1].valueAsText
geomProperty= parameters[2].valueAsText
units = parameters[3].valueAsText
shapeFieldName = arcpy.Describe(in_features).shapeFieldName
# Create the expression
exp = '!' + shapeFieldName
if geomProperty == 'Area':
    exp += '.area@'+ units.replace('','')
elif geomProperty in ['Length','Perimeter']:
    exp += '.length@'+ units.replace('','')
else:
    propertyList = geomProperty.split('')
    coord = propertyList[0]
    if propertyList[-1] in ['Point','Start']:
       exp += '.firstPoint.' + coord
    elif propertyList[-1] == 'End':
       exp += '.lastPoint.'+ coord
    elif propertyList[-1] == 'Centroid':
       exp += '.centroid.'+ coord
exp+= '!'

messages.addMessage(
'\nExpression used for field calculation: {0}\n'.format(exp))

#Calculate Field
arcpy.CalculateField_management(in_features,field,exp,'PYTHON_9.3')
return

Attachments

Outcomes