Creating buffer with Python

10214
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
1 Solution

Accepted Solutions
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 

View solution in original post

0 Kudos
18 Replies
Zeke
by
Regular Contributor III
You need to loop through the features, creating a buffer for each one. As you access each one, you can multiply the value in the height field by your number. I doubt that you need or will see a better result by using a number with such precision, but hey, that's your call. You could use a search cursor to iterate through the records.

If you have a relatively small number of unique heights, it might be faster to select sets of features by height and buffer all of them with that value at once.
0 Kudos
ToddHowell
New Contributor
Thanks Greg! I appreciate the feedback. How exactly do I establish the geodatabase as a list for input into a for loop? Is there any way to preserve the feature datasets so that they transfer into the output geodatabase once the feature classes are processed through the buffer tool?
0 Kudos
IanMurray
Frequent Contributor
From reading your post, I gather you have multiple feature datasets in your geodatabase with multiple feature classes in each, so you need to iterate through each dataset and feature class within the each dataset.

Easiest way to do that is to use arcpy.ListDatasets and arcpy.ListFeatureClasses


As for the multiplying the flight height field by your float value I'd use arcpy.SearchCursor to get the value from the field

# 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"

#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 

     # fetches all feature classes in workspace into a list
     fclist = arcpy.ListFeatureClasses()

     #loop through feature classes in our list
     for fc in fclist:
          distanceField = "Flight_Height"
          sideType = "FULL"
          endType = "FLAT"
          dissolveType = "NONE"
          multiplier = 1.502167099846
          cursor = arcpy.SearchCursor(fc)
          for row in cursor:
                distance = ((row.getValue(distanceField))*(multiplier))
                arcpy.Buffer_analysis(fc, PhotoCoverages, distance, sideType, endType, dissolveType)

del row 
del cursor


Note this will only work for if there is only a single record in each feature class(which I am assuming from the fact you have multiple feature datasets and feature classes).  The for loop for the cursor is not needed but I wasn't sure how to call it otherwise, I'm use to looping through multiple records at the same time.

Edit: I originally had arcpy.ListFeatureDatasets the correct syntax is arcpy.ListDatasets, sorry for the confusion
0 Kudos
IanMurray
Frequent Contributor
You can use Copy_management tool to copy the feature datasets to your other geodatabase.   Also if you wanted to save the feature classes in each feature dataset, then your output location would have to be the feature dataset in the output geodatabase, right now my code has it outputting as a feature class within the geodatabase.

Alternatively to using the cursor, you could just make a field in each feature classes that was the flight height multiplied by the float value you are using, then just use that field value as the value for the buffer, so you are using the field name as input instead of a number.
0 Kudos
Zeke
by
Regular Contributor III

Alternatively to using the cursor, you could just make a field in each feature classes that was the flight height multiplied by the float value you are using, then just use that field value as the value for the buffer, so you are using the field name as input instead of a number.


Oh, sure, if you want to do it the easy way!  🙂

You could still use the looping concept to add and calculate the new field to each feature class.
0 Kudos
ToddHowell
New Contributor
Ian,
   WOW. Thanks for the help, I do have feature classes with multiple records. Is it possible to work with that same code and modify it to work? The reason I have multiple datasets and feature classes is I am working with statewide data, and needed to be able to apply the state plane coordinates to each different area based on county, and then have feature classes based on towns. However, some towns have multiple flight lines so they required multiple records in the feature class.

    Currently I am working mostly with the ESRI Press Python Scripting for ArcGIS book. Are there any other resources you could recommend for a person new to programming to get a good start with. I need to preserve the feature datasets into the new geodatabase as well. How would that best fit into the script example you have given?

Thanks again for your help, I'm really taken aback at how helpful the Python community as a whole is.

Todd Howell
0 Kudos
ToddHowell
New Contributor
Runtime error
Traceback (most recent call last):
  File "<string>", line 35, in <module>
  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'm having trouble figuring out why it is returning this error when I try to run that code in ArcGIS as well.
0 Kudos
IanMurray
Frequent Contributor
Ian,
   WOW. Thanks for the help, I do have feature classes with multiple records. Is it possible to work with that same code and modify it to work? The reason I have multiple datasets and feature classes is I am working with statewide data, and needed to be able to apply the state plane coordinates to each different area based on county, and then have feature classes based on towns. However, some towns have multiple flight lines so they required multiple records in the feature class.

    Currently I am working mostly with the ESRI Press Python Scripting for ArcGIS book. Are there any other resources you could recommend for a person new to programming to get a good start with. I need to preserve the feature datasets into the new geodatabase as well. How would that best fit into the script example you have given?

Thanks again for your help, I'm really taken aback at how helpful the Python community as a whole is.

Todd Howell


You can you the copy the feature datasets with arcpy.Copy_management, which can be put in the python script, probably while you are looping through feature datasets. 
THis is one problem
arcpy.Buffer_analysis(fc, PhotoCoverages, distance, sideType, endType, dissolveType)
as it needs to output to a feature class, which we have it outputting to a geodatabase, but its a pretty easy fix, but we need to make sure it has a different output name each time or it will crash. 

Busy at work right now, but I can help you out again in a bit.  I'm pretty new to python myself, so not familiar with alot of good online resources, but arcgis help within ArcGIS is really handy for checking syntax and what your input and outputs for the methods are.
0 Kudos
Zeke
by
Regular Contributor III
You might want to set your distance_height through multiplier variables outside of the for loop to save the overhead of setting them each trip through the loop. Might only be a negligible performance hit, but good practice to avoid it if not needed.
0 Kudos