Python Script: loop through selected features and and copy to geodatabase

4355
14
04-13-2014 12:35 PM
DavidBailey
New Contributor II
I am working with surface types that I derived from LIDAR data. These surface types are in one feature class (polygon) -
associated with the feature class is a column called "grid_code"; the grid_code column has values from 0 to 145. These are elevation values and will be selected out to classify three surface types (ground surface, shrubs and trees).

I want to write a script that selects each surface type and creates a feature class for each of them. My output would have three
feature classes: ground, shrub and tree.

Here is the code I am working with but I am getting errors:

Thanks!



import arcpy, os

aWS = r"C:\Thesis_Research\GIS\Prov_classification.gdb"

arcpy.env.workspace = aWS

arcpy.env.overwriteOutput = True

try:
  
    # Create query statements for each land cover type
    LIDAR_tree = '"grid_code" > \'3\''
    LIDAR_shrub = '"grid_code" = \'2\' OR "grid_code" = \'3\''
    LIDAR_ground = '"grid_code" <= \'1\''

    aListLIDAR = [LIDAR_tree, LIDAR_shrub, LIDAR_ground]
   
    for item in aListLIDAR:
       
        arcpy.MakeFeatureLayer_management("P303_LIDAR_Poly", P303_layerL)

        arcpy.SelectLayerByAttribute_management(P303_layerL, "NEW_SELECTION", aListLIDAR)
       
        arcpy.CopyFeatures_management(P303_layerL, "P303_" + str(item))

    del aListLIDAR
    del item
    del P303_layerL

   
except:
   
    # Code to run when an error occured
    print "An ERROR Occured!"
    print "\n" + arcpy.GetMessages()

else:
   
    # Message when there was no error
    print "\nNo Error occurred"
   
# Script end message
print "\nEnd of the script!"
Tags (2)
0 Kudos
14 Replies
DanPatterson_Retired
MVP Emeritus
what are the errors?
enclose your script in code blocks so that they can be read
0 Kudos
DavidBailey
New Contributor II
I put the script in a code block - It is not telling me the error.

I am new to python, and I just threw this script together by reading other python scripts. Let me know if you need more info


# Developed by: David Bailey
# Description: Providence Creek Watershed: land cover processing


# import arcpy site-package and os module
import arcpy, os

# Set geoprocessing environment:
# a) set the workspace environment 
aWS = r"C:\Thesis_Research\GIS\Prov_classification.gdb"
arcpy.env.workspace = aWS

# Set geoprocessing environment:
# b) the overwriteOutput parameter controls whether tools will
#    automatically overwrite any existing output 
arcpy.env.overwriteOutput = True

try:
   
    # Create query statements for each land cover type
    LIDAR_tree = '"grid_code" > \'3\''
    LIDAR_shrub = '"grid_code" = \'2\' OR "grid_code" = \'3\''
    LIDAR_ground = '"grid_code" <= \'1\''

    aListLIDAR = [LIDAR_tree, LIDAR_shrub, LIDAR_ground]
    

    for item in aListLIDAR:
        
        arcpy.MakeFeatureLayer_management("P303_LIDAR_Poly", P303_layerL)

        arcpy.SelectLayerByAttribute_management(P303_layerL, "NEW_SELECTION", aListLIDAR)
        
        arcpy.CopyFeatures_management(P303_layerL, "P303_" + str(item))

    del aListLIDAR
    del item
    del P303_layerL

    
except:
    
    # Code to run when an error occured
    print "An ERROR Occured!"
    print "\n" + arcpy.GetMessages()

else:
    
    # Message when there was no error
    print "\nNo Error occurred"
    
# Script end message
print "\nEnd of the script!"    
0 Kudos
DavidBailey
New Contributor II
I am assuming the "for loop" is not correctly structured?
0 Kudos
IanMurray
Frequent Contributor
I put the script in a code block - It is not telling me the error.

I am new to python, and I just threw this script together by reading other python scripts. Let me know if you need more info


# Developed by: David Bailey
# Description: Providence Creek Watershed: land cover processing


# import arcpy site-package and os module
import arcpy, os

# Set geoprocessing environment:
# a) set the workspace environment 
aWS = r"C:\Thesis_Research\GIS\Prov_classification.gdb"
arcpy.env.workspace = aWS

# Set geoprocessing environment:
# b) the overwriteOutput parameter controls whether tools will
#    automatically overwrite any existing output 
arcpy.env.overwriteOutput = True

try:
   
    # Create query statements for each land cover type
    LIDAR_tree = '"grid_code" > \'3\''
    LIDAR_shrub = '"grid_code" = \'2\' OR "grid_code" = \'3\''
    LIDAR_ground = '"grid_code" <= \'1\''

    aListLIDAR = [LIDAR_tree, LIDAR_shrub, LIDAR_ground]
    

    for item in aListLIDAR:
        
        arcpy.MakeFeatureLayer_management("P303_LIDAR_Poly", P303_layerL)

        arcpy.SelectLayerByAttribute_management(P303_layerL, "NEW_SELECTION", aListLIDAR)
        
        arcpy.CopyFeatures_management(P303_layerL, "P303_" + str(item))

    del aListLIDAR
    del item
    del P303_layerL

    
except:
    
    # Code to run when an error occured
    print "An ERROR Occured!"
    print "\n" + arcpy.GetMessages()

else:
    
    # Message when there was no error
    print "\nNo Error occurred"
    
# Script end message
print "\nEnd of the script!"    




A few questions and observations.  First is "P303_LIDAR_Poly" a feature class that is directly within your geodatabase, or is it in a feature class within the feature dataset?  If its in a feature dataset within the geodatabase, your environment for that part needs to be within that feature dataset it resides. 

Second, "arcpy.SelectLayerByAttribute_management(P303_layerL, "NEW_SELECTION", aListLIDAR)" is wrong.  it should be "arcpy.SelectLayerByAttribute_management(P303_layerL, "NEW_SELECTION", item)".  Right now it is using the whole list for your SQL expression, which is a list.  You want it to run through each expression individually, so use item.
0 Kudos
DavidBailey
New Contributor II
Thanks for the response.

"P303_LIDAR_Poly" is a feature class directly in my geodatabase - I did not create a feature dataset.

I changed the "arcpy.SelectLayerByAttribute_management" tool to (arcpy.SelectLayerByAttribute_management(P303_layerL, "NEW_SELECTION", item)" but I still had an error.

I have my code written where it will tell me what the error was - but for some reason it is not giving me the messages.
0 Kudos
MattEiben
Occasional Contributor
Well there seems to be a couple issues here.

In your arcpy.MakeFeatureLayer_management method, your outlayer is being written to a variable "P303_layerL" that was never declared anywhere, that would certainly throw an error.

I made some changes to your script and posted them below here.

Some of the changes I made in your for loop:


[INDENT]I integrated the select by attributes method right into the Make Feature Layer, since it has an optional where clause where you put your query.
Make Feature Layer Documentation

I changed your naming in the copy feature layer to reflect which layer you're copying by vegetation type.

I added in a delete step at the end to remove the temporary feature layer before you create another one on the next loop.  Not deleting the feature layer before the next step may cause issues.[/INDENT]



Hopefully this code works for you!
I'm happy to help you tweak it further if you're still having some issues.

Matt

# Developed by: David Bailey
# Description: Providence Creek Watershed: land cover processing


# import arcpy site-package and os module
import arcpy, os

# Set geoprocessing environment:
# a) set the workspace environment 
aWS = r"C:\Thesis_Research\GIS\Prov_classification.gdb"
arcpy.env.workspace = aWS

# Set geoprocessing environment:
# b) the overwriteOutput parameter controls whether tools will
#    automatically overwrite any existing output 
arcpy.env.overwriteOutput = True

try:
   
    # Create query statements for each land cover type
    LIDAR_tree = '"grid_code" > \'3\''
    LIDAR_shrub = '"grid_code" = \'2\' OR "grid_code" = \'3\''
    LIDAR_ground = '"grid_code" <= \'1\''

    aListLIDAR = [LIDAR_tree, LIDAR_shrub, LIDAR_ground]
    layerName = ["tree","shrub","ground"]

    n = 0
    for query in aListLIDAR:

        arcpy.MakeFeatureLayer_management("P303_LIDAR_Poly", "temp_layer", where_clause=query)
        arcpy.CopyFeatures_management("temp_layer", "P303_{0}_layer".format(layerName))
        arcpy.Delete_management("temp_layer")
        n += 1

except:
    
    # Code to run when an error occured
    print "An ERROR Occured!"
    print "\n" + arcpy.GetMessages()
    
# Script end message
print "\nEnd of the script!"
0 Kudos
benberman
Occasional Contributor
The arcpy.Delete_management("temp_layer") should be outside of the for loop, yet on the same indentation. You want the temp layer to be deleted after you have processed the items in the list.
0 Kudos
DavidBailey
New Contributor II
Thanks for the responses. The new script looks good and it ran without any errors - however when I opened my three new land
surface types (P303_ground_layer, P303_shrub_layer, and P303_tree_layer) they had the same attributes as "P303_LIDAR_poly".
It seems as if it did not process the query statements.
0 Kudos
IanMurray
Frequent Contributor
arcpy.MakeFeatureLayer_management("P303_LIDAR_Poly", "temp_layer", where_clause=query)

should probably be

arcpy.MakeFeatureLayer_management("P303_LIDAR_Poly", "temp_layer", query)

As I recall, you don't have to put the word where_clause in the parameters, its understood since its the 3rd parameter for make feature layer. 

Also Matt



In your arcpy.MakeFeatureLayer_management method, your outlayer is being written to a variable "P303_layerL" that was never declared anywhere, that would certainly throw an error.



its not being written to a variable, its a string, and since its an output parameter, it doesn't need to exist already, you are just naming your output layer name, it no different then what you changed it to.  "temp_layer" has no special meaning, its just a name you are giving it to store in memory.
0 Kudos