Given multiple polygons that overlap in multiple ways, I would like to export from this feature all polygons that don't overlap with others iteratively. The product would be a number of features with no overlap that, when summed together, make up the original. The products could then be used as input to Zonal Statistics, and this would be much faster than iterating Zonal Statistics over each poly. I have been trying to code this in arcpy and been driving myself nuts. Has anyone attempted this before, or does something out there already exist? Thank you.
|
|
This is a graph coloring problem. Recall that a graph coloring is an assignment of a color to the vertices of a graph in such a way that no two vertices which share an edge will also have the same color. Specifically, the (abstract) vertices of the graph are the polygons. Two vertices are connected with an (undirected) edge whenever they intersect (as polygons). If we take any solution to the problem--which is a sequence of (say k) disjoint collections of the polygons--and assign a unique color to each collection in the sequence, then we will have obtained a k-coloring of the graph. It is desirable to find a small k. This problem is pretty hard and remains unsolved for arbitrary graphs. Consider an approximate solution that's simple to code. A sequential algorithm ought to do. The Welsh-Powell algorithm is a greedy solution based on a descending ordering of the vertices by degree. Translated to the language of the original polygons, first sort the polygons in descending order of the number of other polygons they overlap. Working in order, give the first polygon an initial color. In each successive step, try to color the next polygon with an existing color: that is, choose a color that is not already used by any of that polygon's neighbors. (There are many ways to choose among the available colors; try either the one that has been least used or else choose one randomly.) If the next polygon cannot be colored with an existing color, create a new color and color it with that. Once you have achieved a coloring with a small number of colors, perform zonalstats color by color: by construction, you're guaranteed that no two polygons of a given color overlap. Here's sample code in
That is, polygons 1 and 2 overlap, and so do polygons 2 and 3, 3 and 4, ..., 1 and 7. Sort the vertices by descending degree:
A (crude) sequential coloring algorithm uses the earliest available color not already used by any overlapping polygon:
Initialize the data structures (
Split the polygons into groups according to color:
The output in this example uses four colors:
It has partitioned the polygons into four non-overlapping groups. In this case the solution is not optimal ({{3,6,5}, {2,4}, {1,7}} is a three-coloring for this graph). In general the solution it gets shouldn't be too bad, though. |
||||
|
The methodology recommended by #whuber inspired me to take a new direction, and here is my arcpy solution, in two functions. The first, called countOverlaps, make two fields, "overlaps" and "ovlpCount" to record for each poly which polys overlapped with it, and how many overlaps occurred. The second function, explodeOverlaps, creates a third field, "expl", which gives a unique integer to each group of non-overlapping polys. The user can then export new fc's based on this field. The process is broken into two functions because I think the countOverlaps tool can prove useful by itself. Please excuse the sloppiness of the code (and the careless naming convention), as it's pretty preliminary, but it works. Also make sure that the "idName" field represents a field with unique IDs (only tested with integer IDs). Thank you whuber for providing me with the framework necessary to approach this problem!
|
|||||||
|
|
In this cases I generally use the following method:
I believe the result will be the one you wanted, and you can even count the number of overlaps. Don't know if in terms of performance will it be better for you or not. |
|||||||||||
|
|
I find it hard to deduce what solution was originally required (before trying to de-overlap intersecting polygons), but had my own bump with zonal stats not allowing overlap. I'll describe my project and solution. I want to deduce the height of buildings from a very finely meshed elevation grid and building-footprints as polygons. Since the buildings do not overlap, applying (zonal) stats to deduce elevation-information can be done in a straightforward manner. However, to determine building-height, I also need the terrain-elevation near the buildings. To extract this information, I buffered the buildings (outside only). These polygons routinely overlap. Since I really want to apply stats to the gridvalues falling within each polygon, it is not required that the polygons be de-overlapped, it is preferrable that they stay intact (as much as possible), otherwise I would have to reassemble the stats. Rethinking, I could have written a script selecting the elevations per polygon and processing them to produce stats. I did something similar by writing a C program (standalone executable). It has very good performance, but needs the grid as a .bil and the polygons as shapefile. The stats are similar to zonal stats. Complex and multipart polygons are supported, but no extensive testing has been done sofar. If anyone thinks this potentially useful, please let me know. Jan |
|||||
|


