Selecting overlapping polygons (or work-around based on points)

4699
4
03-14-2016 02:11 PM
CorrieNavis
New Contributor

Here's my situation: I have a map with >2000 points. I want to buffer all of these points to a radius of 0.8km and then run other functions to calculate info about those circles. The problem is that the majority of those circles overlap with one or numerous other circles. (And the tools I want to use don't handle overlapping polygons well-- trust me, I've looked into that one thoroughly already.)

So what I'm hoping to do is separate out these observations into separate layers that contain non-overlapping polygons, so I can run the needed calculations on each layer separately.
- I don't want to select just the overlapping portions of the polygons; I need to be able to export the polygons, complete, into a new layer
- Dissolving the polygons into a single layer won't work-- each point is an observation that I need to calculate unique data for
- Ideally, I'd like to find a way to select only one of the overlaps-- because, for example, if two circles overlap, exporting them both to a new layer doesn't immediately solve my issue of having overlaps in the new layer (I'd have to do a lot of manual sorting through)

The work-around mentioned is that I can buffer the points either before or after sorting them into separate layers. If there is a way to achieve the similar goal (separating out layers so that each contains points that are at least 1.6km distant from each other) that would certainly work as well.

Hoping someone has an idea of what I can try?? Thanks!!

I am using ArcMap for desktop, 10.x

0 Kudos
4 Replies
DanPatterson_Retired
MVP Emeritus

a screen grab would be useful

I don't suppose you have an advanced license so you could use Aggregate Points—Help | ArcGIS for Desktop

but there are work arounds

EDIT

if you search GeoNet using ... overlapping polygons ... as key phrase search, there are a variety of scenarios and tools proposed for different situations, perhaps you could rule out some of those threads to simplify responses from here.

0 Kudos
DarrenWiens2
MVP Honored Contributor

The following script iterates through your buffer geometries, and assigns each to a group where none of the geometries overlap. There are surely ways to streamline the code and this may not be very efficient for large datasets, so I make no guarantees there.

>>> def group_buffs(buff_dict, group_no): # the magic function
...     group_no += 1 # group ID
...     changes = 0 # see if any changes happened on this run
...     for k,v in buff_dict.iteritems(): # loop through buffer dictionary
...         if v[1] == 0: # if row doesn't have a group ID
...             test_geom = v[0] # record geometry
...             buff_dict[1] = group_no # assign group ID
...             break # just need the first one
...     for k,v in buff_dict.iteritems(): # loop through buffer dictionary
...         if v[1] == 0: # if row doesn't have a group ID
...             if v[0].disjoint(test_geom): # if row is disjoint to the test_geom
...                 changes += 1 # record a change
...                 buff_dict[1] = group_no # assign group ID
...                 test_geom = test_geom.union(v[0]) # add current geometry to test_geom
...     if changes == 0: # no changes, must be done
...         return buff_dict # return the finished dictionary
...     else: # there were changes, call function again
...         return group_buffs(buff_dict,group_no) # call the function again and return the result
... buff_fc = 'buff2km' # the buffer feature class
... buff_dict = {} # an empty dictionary
... with arcpy.da.SearchCursor(buff_fc,['OID@','SHAPE@']) as cursor: # load OIDs and geometries to dictionary
...     for row in cursor:
...         buff_dict[row[0]] = [row[1],0] # key = OID, value = [geometry, default group ID]
... buff_dict = group_buffs(buff_dict, 0) # call function to assign group IDs
... group_field = 'group_no'
... #arcpy.AddField_management(buff_fc,group_field,"SHORT") # uncomment if need to add a field for group ID to feature class
... with arcpy.da.UpdateCursor(buff_fc,['OID@',group_field]) as uCursor: # update feature class with group IDs
...     for uRow in uCursor:
...         uRow[1] = buff_dict[uRow[0]][1]
...         uCursor.updateRow(uRow)

edit: I'll add that you can do exactly the same thing using PointGeometries and its distanceTo method, rather than Polygon's disjoint method.

CorrieNavis
New Contributor

Ah, that output looks like exactly what I need (and your description of the script, as well)!! Unfortunately, I'm a total python novice (I've taken one GIS course and am using ArcGIS for my master's thesis project, but had no intro to python as part of that course)-- anyone know a good "python for dummies" thread?

0 Kudos
AdrianWelsh
MVP Honored Contributor

I am not sure on a "Python for dummies" type of site but I have this book and I really enjoy it. It has helped me to utilize Python more in my GIS world and helped me to understand it better:

Python Scripting for ArcGIS, Paul A. Zandbergen, eBook - Amazon.com

There are a few thousand sites out there that show how to use Python in various forms and capacities. The issue I had always come across was how to use Python for my specific application (ArcGIS). This is one reason why I liked this book since it is tailored for that. Though, you can still find other sites that mention Python in a GIS environment from searching the web. This site lists a few places for finding those resources:

Resources for learning Python programming with generic GIS goals in mind? - Geographic Information S...

0 Kudos