Creating buffer with Python

10296
18
Jump to solution
04-09-2014 08:09 AM
ToddHowell
New Contributor
I am very new to python, and am trying to utilize a stand alone script that I can use on a working geodatabase full of feature classes in various feature datasets. Here's what I'm trying to accomplish, and the script that I have constructed.

1. I have a file geodatabase full of feature datasets based on county, inside of the county feature datasets I have feature classes that represent the center of aerial photography flight lines. These feature classes have a field that contains the flight height of the photography.

2. I have constructed a script that so far is unsuccessful at what I want it to accomplish. My goal is to have a script that will batch process all of the feature classes in the geodatabase, will create buffers of the lines contained in those feature classes based on the flight height field which needs to be multiplied by a factor of 1.502167099846. Then output into my separate geodatabase that will contain those photo coverages for use with an ArcGIS online map service.

Here is the script that I have constructed thus far:

 # Name: Flight_Line_Buffer.py # Description: Creates area of Aerial Photography coverage based on digitized flight lines, and associated flight height field in flight line table.  #Import system modules import arcpy from arcpy import env  # Set environment settings env.workspace = "J:\Flight_Lines_GDB\Flight_Lines_Coverage.gdb" env.Outworkspace = "J:\Aerial_Photo_GDB\Aerial_Photography_Coverage.gdb"  # Create buffer distance output from Flight Height field, and buffer flight lines Flightlines = "J:\Flight_Lines_GDB\Flight_Lines_Coverages.gdb" PhotoCoverages = "J:\Aerial_Photo_GDB\Aerial_Photography_Coverage.gdb" distanceField = "Flight_Height" sideType = "FULL" endType = "FLAT" dissolveType = "NONE" arcpy.Buffer_analysis(Flightlines, PhotoCoverages, distanceField, sideType, endType, dissolveType) 


Things I know.
- I cannot just input the geodatabase as an input in the buffer tool, but I am unsure how to accomplish a loop or the like to process through all of the feature classes in the geodatabase.
-I cannot multiply a the field that I want to input as the buffer distance by a number either when I am defining it or in the tool parameters.
-I am a bit in over my head, and I am very very thankful for anyone with the patience and gracious nature to help me in any way.

Thanks for looking at this, I appreciate any help you can give.

Todd Howell
Tags (2)
0 Kudos
18 Replies
IanMurray
Frequent Contributor
This will probably take a bit of debugging, since I don't have a sample dataset to test on but this should run through each feature dataset in your gdb, copy your feature dataset to you AerialPhotographycoverage.gdb and then run through each feature class in your feature dataset make a buffer and save the buffer in the copied feature dataset in the aerialphotographycoverage.gdb.


# Name: Flight_Line_Buffer.py
# Description: Creates area of Aerial Photography coverage based on digitized flight lines, and associated flight height field in flight line table.

#Import system modules
import arcpy
from arcpy import env

# Set environment settings
env.workspace = "J:\Flight_Lines_GDB\Flight_Lines_Coverage.gdb"
env.Outworkspace = "J:\Aerial_Photo_GDB\Aerial_Photography_Coverage.gdb"

# Create buffer distance output from Flight Height field, and buffer flight lines
PhotoCoverages = "J:\Aerial_Photo_GDB\Aerial_Photography_Coverage.gdb"

fdOutput = "J:\Aerial_Photo_GDB\Aerial_Photography_Coverage.gdb"
#fetches all feaure datasets in workspace into a list
fdlist = arcpy.ListDatasets()

# loop through feature datasets in the list
for fd in fdlist:
    #setting new workspace to the feature dataset we are using
    env.workspace = fd 
 arcpy.CopyManagement(fd , fdOutput + "/" + fd)
    # fetches all feature classes in workspace into a list
    fclist = arcpy.ListFeatureClasses()

    #loop through feature classes in our list
    for fc in fclist:
  FCOutput = fdOutput + "/" + fd
        distanceField = "Flight_Height"
        sideType = "FULL"
        endType = "FLAT"
        dissolveType = "NONE"
        multiplier = 1.502167099846
        cursor = arcpy.SearchCursor(fc)
  count = 1
        for row in cursor:
            distance = ((row.getValue(distanceField))*(multiplier))
            arcpy.Buffer_analysis(fc, FCOutput + "/" + fc + "_Buffer" + str(count) , distance, sideType, endType, dissolveType)
            count += 1

del row 
del cursor



Sorry those buffer parameters get a bit nasty at the end.  I needed to set the output path and give each buffer a unique name so it doesn't crash because the same file name exists.

Hope this does the trick for you!
0 Kudos
ToddHowell
New Contributor
So I am getting a error returned for Line 23 which is where the Copy Management tool is called. In messing with the parameters in the tool to see what I could get to work, I had to call a specific feature dataset as the input and then the output could be just the OutWorkspace database. So, I think then the sticking point is creating another for in loop from a dataset list that would process the datasets into the target geodatabase, or is that going to copy over all the feature classes too? I'm sorry for being so bad at this, I'm really new, and took on a pretty ambitious project for my limited abilities. 🙂
0 Kudos
IanMurray
Frequent Contributor
Some of my indents were off, and I changed the environment before copying the feature datasets.  I tweaked it a bit, and hopefully it will run.  Next time if there is an error, post the error message, it will help with debugging. 


# Name: Flight_Line_Buffer.py
# Description: Creates area of Aerial Photography coverage based on digitized flight lines, and associated flight height field in flight line table.

#Import system modules
import arcpy
from arcpy import env

# Set environment settings
env.workspace = "J:\Flight_Lines_GDB\Flight_Lines_Coverage.gdb"
env.Outworkspace = "J:\Aerial_Photo_GDB\Aerial_Photography_Coverage.gdb"

# Create buffer distance output from Flight Height field, and buffer flight lines
PhotoCoverages = "J:\Aerial_Photo_GDB\Aerial_Photography_Coverage.gdb"

fdOutput = "J:\Aerial_Photo_GDB\Aerial_Photography_Coverage.gdb"
#fetches all feaure datasets in workspace into a list
fdlist = arcpy.ListDatasets()

# loop through feature datasets in the list
for fd in fdlist:
    print fd
    #setting new workspace to the feature dataset we are using
    arcpy.CopyManagement(fd , fdOutput + "/" + fd)
    env.workspace = fd 
    # fetches all feature classes in workspace into a list
    fclist = arcpy.ListFeatureClasses()

    #loop through feature classes in our list
    for fc in fclist:
        FCOutput = fdOutput + "/" + fd
        distanceField = "Flight_Height"
        sideType = "FULL"
        endType = "FLAT"
        dissolveType = "NONE"
        multiplier = 1.502167099846
        cursor = arcpy.SearchCursor(fc)
        count = 1
        for row in cursor:
            distance = ((row.getValue(distanceField))*(multiplier))
            arcpy.Buffer_analysis(fc, FCOutput + "/" + fc + "_Buffer" + str(count) , distance, sideType, endType, dissolveType)
            count += 1

    del row 
    del cursor
0 Kudos
ToddHowell
New Contributor
Error:

Runtime error
Traceback (most recent call last):
  File "<string>", line 23, in <module>
AttributeError: 'module' object has no attribute 'CopyManagement'

I had noticed those indent errors when I debugged it in PythonWin. The above error is the same one that was returning on the previous script too. I'm not sure if the input and input can be geodatabases in the copy tool. I tried setting up the tool in ArcMap with the parameters specified in the script and it gave an error for the output being a geodatabase, and not wanting to overwrite the OutWorkspace gdb with the input gdb. Should I try to just keep the current workspace .gdb for archival purposes, copy the feature classes out to a working gdb for the sake of simplifying the geoprocessing (removing the element of feature datasets). I think I'm going to write a script for creating a field with the calculated values for the buffer input to simplify that part of the code a bit too. What are your thoughts? Thank you very very much for all your help. I really appreciate you taking your time to teach me so much.
0 Kudos
IanMurray
Frequent Contributor
Now I feel like an idiot.

CopyManagement should have been Copy_management.  Replace that and it should work(at least past that point)
0 Kudos
ToddHowell
New Contributor
Ian,
I have taken a few more ESRI online python trainings, I'm back to trying to debug this script. The current sticking point is as follows:

>>> Eddy_County
Traceback (most recent call last):
  File "C:\Python27\ArcGIS10.2\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 326, in RunScript
    exec codeObject in __main__.__dict__
  File "C:\Users\thowe01\Desktop\IMURRAY_SCRIPT.py", line 39, in <module>
    distance = ((row.getValue(distanceField))*(multiplier))
  File "C:\Program Files (x86)\ArcGIS\Desktop10.2\arcpy\arcpy\arcobjects\arcobjects.py", line 1064, in getValue
    return convertArcObjectToPythonObject(self._arc_object.GetValue(*gp_fixargs(args)))
RuntimeError: ERROR 999999: Error executing function.

I have a few questions/ideas about it as well. I'll wait until you see this before I go muddying the waters with my half cocked ideas though. Hope you are doing well.

Todd
0 Kudos
Zeke
by
Regular Contributor III
Can you use row.distanceField instead of row.getValue(distanceField)? Also, make sure distanceField is numeric, not text, although that would probably be a different error.
0 Kudos
ToddHowell
New Contributor
I'm thinking it might just be easier to start with a script that creates a field for the buffer distance in the feature classes first, also having a field calculator script to use in the future while digitizing the new flight lines. The cursor script for making the calculations seems to be where this is all getting hung up at, right?
0 Kudos
IanMurray
Frequent Contributor
Got another idea for taking care of that getting that field value.  We just have the cursor only iterate through that field so when we set the cursor, set the feature class, then fields you want in brackets, if you needed more then one you can comma seperate each field name(they need to be strings and all inside the brackets).  cursor = arcpy.SearchCursor(fc, ["distanceField"]). 

In the loop calling an index value on row will not refer back to the original field number i.e. if this was column 5 in your attribute table or index value 4, now it is index value 0(first one in the cursor).  If you had another field you were going to iterate through with the cursor listed after this one(say ID field) that would be index value 1, etc.  So I put in distance = int(row[0])*(multiplier)) in the for loop instead. 


 # Name: Flight_Line_Buffer.py # Description: Creates area of Aerial Photography coverage based on digitized flight lines, and associated flight height field in flight line table.  #Import system modules import arcpy from arcpy import env  # Set environment settings env.workspace = "J:\Flight_Lines_GDB\Flight_Lines_Coverage.gdb" env.Outworkspace = "J:\Aerial_Photo_GDB\Aerial_Photography_Coverage.gdb"  # Create buffer distance output from Flight Height field, and buffer flight lines PhotoCoverages = "J:\Aerial_Photo_GDB\Aerial_Photography_Coverage.gdb"  fdOutput = "J:\Aerial_Photo_GDB\Aerial_Photography_Coverage.gdb" #fetches all feaure datasets in workspace into a list fdlist = arcpy.ListDatasets()  # loop through feature datasets in the list for fd in fdlist:     print fd     #setting new workspace to the feature dataset we are using     arcpy.CopyManagement(fd , fdOutput + "/" + fd)     env.workspace = fd      # fetches all feature classes in workspace into a list     fclist = arcpy.ListFeatureClasses()      #loop through feature classes in our list     for fc in fclist:         FCOutput = fdOutput + "/" + fd         distanceField = "Flight_Height"         sideType = "FULL"         endType = "FLAT"         dissolveType = "NONE"         multiplier = 1.502167099846         cursor = arcpy.SearchCursor(fc, ["distanceField"])         count = 1         for row in cursor:             distance = float(row[0])*(multiplier))             arcpy.Buffer_analysis(fc, FCOutput + "/" + fc + "_Buffer" + str(count) , distance, sideType, endType, dissolveType)             count += 1      del row      del cursor 
0 Kudos