# UpdateAngle.py # assumes rectangular polygons # find bearing of longest side # might have trouble with up # 2 June 2011 # Kim Ollivier import arcgisscripting from math import * import datetime gp = arcgisscripting.create(9.3) try: layer = sys.argv[1] except: layer = "stripindex" ws = 'e:/teararoa/nz/current.gdb' gp.workspace = ws if not gp.Exists(ws): print "ws",ws raise Exception rotField = "smap_angle" if not gp.ListFields(layer,rotField): gp.AddField(layer,rotField,"FLOAT") def calcbearing(dPt): ''' calculate bearing of longest side ''' # points pt1 = dPt[1] pt2 = dPt[2] pt3 = dPt[3] # lengths l1 = hypot(pt2[0] - pt1[0],pt2[1] - pt1[1]) l2 = hypot(pt3[0] - pt2[0],pt3[1] - pt2[1]) # bearings b1 = atan2(pt2[1] - pt1[1],pt2[0] - pt1[0]) b2 = atan2(pt3[1] - pt2[1],pt3[0] - pt2[0]) # print "test",round(l1),round(l2),degrees(b1),degrees(b2) # print dPt if l1 > l2 : degree = degrees(b1) else: degree = degrees(b2) bearing = 90.0 - degree if bearing > 90: bearing = bearing - 180 if bearing < -90: bearing = bearing + 180 return bearing cur = gp.UpdateCursor(layer) ##,"ID = 1") row = cur.next() print while row: feat = row.Shape for partNum in range(feat.partCount) : part = feat.getPart(partNum) dPt = {} n = 0 for pt in iter(lambda: part.next(),None): # stops at null pt n+=1 dPt= (pt.X,pt.Y) rotation = calcbearing(dPt) row.setValue(rotField,rotation) row.setValue("LastUpdate",datetime.datetime.now()) # print row.objectid,row.id,row.island,rotation #,dPt cur.updateRow(row) row = cur.next() del row,cur
Has anyone found a Simple solution to this? I am experiencing the same problem
I believe you will still have to rely on a custom python script, although using arcpy geometry objects will likely shorten Kim's script considerably. I'll try to follow up on this.
Here is a 10.1 script you can use to calculate the data driven page rotation angle into a field called calcAngle, for an index feature class of rectangles.
>>> import math ... with arcpy.da.UpdateCursor("RECTANGLE_INDEX_FEATURE CLASS",["SHAPE@","calcAngle"]) as cursor: ... for row in cursor: ... points = [] ... for part in row[0]: ... for pnt in part: ... points.append(pnt) ... lines = [] ... for i in range(1,3): ... lines.append(arcpy.Polyline(arcpy.Array([points,points[i-1]]))) ... if lines[0].length > lines[1].length: ... firstShort = 0 ... else: ... firstShort = 1 ... dx = points[firstShort].X - points[firstShort+1].X ... dy = points[firstShort].Y - points[firstShort+1].Y ... ang = math.degrees(math.atan(dy/dx)) ... row[1] = 360-ang ... cursor.updateRow(row)
Hi Darren,
This looks exactly like what I need however I cannot get the code to work for me. I am trying this in 10.3. I get the error message :Runtime error
Traceback (most recent call last):
File "<string>", line 6, in <module>
TypeError: 'float' object is not iterable
I changed the Feature class and field names to match my layer. ("Release_Grid",["Shape","calcAngle"]
Any suggestions?
Make sure you use "SHAPE@", a special token for the actual geometry.
Got it! Thank you!!
Thanks for Darren's script which works perfectly. However I found it requires the 4 points of the polygon be created in a certain order, which might be all right for index polygons created via DDP tool, but in our case we often got the index polygons from other source like CAD design where how it was created not always guaranteed. So I modified Darren's code a bit to allow the calculation work on polygons created in any direction. cheers,