11

I would like to take a polygon feature class with multiple irregular polygons, and have ArcMap draw parallel lines inside of each polygon. Ideally, it would be nice for ArcMap to figure out the angle of the longest side of the polygon and draw parallel lines to that side, but to keep it simple, I think if I could just enter one angle for all the parallel lines, that would be easier.

So line angle, width between lines, min/max length, and buffer width from the sides of the polygons are what my basic criteria are.

Image attached if that helps.

enter image description here

0

2 Answers 2

10

As @cndnflyr mentions, this can be scripted in Python.

Script Tool UI:

enter image description here

Sample Output: enter image description here

# import libraries
import arcpy

# set input/output parameters
polyFC = arcpy.GetParameterAsText(0)        # input polygons
outParallel = arcpy.GetParameterAsText(1)   # output parallel lines
lineSpacing = arcpy.GetParameterAsText(2)   # line spacing
buffDist = arcpy.GetParameterAsText(3)      # inner buffer distance

# parse numbers from parameters
lineSpaceNum = float(lineSpacing.split(' ')[0])
buffNum = float(buffDist.split(' ')[0])

# establish spatial reference
desc = arcpy.Describe(polyFC)
SR = desc.spatialReference

# set overwrite environment
arcpy.env.overwriteOutput = True
arcpy.env.outputCoordinateSystem = SR

parallels = []
# loop through each input shape
for row in arcpy.da.SearchCursor(polyFC, ["SHAPE@"], spatial_reference=SR):

    # create inner buffer
    polyBuff = row[0].buffer(buffNum * -1)

    # create hull rectangle to establish a rotated area of interest
    coordSplit = row[0].hullRectangle.split(' ')

    # collect corner coordinates
    coordList = arcpy.Array([arcpy.Point(coordSplit[0],coordSplit[1]),arcpy.Point(coordSplit[2],coordSplit[3]),arcpy.Point(coordSplit[4],coordSplit[5]),arcpy.Point(coordSplit[6],coordSplit[7]),arcpy.Point(coordSplit[0],coordSplit[1])])

    # create lines from hull rectangle
    currentLines = []
    for pointNum in range(0,4):
        arcpy.Array([coordList.getObject(pointNum),coordList.getObject(pointNum+1)])
        hullRecLine = arcpy.Polyline(arcpy.Array([coordList.getObject(pointNum),coordList.getObject(pointNum+1)]))
        currentLines.append(hullRecLine)

    # compare first and second line to determine if first line is short or long
    firstLong = 0
    if currentLines[0].length > currentLines[1].length:
        firstLong = 1

    # calculate number of points needed along short axis
    numPoints = int(math.floor(currentLines[firstLong].length/lineSpaceNum))

    # create and join points to create parallel lines
    for point in range(1,numPoints+1):
        shortPoint1 = currentLines[firstLong].positionAlongLine(lineSpaceNum*point)
        shortPoint2 = currentLines[firstLong + 2].positionAlongLine(currentLines[firstLong + 2].length - (lineSpaceNum*point))
        parallel = arcpy.Polyline(arcpy.Array([shortPoint1.centroid,shortPoint2.centroid]), SR)

        # intersect parallel lines with buffer
        parallelBuff = parallel.intersect(polyBuff,2)
        parallels.append(parallelBuff)

# write geometries to disk
arcpy.CopyFeatures_management(parallels, outParallel)

# add to map
mxd = arcpy.mapping.MapDocument("CURRENT")
dataFrame = arcpy.mapping.ListDataFrames(mxd, "*")[0]
addLayer = arcpy.mapping.Layer(outParallel)
arcpy.mapping.AddLayer(dataFrame, addLayer)

del row
0
4

This could be done with Python, but it would take some time to write it out.

I think the quickest way to implement it without Python is to have a template SHP file of these parallel lines. Have a few if you have varying widths needed, and just use the appropriate one for that Polygon. Make the template lines cover enough area to cover the largest Polygon you'll encounter.

  1. While editing, move the lines over the polygon.
  2. Use the Rotate tool, move the anchor point to where a Parallel line and the Polygon edge match, and rotate the lines so it snaps to the Polygon edge you lined it up on.
  3. Convert the Polygon to a Polyline
  4. Buffer the Polyline whatever distance you want the Parallel lines to be from the polygon edge.
  5. Use the Erase tool to erase the Polylines that are covered by the Buffered Polygon Edge
  6. Select by location all the lines that aren't inside the polygon and delete them. Or I think the Clip tool would work too.
  7. Select by attribute all the lines that are less than a certain length (too short to keep, although you might need to add a field and calculate the geometry first), and more than a certain length (too long to keep if that's what you want), delete them.
  8. Rinse and Repeat...

Steps 3 through 7 could be Modeled, without having to write any code.

Much the same process could be used for coding the process, but instead of having template lines, you could have the code draw the lines at the right angle, distance apart, etc. I haven't done this for awhile, but I think a Python library like shapely would help. Just make sure it covers a larger area than the Polygon, and use the tools to automatically convert to polyline, buffer, erase, select the lines not inside the polygon, and delete them.

0

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.