Reputation: 81
I'm trying to create regions of polygons on the condition that they touch. In my example I have an example dataset with 382 polygons that need to be grouped together (but the full dataset contains 6355 polygons). (I would show a picture, but I don't have enough reputation to do that..)
I though of doing this brute force, but of course that takes very long and is not very optimal.
def groupBuildings(blds):
# blds is a list with shapely polygons
groups = []
for bld in blds:
group = []
group.append(bld)
for other in blds:
for any in group:
if any != other and any.intersects(other):
group.append(other)
groups.append(group)
return groups
I learned about region growing and thought that that would be a possible solution, but still the performance is terrible. I've implemented this in the following way:
def groupBuildings(blds):
# blds is a list with shapely polygons
others = blds
groups = []
while blds != []:
done = []
group = []
first = blds.pop(0)
done.append(first)
group.append(first)
for other in others:
if (other in blds) and first.touches(other):
group.append(other)
blds.remove(other)
return groups
But I think the problem here is that I don't have any nearest neighbors, so I still have to iterate over every building twice.
So my question is: are nearest neighbors essential for region growing? Or is there another way of doing this efficiently?
Upvotes: 1
Views: 453
Reputation: 1573
You will be best served using shapely.ops.cascaded_union()
(docs here).
from shapely.geometry import Point, Polygon, MultiPolygon
from shapely.ops import cascaded_union
import numpy as np
polygons = [Point(200*x,200*y).buffer(b) for x,y,b in np.random.random((6000,3))]
multi = MultiPolygon(polygons)
unioned = cascaded_union(multi)
%%timeit
unioned = cascaded_union(multi)
# 2.8 seconds for me
Upvotes: 1