0

I have a polygon layer with a number of features which overlap (in my case this wildfires in an area over time). I would like to clip the underlying features so there is no overlap. To elaborate I want to select the most recent feature (fire) and clip any portions of other features (older fires) which fall within the selection of my most recent feature (fire). I would then like to continue this process untill I have a layer with no overlapping polygons. How can I do this?

2
  • 1
    Welcome to GIS SE. As a new user, please take the Tour. Please Edit the Question to specify the GIS software in use,what you have tried, and where you are stuck.
    – Vince
    Jun 13 at 12:41
  • Something that might work for me is Polygon self-intersection if I was able to set the feature order? Jun 13 at 13:15

1 Answer 1

0

We had a similar problem with overlapping drainage areas for BMPs, where we wanted to retain the drainage area for one feature based on its attributes and remove the overlapping areas from the rest. Here's a simplified version of my script that should work for you (with some slight modifications), assuming you are working in ArcGIS.

import arcpy
import os

# Input polygon feature class or layer with overlapping features
polyInput = r"InputPolygon"
# Data field used to choose which overlapping polygon to keep
dataField = 'Year'

# Create a copy and a feature layer to make selections on
arcpy.env.addOutputsToMap = 1
arcpy.conversion.FeatureClassToFeatureClass(polyInput, arcpy.env.scratchGDB, 'PolygonCopy')
arcpy.env.addOutputsToMap = 0
arcpy.management.MakeFeatureLayer(os.path.join(arcpy.env.scratchGDB,'PolygonCopy'), 'polyLyr')

# Output FC and table to use with Count Overlapping
overlapFC = os.path.join(arcpy.env.scratchGDB,'overlapFC')
overlapTable = os.path.join(arcpy.env.scratchGDB,'overlapTable')
# Set minimum overlap count to 2
arcpy.analysis.CountOverlappingFeatures('polyLyr', overlapFC, 2, overlapTable)

# Get list of OIDs for overlapFC and loop through them
overlaps = [row[0] for row in arcpy.da.SearchCursor(overlapFC, "OBJECTID")]

for overlap in overlaps:    
    # Get the list of polygon OIDs for that overlap
    polys = [row[0] for row in arcpy.da.SearchCursor(overlapTable, "ORIG_OID",where_clause = 'OVERLAP_OID = '+str(overlap))]
    
    # Select them
    arcpy.management.SelectLayerByAttribute('polyLyr', 'NEW_SELECTION', "OBJECTID IN ({:s})".format(','.join(f"{x}" for x in polys)))
    
    # Extract data from selection as lists of OID and dataField
    rankOID  = [row[0] for row in arcpy.da.SearchCursor('polyLyr',"OBJECTID")]   
    rankData = [row[0] for row in arcpy.da.SearchCursor('polyLyr', dataField)]
    
    # Sort OIDs based on descending values of dataField (so the first OID is the most recent year in this example)
    clipOIDs = [x for _, x in sorted(zip(rankData, rankOID),reverse=True)]
    
    # Keep the desired OID, the remaining list will all be clipped
    keepOID = clipOIDs.pop(0)
    keepShape = [row[0] for row in arcpy.da.SearchCursor('polyLyr', "SHAPE@",where_clause = 'OBJECTID = '+str(keepOID))][0]
    
    # Loop through and clip
    with arcpy.da.UpdateCursor('polyLyr',"SHAPE@",where_clause="OBJECTID IN ({:s})".format(','.join(f"{x}" for x in clipOIDs))) as cursor:
        for row in cursor:
            oldShape=row[0]
            newShape=oldShape.difference(keepShape)
            cursor.updateRow((newShape,))
   
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.