I am trying to write a Python Script for ArcGIS 10.2.
#import system modules
import arcpy
import math
from arcpy import env
#Set environment options
env.workspace="C:/Users/el/ac/script1"
# Set local variables
inFeatures = "line2.shp"
fieldName = "angle1"
expression = "GetAzimuthPolyline(!Shape!)"
codeblock = """import math
def GetAzimuthPolyline(shape):
radian = math.atan((shape.lastpoint.x - shape.firstpoint.x)/(shape.lastpoint.y - shape.firstpoint.y))
degrees = radian * 180 / math.pi
return degrees"""
# Execute AddField
arcpy.AddField_management(inFeatures, fieldName, "SHORT")
#print "Field has been added."
# Execute CalculateField
arcpy.CalculateField_management(inFeatures, fieldName, "GetAzimuthPolyline(!Shape!)", "PYTHON", codeblock)
Field was added, but the result is not calculated and is not writing into the field. But, if I write the code block in Calculate field in ArcMap, field calculates correctly. Why?
Code was amended. But if I run the script:
Traceback (most recent call last):
File "C:\Users\el\ac\script1\scr1.py", line 35, in <module>
arcpy.CalculateField_management(inFeatures, fieldName, "GetAzimuthPolyline(!Shape!)", "PYTHON", codeblock)
File "c:\program files (x86)\arcgis\desktop10.2\arcpy\arcpy\management.py", line 3354, in CalculateField
raise e
ExecuteError: ERROR 000539: Error running expression: GetAzimuthPolyline(GPVARIANTOBJECT0)
Traceback (most recent call last):
File "<expression>", line 1, in <module>
File "<string>", line 3, in GetAzimuthPolyline
AttributeError: 'str' object has no attribute 'x'
3 Answers 3
You're using an expression type of 'PYTHON'
, but to support the calculation you're trying, you need to use 'PYTHON_9.3'
.
-
DWYnne is correct. I was able to get the function to work when I changed it "PYTHON_9.3"F_Kellner– F_Kellner2015年04月03日 20:04:02 +00:00Commented Apr 3, 2015 at 20:04
Since you're doing the calculation from within a Python script anyway (as opposed to the Field Calculator GUI or a Model Builder model), I would rewrite the code using an arcpy.da.UpdateCursor
to avoid the awful code-within-a-string that's required for a CalculateField_management()
codeblock:
#import system modules
import arcpy
import math
from arcpy import env
#Set environment options
env.workspace="C:/Users/el/ac/script1"
# Set local variables
inFeatures = "line2.shp"
fieldName = "angle1"
def GetAzimuthPolyline(shape):
radian = math.atan((shape.lastPoint.x - shape.firstPoint.x)/(shape.lastPoint.y - shape.firstPoint.y))
degrees = radian * 180 / math.pi
return degrees
# Execute AddField
arcpy.AddField_management(inFeatures, fieldName, "SHORT")
#print "Field has been added."
# Calculate field with arcpy.da.UpdateCursor
with arcpy.da.UpdateCursor(inFeatures, ['SHAPE@', fieldName]) as cursor:
for row in cursor:
row[1] = round(GetAzimuthPolyline(row[0])) # Round to integer, because field is "SHORT"
cursor.updateRow(row)
As @Erica said, there is an indentation error in your code block. I'm surprised it isn't throwing a Syntax Error when you try to run calculate field. In any case,
codeblock = """import math
def GetAzimuthPolyline(shape):
radian = math.atan((shape.lastpoint.x - shape.firstpoint.x)/(shape.lastpoint.y - shape.firstpoint.y))
degrees = radian * 180 / math.pi
return degrees"""
should be
codeblock = """import collections
import math
pt_ = collections.namedtuple("pt", "x y")
def toPoint(shapePT):
if isinstance(shapePT, basestring):
return pt(*map(shapePT.split()[:2]))
return shapePT
import math
def GetAzimuthPolyline(shape):
first_point = toPoint(shape.firstpoint)
last_point = toPoint(shape.lastpoint)
radian = math.atan((last_point.x - first_point.x)/(last_point.y - first_point.y))
degrees = radian * 180 / math.pi
return degrees
return shapePT"""
-
Thank You, but I get the same error as in the beginning. I think the problem in line: arcpy.CalculateField_management(inFeatures, fieldName, "GetAzimuthPolyline(!Shape!)", "PYTHON", codeblock)Elshurito– Elshurito2014年04月21日 06:25:31 +00:00Commented Apr 21, 2014 at 6:25
codeblock
statement indented or not? (It might be correctly indented in your actual code, but was lost when pasting.)shape.firstPoint.X
,shape.firstPoint.Y
,shape.lastPoint.X
andshape.lastPoint.Y