1

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'
ahmadhanb
41.8k5 gold badges55 silver badges110 bronze badges
asked Apr 20, 2014 at 14:18
5
  • 2
    Check the indentation: are all the lines of the codeblock statement indented or not? (It might be correctly indented in your actual code, but was lost when pasting.) Commented Apr 20, 2014 at 17:18
  • i'm sorry. I lost actual code when pasting Commented Apr 20, 2014 at 21:13
  • 2
    I have always had trouble with CalculateField run from a python script so I prefer to use cursors instead .... could this be an option for you? Commented Apr 24, 2014 at 12:23
  • 1
    Might it be a problem with case-sensitivity? Try shape.firstPoint.X, shape.firstPoint.Y, shape.lastPoint.X and shape.lastPoint.Y Commented May 21, 2014 at 2:22
  • 2
    Instead of using calculate field, you might want to investigate cursors in the data access module. Don't need to worry about formatting all this as a multi-line string. Commented May 21, 2014 at 3:23

3 Answers 3

4

You're using an expression type of 'PYTHON', but to support the calculation you're trying, you need to use 'PYTHON_9.3'.

answered Apr 3, 2015 at 16:49
1
  • DWYnne is correct. I was able to get the function to work when I changed it "PYTHON_9.3" Commented Apr 3, 2015 at 20:04
2

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)
answered Sep 18, 2014 at 14:29
1

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""" 
answered Apr 20, 2014 at 18:10
1
  • 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) Commented Apr 21, 2014 at 6:25

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.