Hey Everyone,
Currently what I am trying to do is rotate polylines in certain grid sections to the same orientation of existing polylines in that grid. This seems to be quite complicated as I have looked quite extensively for something like this, but to no success. Currently right now I have implemented a tool that was posted here arcpy - Drawing parallel lines inside polygons (Well Paths) using ArcGIS Desktop? - Geographic Infor... now this works for me and does what it should... but here is my problem posted below.
The grid lines that were drawn automatically (yellow) are horizontal where as I would like them be vertical. If there is a way through arcpy or other tools where I can rotate these lines to be the same direction of polylines that are currently there. This is just one example, this happens many times in different areas.
Thank you!
Solved! Go to Solution.
Adam, I would stick with Randy's since it is designed to work with the azimuth within a table.
Mine is designed to work from scratch given a start location, known distance and azimuths.
It is in essence the line version of my...
I have a point version in my Point Tools toolbox, also on the code sharing site (search using Dan_Patterson should bring up a list
Thanks Dan, I will take a look and see what I can find, thank you!
Have been trying to replicate an inside buffer and intersect lines within that buffer while iterating through it all but keep running into this error... Not sure what is occurring.
Here is the code so far;
Once again have to thank you for all the help and cooperation with me!
You are going to have to throw in some print statements to make sure 'feature' does indeed have at least 2 points
The 'cursor' people may want to jump in... my eyes tend to glaze over when I see them
Also
/blogs/dan_patterson/2016/08/14/script-formatting
help us refer line numbers to people
Hey Dan, Thanks for the tips and link on that! Was helpful,
I created a print statement for 'feature' and was returned with this.
so I do believe those features have at least 2 points, unsure as to why the intersect on the buffer is not working.
I've been experimenting with some code that I will post later today or this weekend.
Right now I'm wondering if the spatial reference is getting messed with when creating "polyBuff". Lines 1-2 and 6 clarify the spatial reference.
desc = arcpy.Describe(polyFC)
SR = desc.spatialReference
# ...
with arcpy.da.SearchCursor(polyFC,['SHAPE@', 'AVGAzimuth'], spatial_reference=SR) as cursor:
for row in cursor:
polyBuff = row[0].buffer(buffNum * -1)
It's possible, I will look into the spatial referencing issues possibly, but thanks again Randy for that, this has proved to be quite a challenging project to complete! But cant thank you all enough for the help.
Here is the code I've been working with:
import arcpy
import math
def rotate(origin, point, angle):
"""
Rotate a point counterclockwise by a given angle around a given origin.
The angle should be given in radians.
"""
ox, oy = origin
px, py = point
qx = ox + math.cos(angle) * (px - ox) - math.sin(angle) * (py - oy)
qy = oy + math.sin(angle) * (px - ox) + math.cos(angle) * (py - oy)
return qx, qy
def make_lines(origin, num_lines, length, spacing, bearing):
'''
origin = (x,y), num_lines = number of lines to draw
length = 1/2 length of line, spacing = spacing between lines
bearing = angle to rotate points
'''
angle = math.radians(360.0 - bearing)
lines = []
x, y = origin
# set up line points before rotation
xx = x - (spacing*(num_lines-1))/2.0
y1 = y + length*1.0
y2 = y - length*1.0
# rotate points around origin
for lns in range(1,num_lines+1):
qx1,qy1 = rotate((x,y),(xx,y1),angle)
qx2,qy2 = rotate((x,y),(xx,y2),angle)
lines.append([qx1,qy1,qx2,qy2])
xx += spacing
return lines
# set input/output parameters
polyFC = arcpy.GetParameterAsText(0) # input polygons : feature layer, input
angleField = arcpy.GetParameterAsText(1) # field containing rotation: field, input (obtained from param0)
numLines = arcpy.GetParameterAsText(2) # number of lines: long, input
lineSpacing = arcpy.GetParameterAsText(3) # line spacing : linear unit, input
buffDist = arcpy.GetParameterAsText(4) # inner buffer distance : linear unit, input
outLines = arcpy.GetParameterAsText(5) # output parallel lines : feature class, output
desc = arcpy.Describe(polyFC)
SR = desc.spatialReference # get spatial reference of polygon feature
arcpy.env.overwriteOutput = True # output will be overwritten
arcpy.env.outputCoordinateSystem = SR # set default spatial reference
D2M = { # dictionary for converting distance to meters
'CENTIMETERS': .01,
'DECIMALDEGREES': 1.0, # no conversion
'DECIMETERS': 0.1,
'FEET': 0.3048, # 0.304800609601 Foot_US
'INCHES': 0.0254,
'KILOMETERS': 1000.0,
'METERS': 1.0, # no conversion
'MILES': 1609.344,
'MILLIMETERS': 0.001,
'NAUTICALMILES': 1852.0,
'POINTS': 0.000352778,
'UNKNOWN': 1.0, # no conversion, tool may select data frame default
'YARDS': 0.9144,
}
# parse numbers from parameters
numLines = int(numLines)
lineSpacing = lineSpacing.split(' ')
if lineSpacing[1].upper() not in D2M.keys():
lineSpacing[1] = 'UNKNOWN'
spacing = float(lineSpacing[0]) * D2M[lineSpacing[1].upper()] * SR.metersPerUnit # convert spacing unit to meters, then to SR units
buffDist = buffDist.split(' ')
if buffDist[1].upper() not in D2M.keys():
buffDist[1] = 'UNKNOWN'
buffNum = float(buffDist[0]) * D2M[buffDist[1].upper()] * SR.metersPerUnit # convert buffer unit to meters, then to SR units
# list to save lines
lines = []
with arcpy.da.SearchCursor(polyFC,['SHAPE@', angleField]) as cursor:
for row in cursor:
# buffer for trimming lines to polygon
polyBuff = row[0].buffer(buffNum * -1)
# get centroid of polygon
centroid = row[0].centroid
# find distance from centroid to farthest point, this will be used as 1/2 line length
dist = 0
for part in row[0]:
for pnt in part:
cent_vert_dist = arcpy.PointGeometry(pnt).distanceTo(centroid)
if cent_vert_dist > dist:
dist = cent_vert_dist
# pass centroid, dist for 1/2 line length, and other variables to make lines
mkLns = make_lines(((centroid.X, centroid.Y)), numLines, dist, spacing, row[1])
# make polyline and trim to buffer
for ln in mkLns:
pl = arcpy.Polyline(arcpy.Array([arcpy.Point(ln[0],ln[1]), arcpy.Point(ln[2],ln[3])]), SR)
bufLn = pl.intersect(polyBuff,2)
lines.append(bufLn)
# save lines to feature class
arcpy.CopyFeatures_management(lines,outLines)
I added some code to better deal with the linear units; the original tool ignored the type of unit selection and used the default from the spatial reference. I create points for the ends of the lines and then rotate the points using the polygon's centroid as the rotation origin. The length for the lines (before buffering) is twice the distance from the centroid to the far point.
I've modified and added to the tool parameters:
And the results:
Hope this helps.
Hey Randy!
This looks almost exactly what I was trying to achieve, when I am in the office tomorrow I will give it a go! Thank you very much for this! I have been reading it over and researching a lot of the stuff you used so I can understand it fully! Outside of forum postings here, and if you're comfortable of course do you have any other form of communication I could possibly send questions should I have them? I am not sure of GeoNet's messaging or other communication means it has!
Thank you again.
Cheers
Adam
I am just getting into the Python scripting world, so my understanding of all the logic is very basic at this point, but I have found the script you put together extremely helpful. The script works wonderful on solid polygons but I am having a issue when it comes to polygons with holes it is giving me this error message, if you have any idea on how I could correct this or lead me in the right direction I would really appreciate it.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Thank you