Select to view content in your preferred language

Syntax help: defining a function in python

981
8
10-13-2011 04:44 PM
RichardThurau
Deactivated User
Hi,
Trying to write a code based on what I've learned in another thread

What I would like to do: Loop through each feature in a featureclass, select each feature, buffer, export as an individual featureclass.

What I am trying to do with this script: Select features "Grid_Num" = 7 and 22, buffer them, and export them as individual feature classes.

Here's my code:
import arcpy
##from arcpy.sa import *
from arcpy import env
##arcpy.CheckOutExtension("Spatial")
workspace = arcpy.env.workspace = "X:\\Grid\\Grid_Working.gdb\\All_Tiles\\"
##arcpy.env.overwrightOutput = True
GDB = "X:\\Grid\\Grid_Working.gdb\\All_Tiles\\"
FC = "X:\\Grid\\Grid_Working.gdb\\All_Tiles\\Grid_w_rShad"
fieldName = "Grid_Num"
buf = '200 feet'

def selectBufExport(GDB, FC, fieldName, fieldVal, buf):
    selection = arcpy.selectByAttributes(GDB +'\\'+ FC, '%s = %s' % (fieldName, fieldVal))
    bufferedSelection = arcpy.Buffer(selection, buf)
    arcpy.Export(bufferedSelection, GDB + '\\' + '%s_%s_tile' % (fieldName, fieldVal))

for (fieldVal, buf) in [(7, buf), (22, buf)]:
    selectBufExport(GDB, FC, fieldName, fieldVal, buf)


Error message:    
selection = arcpy.selectByAttributes(GDB +'\\'+ FC, 'fieldName = 7')
AttributeError: 'module' object has no attribute 'selectByAttributes'


Stacy R, I tried writing this from your example cited above, but I'm not savvy enough!

Looking for help solving this issue, or advice on how to improve, and suggestions for learning more in general. Much appreciated.

Rich
Tags (2)
0 Kudos
8 Replies
AlessandroCinnirella
Regular Contributor
the correct sintax is arcpy.SelectLayerByAttribute_management

ciao,
AC
0 Kudos
RichardThurau
Deactivated User
Thanks AC,
I think what I'm after is more structural guidance.

Is there a way to select each feature in a feature class without having to select by an attribute value?

New code:
GDB = workspace = arcpy.env.workspace = "X:\\Grid\\Grid_Working.gdb\\working_utm"
outFold = "X:\Grid\\Shape_AOI_files"
FC = "X:\\Grid\\Grid_Working.gdb\\All_Tiles\\Grid_w_rShad"
fieldName = "Grid_Num"
buf = '200 feet'
def selectBufExport(GDB, FC, fieldName, fieldVal, buf):
    selection = arcpy.Select_analysis(FC, GDB + '\\' + fieldVal, '%s = %s' % (fieldName, fieldVal))
    bufferedSelection = arcpy.Buffer_analysis(selection, GDB + '\\' + "_buf", buf)
    arcpy.Export(bufferedSelection, GDB + '\\' + '%s_%s_tile' % (fieldName, fieldVal))
for (fieldVal, buf) in [(2, buf), (22, buf)]:
    selectBufExport(GDB, FC, fieldName, fieldVal, buf)


Specific question: Is it possible to name output using the fieldName, and fieldVal terms? These are INT objects, so how do I treat these as text?
Am I so far off that no one can point me in the right direction?
0 Kudos
LoganPugh
Frequent Contributor
Here's one way to do it -- see comments in script. What I normally do is write one module with all the functions I need, as well as a test routine in the __main__ part, and then import those functions into another script for use as a script tool. That way I'm not duplicating code if multiple script tools use some of the same functions.

import arcpy
import os

def bufferFeaturesToIndividualFCs(inputFC, outputWorkspace, fieldName, bufferAmount, inputWhereClause=None):
    """Buffers each feature in the input feature class and creates a new
    feature class for each buffered feature. Specify a WHERE clause to
    specify which features should be processed."""

    arcpy.env.overwriteOutput = True # Overwrite outputs if they already exist
    desc = arcpy.Describe(inputFC)
    oidField = desc.OIDFieldName # Get the name of the ObjectID field so we can copy individual features
    oidFieldDelimited = arcpy.AddFieldDelimiters(inputFC, oidField) # Add field delimiters outside of the loop since it could be expensive
    rows = arcpy.SearchCursor(inputFC, inputWhereClause) # Create a cursor with which we can loop over the input features
    tempFC = r"in_memory\temp" # Designate a temporary feature class. In this case we use the in-memory workspace
    for row in rows: # Loop over the input features
        whereClause = "%s = %d" % (oidFieldDelimited, row.getValue(oidField)) # Construct a WHERE clause for the current feature's ObjectID
        arcpy.FeatureClassToFeatureClass_conversion(inputFC, os.path.dirname(tempFC), os.path.basename(tempFC), whereClause) # Copy the current feature to the temporary feature class
        outputFCName = "%s_%s_Buffer" % (os.path.basename(inputFC), str(row.getValue(fieldName))) # Construct the name of the output feature class
        outputFCPath = os.path.join(outputWorkspace, outputFCName) # Construct the full path of the output feature class
        arcpy.Buffer_analysis(tempFC, outputFCPath, bufferAmount) # Buffer the temporary feature class and write it to the output feature class
    if arcpy.Exists(tempFC):
        arcpy.Delete_management(tempFC) # Clean up the temporary workspace

if __name__ == "__main__":
    inputFC = r"C:\GISData\test.gdb\control"
    outputGDB = r"C:\GISData\buffertest.gdb"
    fieldName = "ID"
    bufferAmount = "200 feet"
    inputWhereClause = '"CONTROL_ID" IN(1, 2)'
    bufferFeaturesToIndividualFCs(inputFC, outputGDB, fieldName, bufferAmount, inputWhereClause)
0 Kudos
RichardThurau
Deactivated User
Logan,
Thanks a bunch. As it happens, I wasn't able to get back to this for a while. It's been very helpful though both for getting it done and learning quite a bit about update cursor.

I'll try posting a new problem here, but may have to start a new thread: I'm trying to use update.cursor to do a spatial selection of another layer, then populate the selection layer with an attribute from the cursor layer:

arcpy.MakeFeatureLayer_management(Jurs_dis, "JurLyr")
rows = arcpy.SearchCursor("JurLyr", "", "", "Jur_Name", "")
arcpy.MakeFeatureLayer_management(parcels, "parcLyr")
for row in rows:
    arcpy.SelectLayerByLocation_management("parcLyr", "HAVE_THEIR_CENTER_IN", "JurLyr", "", "NEW_SELECTION")
    arcpy.CalculateField_management("parcLyr", "Dist", "%s") %(row.Jur_Name)


I'm trying to select "parcLyr" by each feature in "JurLyr", then populate "parcLyr" field "Dist" with the value in "JurLyr" field "Jur_Name".

I'm getting an "invalid character" error. I feel like I'm close.

Any help would be greatly appreciated.

Thanks!

Rich
0 Kudos
by Anonymous User
Not applicable
Try something like:
arcpy.CalculateField_management("parcLyr", "Dist", '"%s" %(row.Jur_Name)',"PYTHON")

instead of

arcpy.CalculateField_management("parcLyr", "Dist", "%s") %(row.Jur_Name)


Here's one I use:
arcpy.CalculateField_management(featureclass, "FACILITY_JOIN", '"%s-%s" % (!FACILITY!,!FLOOR!)', "PYTHON")
0 Kudos
RichardThurau
Deactivated User
Huey,
Thanks, the code did run and update my parcels attribute. However, instead of populating parcels based on the JurName each parcel is inside, it updated all the parcels with the first JurName.

I guess I need to add some iteration? I thought the for loop would do it.

Any suggestions on that?

THanks.

Rich
0 Kudos
LoganPugh
Frequent Contributor
Have you considered using a spatial join? You could then use a regular join and calculate the desired field from the joined layer.
0 Kudos
RichardThurau
Deactivated User
Interesting suggestion, mostly because it works. Thanks.

Ultimately, if I had to join multiple types of larger geographies' attributes to the parcels (which I do), I'd have to do a lot of spatial joins then join fields to my original parcels dataset.

Select by location based on layer selections seems at least a little more efficient. I'm not going to worry about it now, but conceptually it seems like the code I posted last should work.

Thanks for resolving my issue, but I wonder if any one out there has made a dual layer selection system like this work in python?

rich
0 Kudos