5

I am currently working with compressor stations on centerline routes. These compressor stations have a 3 mile buffer surrounding them. I wish to cut a portion of the circular buffer off. These cut buffers represent unidirectional flow on the route. I plan to clip the lines within each of the buffers so I can ultimately highlight these clipped lines.

Below is a picture of what I have done manually through the polygon editor. I wanted to see if there was an arcpy script available to help me automate this process.enter image description here

  • How would you determine which half to keep? – Aaron Jul 1 '15 at 15:21
  • The flow for the route is always north, so I would be cutting off the bottom portion of the circle buffer – GIS_ROOK Jul 1 '15 at 15:23
  • Will the 3-mile buffers ever overlap each other? – Emil Brundage Jul 1 '15 at 16:49
  • There is a chance that they will overlap. It all depends on the location of the compressor stations that the buffers will be built around. – GIS_ROOK Jul 1 '15 at 17:40
6

Here's a script I put together. The script uses your point and your line feature class, and outputs a new line feature class of line features as desired. The basic steps:

  • Iterate through points
  • Create a buffer around each point
  • Create East-West line from each point. This will be used to slice your buffer in half
  • Create point north of each input point. This will be used to select northern buffer half
  • Slice the buffer in half with Feature to Polygon
  • Select northern half with northern point
  • Add all northern buffers to new feature class
  • Clip input line feature class by northern buffers

Note that the script assumes a northern direction means an increase in the y-value of a point's coordinate. I've commented out a different line if the opposite is true. You should find it with my comments.

Also note that your input point feature class needs to be in a projected coordinate system.

Inputs:

  • pntFc: Full path to your point feature class
  • lineFc: Full path to your line feature class you wish to slice up
  • bufferDist: Distance in meters for your buffer
  • workspace: in_memory or a file geodatabase to store intermediate data
  • outLineFC: Full path of line output
  • outBufferFC: Full path of half-buffer output

Script:

#Locals-----------
"""
Creates northerly buffers from point data set
Intersects line feature class 
"""

#Input point feature class
pntFc = r"C:\temp\temp.gdb\testpnt"

#Input line feature class
lineFc = r"C:\temp\temp.gdb\testline"

#Buffer distance in meters
## 3 miles * 1609.34 = 4828.03
bufferDist = 4828.03

#Workspace
workspace = r"in_memory"

#Full path of line output
outLineFC = r"C:\temp\temp.gdb\testline_out2"

#Full path of buffer output
outBufferFC = r"C:\temp\temp.gdb\buffer_out"

#End locals -----------

#Import modules
print "Importing modules"
from arcpy import *
import os

#Optional: overwrite output
#Will allow for overwriting feature classes in workspace
env.overwriteOutput = True

#Get spatial reference to determine feature class meter unit conversion
SR = Describe (pntFc).spatialReference
metersPerUnit = SR.metersPerUnit


#Create empty line feature class for east/west line - used for slicing
ewLineFc = os.path.join (workspace, "sliceLine")
CreateFeatureclass_management (workspace, "sliceLine", "POLYLINE", spatial_reference = SR)

#Create empty point feature class for northerly point - used for selecting northern half of buffer
nPointFc = os.path.join (workspace, "nPoint")
CreateFeatureclass_management (workspace, "nPoint", "POINT", spatial_reference = SR)


#Creater empty polygon to store northerly buffers
bufferHalfs = os.path.join (workspace, "bufferHalfs")
CreateFeatureclass_management (workspace, "bufferHalfs", "POLYGON", spatial_reference = SR)

#Empty list to store northern buffers
northBuffs = []

#Iterate points
print "Creating northernly half-buffers"
with da.SearchCursor (pntFc, ["SHAPE@X", "SHAPE@Y", "SHAPE@"]) as cursor:
    for xCoor, yCoor, shape in cursor:

        #Buffer feature class
        bufferFc = os.path.join (workspace, "buffer")
        Buffer_analysis (shape, bufferFc, "%s Meters" % str(bufferDist))

        ###Create east-west line feature class ------

        #Array object
        array = Array()

        #Create easterly and westerly points
        ePoint = Point()
        ePoint.Y = yCoor
        ePoint.X = xCoor + (bufferDist / metersPerUnit) + 1

        wPoint = Point()
        wPoint.Y = yCoor
        wPoint.X = xCoor - (bufferDist / metersPerUnit) - 1

        array.add (ePoint)
        array.add (wPoint)

        #Create easterly/westerly line
        line = Polyline (array)

        #Add line to east-west line feature class
        inCurs = da.InsertCursor (ewLineFc, ["SHAPE@"])
        inCurs.insertRow ((line,))
        del inCurs


        ##Done creating east-west line feature class -----

        ###Create northerly point ------
        ###Allows selection of northern buffer

        #Northerly point
        nPoint = Point()
        nPoint.Y = yCoor + ((bufferDist / metersPerUnit) /2) #Assumes increased coordinate == north
        #If north == minusing y Coordinate use:
        #nPoint.Y = yCoor - ((bufferDist / metersPerUnit) /2)
        nPoint.X = xCoor

        #Add point to  north point feature class
        inCurs = da.InsertCursor (nPointFc, ["SHAPE@"])
        inCurs.insertRow ((nPoint,))
        del inCurs

        ##Done creating northerly point ------------

        #Slice buffer
        slicedBufferFc = os.path.join (workspace, "sliceBuffer")
        FeatureToPolygon_management ([bufferFc, ewLineFc], slicedBufferFc)

        #Make feature layer to select northerly half of buffer
        MakeFeatureLayer_management (slicedBufferFc, "sliceLyr")

        #Select sliced layer by northerly point
        SelectLayerByLocation_management ("sliceLyr", "", nPointFc)

        #Get shape object from buffer selection
        northShape = [r[0] for r in da.SearchCursor ("sliceLyr", "SHAPE@")][0]

        #Add buffer half to list
        northBuffs += [northShape]

        #Clean up
        for fil in ["sliceLyr", slicedBufferFc, bufferFc]:
            Delete_management (fil)
        for fc in [nPointFc, ewLineFc]:
            DeleteRows_management (fc)


#Insert cursor to add buffers to feature class
print "Creating split buffer feature class"
cursor = da.InsertCursor (bufferHalfs, "SHAPE@")
for half in northBuffs:
    cursor.insertRow ((half,))
del cursor

print "Clipping"
#Clip buffer halfs with input line feature class
Clip_analysis (lineFc, bufferHalfs, outLineFC)

print "Created:", outLineFC

#Export buffer feature class
buffName = os.path.basename (outBufferFC)
buffPath = os.path.dirname (outBufferFC)
FeatureClassToFeatureClass_conversion (bufferHalfs, buffPath, buffName)
print "Created:", outBufferFC



for fc in [bufferHalfs, ewLineFc, nPointFc]:
    Delete_management (fc)

print "Done"

Input example:

Input

Result: Result Buffers

Let me know if you have any questions!

  • Sure, it was fun. I've updated the script so that the buffers are exported too, since this was your original question. – Emil Brundage Jul 1 '15 at 19:29
  • 1
    @EmilBrundage Nice script! One alternative for ArcGIS 10.2+ is to use the buffer() and cut() methods of the arcpy.Polygon class to perform the geometry operations instead of using geoprocessing tools. This shouldn't affect the output, but it is probably faster. – dmahr Jul 1 '15 at 21:39
  • @dmahr thanks! I was only semi-aware of the geometry class options. They look quite useful. – Emil Brundage Jul 1 '15 at 22:21
  • @EmilBrundage I was wondering if you could provide some assistance with the script you provided. When the script is running through creating the buffers, east-west lines and northern points, it throws an exception after a few minutes. The exception is: "Runtime error Traceback (most recent call last): File "<string>", line 65, in <module> File "c:\program files (x86)\arcgis\desktop10.1\arcpy\arcpy\analysis.py", line 687, in Buffer raise e ExecuteError: ERROR 000735: Input Features: Value is required" Could you provide some insight into why this may be happening? – GIS_ROOK Jul 6 '15 at 14:36
  • Interesting. It's indicating that it can't find the input for the Buffer tool. The best I can figure, there's something wrong with the geometries of one or more of your points. Try a repair geometry tool run. Otherwise you'll have to do a little troubleshooting. See if you can figure out how to print out OIDs each time it iterates through a point. Add "OID@" to the list of fields in the cursor, add OID to the for loop, and then print OID at the start of each iteration. Then you'll know which point fails. – Emil Brundage Jul 6 '15 at 14:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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