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'
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.)
    – Erica
    Apr 20, 2014 at 17:18
  • i'm sorry. I lost actual code when pasting
    – Elshurito
    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?
    – dango
    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
    – nmpeterson
    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.
    – Paul
    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'.

1
  • DWYnne is correct. I was able to get the function to work when I changed it "PYTHON_9.3"
    – F_Kellner
    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)
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""" 
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)
    – Elshurito
    Apr 21, 2014 at 6:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.