- inFc: The input feature class
- eraseFc: The feature class whose features will be erased from the input feature class
- outLoc: The output file geodatabase
- outName: The final name of the output feature class
- workspace: A file geodatabase workspace
- notices: Set to True for printed progress information
The code:
def Erase (inFc, eraseFc, outLoc = "", outName = "", workspace = "in_memory", notices = False): import os addToToc = arcpy.env.addOutputsToMap arcpy.env.addOutputsToMap = False if not outName: outName = os.path.basename (inFc) + "_Erase" if not outLoc: catPath = arcpy.Describe (inFc).catalogPath outLoc = os.path.dirname (catPath) outFc = UniqueFileName (outLoc, outName) outLoc, outName = os.path.split (outFc) garbage = [] inType = arcpy.Describe (inFc).shapeType eraseType = arcpy.Describe (eraseFc).shapeType #lines and lines if inType == "Polyline" and eraseType == "Polyline": #buffer both lines: flat, left inBuffFc = UniqueFileName (workspace) arcpy.Buffer_analysis (inFc, inBuffFc, ".01 FEET") garbage += [inBuffFc] eraseBuffFc = UniqueFileName (workspace) arcpy.Buffer_analysis (eraseFc, eraseBuffFc, ".01 FEET") garbage += [eraseBuffFc] #union input buffer with erase buffer unionFc = UniqueFileName (workspace) arcpy.Union_analysis ([inBuffFc, eraseBuffFc], unionFc) garbage += [unionFc] #select union output by erase buffer unionLyr = UniqueLayerName (unionFc) garbage += [unionLyr] arcpy.SelectLayerByLocation_management (unionLyr, "WITHIN", eraseBuffFc) #switch union selection arcpy.SelectLayerByAttribute_management (unionLyr, "SWITCH_SELECTION") #check for selection if not arcpy.Describe (unionLyr).FIDSet: arcpy.CreateFeatureclass_management (outLoc, outName, "POLYLINE", inFc, "", "", inFc) for trash in garbage: arcpy.Delete_management (trash) return outFc #clip line arcpy.env.addOutputsToMap = addToToc arcpy.Clip_analysis (inFc, unionLyr, outFc) #lines and polygons elif inType == "Polyline" and eraseType == "Polygon": #buffer both lines: flat, left inBuffFc = UniqueFileName (workspace) arcpy.Buffer_analysis (inFc, inBuffFc, ".01 FEET") garbage += [inBuffFc] #union input buffer with erase buffer unionFc = UniqueFileName (workspace) arcpy.Union_analysis ([inBuffFc, eraseFc], unionFc) garbage += [unionFc] #select union output by erase buffer unionLyr = UniqueLayerName (unionFc) garbage += [unionLyr] arcpy.SelectLayerByLocation_management (unionLyr, "WITHIN", eraseFc) #switch union selection arcpy.SelectLayerByAttribute_management (unionLyr, "SWITCH_SELECTION") #check for selection if not arcpy.Describe (unionLyr).FIDSet: arcpy.CreateFeatureclass_management (outLoc, outName, "POLYLINE", inFc, "", "", inFc) for trash in garbage: arcpy.Delete_management (trash) return outFc #clip line arcpy.env.addOutputsToMap = addToToc arcpy.Clip_analysis (inFc, unionLyr, outFc) #polygons and polygons elif inType == "Polygon" and eraseType == "Polygon": unionFc = UniqueFileName (outLoc, outName) arcpy.env.addOutputsToMap = addToToc arcpy.Union_analysis ([inFc, eraseFc], unionFc, "NO_FID") arcpy.env.addOutputsToMap = False unionLyr = UniqueLayerName (unionFc) garbage += [unionLyr] arcpy.SelectLayerByLocation_management (unionLyr, "WITHIN", eraseFc) arcpy.DeleteFeatures_management (unionLyr) inFlds = [f.name for f in arcpy.ListFields (inFc)] delFlds = [f.name for f in arcpy.ListFields (unionLyr) if not f.name in inFlds and not f.type in ("Geometry", "OID") and f.required == False] arcpy.DeleteField_management (unionLyr, delFlds) arcpy.env.addOutputsToMap = addToToc for trash in garbage: arcpy.Delete_management (trash) return outFc def UniqueFileName(Location = "in_memory", Name = "file", Extension = ""): """ returns an unused file name 'Location' will be the file folder 'Name' will be the file name plus numeric extension if needed 'Extension' is the file extension similar to arcpy.CreateUniqueName """ import arcpy import os if Extension: outName = os.path.join (Location, Name + "." + Extension) else: outName = os.path.join (Location, Name) i = 0 while arcpy.Exists (outName): i += 1 if Extension: outName = os.path.join (Location, Name + "_" + str(i) + "." + Extension) else: outName = os.path.join (Location, Name + "_" + str(i)) return outName def UniqueLayerName(inFC = None, sql = None): """ returns an unused feature layer name """ import arcpy import os lyrName = os.path.join ("lyr0") i = 0 while arcpy.Exists (lyrName): i += 1 lyrName = "lyr" + str(i) if inFC: arcpy.MakeFeatureLayer_management (inFC, lyrName, sql) return lyrName
This comment has been removed by a blog administrator.
ReplyDeleteHi,
ReplyDeleteThank a lot for sharing the code! I think the variable "fcName" in Line 10 should be "outName". Cheers~~
Thanks, you were right. I've fixed the code. Good catch.
DeleteThis works well, however since I didn't have an advanced licence, I had to change the buffer parameters from "Left" to "Full" and from "Flat" to "Round". Since those with an advance licence would simply use the Erase tool, it would make no sense to keep the advanced licence parameters.
ReplyDeleteIt would be helpful if there were a script that would call the Erase Function, for those who are not arcpy proficient.
Good point. I've updated the code accordingly.
DeleteI thought you could use arcpy functions outside of arcmap without license?
ReplyDelete