Created
June 24, 2020 15:26
-
-
Save pmacMaps/56450f73fb1876df37695fbdeddf146b to your computer and use it in GitHub Desktop.
Function and demo to Use ArcPy Search Cursors to loop through a layer and clip other layers by each feature in that layer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Note: this script is designed to run with Python 3 and ArcGIS Pro ArcPy | |
# import modules | |
# arcpy => provides access to Esri ArcGIS Pro | |
# os => provides convient way to construct file paths | |
# sys => provides way to capture errors | |
# re => used for snake case helper function (taken from https://www.30secondsofcode.org/python/s/snake) | |
import arcpy, os, sys | |
from re import sub | |
# replace dashes and spaces with underscore | |
# values in a "Name" field are used to create the name of an ouptu feature class | |
def format_name(s): | |
# return formatted value | |
return '_'.join( | |
sub('([A-Z][a-z]+)', r' \1', | |
sub('([A-Z]+)', r' \1', | |
s.replace('-', ' '))).split()) | |
# end function | |
# function to loop through a feature class, and clip another feature class by each record in feature class being looped through | |
def clip_layers(layer_to_be_clipped, clipping_layer, clipping_layer_fields, output_location, output_layer_name): | |
# create feature layer on "clipping_layer" | |
# you need to create a feature layer to use select by attribute or select by location functions | |
arcpy.MakeFeatureLayer_management(clipping_layer, 'clippingLayer') | |
# open search cursor on "clipping_layer" | |
# provides a way to move through each record in the "clipping_layer" | |
with arcpy.da.SearchCursor(clipping_layer, clipping_layer_fields) as cursor: | |
for row in cursor: | |
# where clause to select each feature in cursor for clip | |
where_clause = "OBJECTID = {}".format(row[0]) | |
# select current feature in cursor | |
arcpy.SelectLayerByAttribute_management('clippingLayer', 'NEW_SELECTION', where_clause) | |
# replace dashes and spaces with underscore for "name" value | |
# in this demo, row[1] represents the "name" field | |
# i.e., "Trout Run" => "Trout_Run" | |
feature_name = format_name(row[1]) | |
# output name for clipped features | |
# i.e., if output layer is LandUse_2019, then output_name = "LandUse_2019_Trout_Run" | |
output_name = r'{}_{}'.format(output_layer_name, feature_name) | |
# clip analysis | |
# i.e., clip the streams layer by the land use layer | |
arcpy.Clip_analysis(layer_to_be_clipped, 'clippingLayer', os.path.join(output_location, output_name)) | |
# print message to console | |
print('Clipped features for watershed "{}"'.format(row[1])) | |
# delete feature layer | |
# do this or your get an error | |
arcpy.management.Delete('clippingLayer') | |
# end function | |
try: | |
# file geodatabase to put output of analyses | |
out_gdb = r'Some Path\To\A\Project\A Cool Project.gdb' | |
# HUC-12 watersheds layer | |
watersheds_layer = os.path.join(out_gdb, 'Watersheds_Small') | |
# fields for search cursor | |
watersheds_layer_fields = watersheds_layer_fields = ['OBJECTID', 'NAME'] | |
# Land Use layer | |
land_use_layer = r'Some\Path\To\SDE_Connections\someUser@DatabaseName on Some Server.sde\DatabaseName.Some_LandUse' | |
# streams layer | |
streams_layer = r'Some\Path\to\Streams.gdb\Streams' | |
# print message to console | |
print('Running clip on "Land Use" layer') | |
# run clip on land use | |
clip_layers(land_use_layer, watersheds_layer, watersheds_layer_fields, out_gdb, 'LandUse_2019') | |
# print message to console | |
print('Completed clip on "Land Use" layer') | |
print('Running clip on "Streams Polyline" layer') | |
# run clip on streams polyline | |
clip_layers(streams_layer, watersheds_layer, watersheds_layer_fields, out_gdb, 'Streams') | |
# print message to console | |
print('Completed clip on "Streams Polyline" layer') | |
# If an error occurs running geoprocessing tool(s) capture error and write message | |
# handle error outside of Python system | |
except EnvironmentError as e: | |
tbE = sys.exc_info()[2] | |
# Write the line number the error occured to the log file | |
print("Failed at Line {}".format(tbE.tb_lineno)) | |
# Write the error message to the log file | |
print("Error: {}".format(str(e))) | |
except Exception as e: | |
# If an error occurred, write line number and error message to log | |
tb = sys.exc_info()[2] | |
print("Failed at Line {}".format(tb.tb_lineno)) | |
print("Error: {}".format(e)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment