Calculating polyline azimuth - code error

8453
16
Jump to solution
08-05-2014 01:43 AM
CamillaRootes
New Contributor III

Hi. I'm trying to run a Python script in the field calculator to output the azimuth values of a series of polylines. However, everytime I try to run the code it throws the following error:

"File "<string>", line 2, in GetAzimuthPolyline

AttributeError: 'str' object has no attribute 'x'

Failed to execute (CalculateField)."

The code block I am using is:

  1. import math 
  2. def GetAzimuthPolyline(shape): 
  3. radian = math.atan((shape.lastpoint.x - shape.firstpoint.x)/(shape.lastpoint.y - shape.firstpoint.y)) 
  4. degrees = radian * 180 / math.pi 
  5. return degrees 

I sourced the code from this thread Calculate angle of each line in a polyline shapefile‌. It seems to be working for the people in the thread but not for me. I'm running Arc 10.1 with the basic license, by the way.

Can anyone see where this is going wrong?

0 Kudos
16 Replies
CamillaRootes
New Contributor III

Great, that's done it. Thanks to both of you for your help, much appreciated!

0 Kudos
DavidHarbor
New Contributor III

Thanks for the postings, but I just tried this on an NHD dataset looking at the azimuths of stream polylines.  It doesn't return the correct azimuth  The azimuth -90 to 90 works, but between 90 and 270 degrees are incorrect. The streams flow direction is reversed.  I am going to look at the math, and will post if I see an improved answer.

stream_azimuth.PNG

0 Kudos
DavidHarbor
New Contributor III

Here is some code that works for me, where the "answer" does not as shown in previous post.

def CalculaAzimuth(linea):

    if (hasattr(linea,'type') and linea.type == 'polyline'):

        xf = linea.firstPoint.X

        yf = linea.firstPoint.Y

        xl = linea.lastPoint.X

        yl = linea.lastPoint.Y

        dX = xl - xf

        dY = yl - yf

        PI = math.pi

        Azimuth = 0 #Default case, dX = 0 and dY >= 0

        if dX > 0:

            Azimuth = 90 - math.atan( dY / dX ) * 180 / PI

        elif dX < 0:

            Azimuth = 270 - math.atan( dY / dX )* 180 / PI

        elif dY < 0:

            Azimuth = 180

        return Azimuth

    else:

        return False

which comes from here

Syntax Errors when Calculating Azimuth with Python in Arcgis 10 - Stack Overflow

stream_azimuth.PNG

Wish I could make use of "atan2(y,x)" but I couldn't get it to return 0-360 correctly in all quadrants.

0 Kudos
BruceHarold
Esri Regular Contributor

Hi, try this:

#Function to return the north azimuth bearing of a line segment in degrees
def NorthAzimuth(x1,y1,x2,y2):
    degBearing = math.degrees(math.atan2((x2 - x1),(y2 - y1)))
    if (degBearing < 0):
        degBearing += 360.0
    return degBearing
0 Kudos
DavidHarbor
New Contributor III

Two questions Bruce

why reverse the y and x  in the atan function?

what is the operator +=  ?

(sorry, I'm a python noob)

0 Kudos
BruceHarold
Esri Regular Contributor

To get north azimuth angles; try it:

>>> for x1y1x2y2 in [(0,0,1,1),(0,0,1,-1),(0,0,-1,-1),(0,0,-1,1)]:

...     x1,y1,x2,y2 = x1y1x2y2[0],x1y1x2y2[1],x1y1x2y2[2],x1y1x2y2[3]

...     print str(math.degrees(math.atan2((x2 - x1),(y2 - y1))))

...   

45.0

135.0

-135.0

-45.0

The += is shorthand for degBearing = degBearing + 360.0

DavidHarbor
New Contributor III

Sweet. Thanks.

0 Kudos