I am trying to loop through a set of polygons in shapely so using python) to determine whether they overlap or not. I do not want to do it manually as later i want to generalise the procedure and do this for a number of polygons imported from a shapefile (through Fiona).
These are the polygons I am now testing
polA = Polygon([(0,0), (3,0), (3,3), (0,3)])
polB = Polygon([(2,-1), (5,-1), (5,2), (2,2)])
polC = Polygon([(5,2), (8,2), (8,5), (5,5)])
I created a collection from these collection = [polA, polB, polC]
and now I want a for loop to go through the list and check each polygon if it overlaps with the next. But nothing I try works, because I don't know how to loop and successfully test all the possible combinations. Don't know if I am understood. Does anyone have any idea how to do this using Shapely of Fiona?
-
It is a pure Python problem, search on the web for ""Comparing the next item in a list" and you will get a lot of solutions– geneCommented Oct 5, 2014 at 10:07
-
The thing is I do not want to repeat the intersection with the polygons I have already checked. For example, if I have polA and polB checked, I do not want to check polB with polA as for more polygons it will take a lot of time. Is that possible? Because, from searching I have to do all possible combinations. My python knowledge is not that advanced and maybe I get sth wrong.– GeomPCommented Oct 5, 2014 at 10:36
-
look below for some solutions– geneCommented Oct 5, 2014 at 11:22
Add a comment
|
1 Answer
Some solutions according to the position of an element in a list:
polA = Polygon([(0,0), (3,0), (3,3), (0,3)])
polB = Polygon([(2,-1), (5,-1), (5,2), (2,2)])
polC = Polygon([(5,2), (8,2), (8,5), (5,5)])
collection = [polA, polB, polC]
Iterating by index:
for i in range(len(collection)-1):
print collection[i], collection[i+1], collection[i].touches(collection[i+1])
POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)) POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1)) False
POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1)) POLYGON ((5 2, 8 2, 8 5, 5 5, 5 2)) True
Iterating with itertools (standard module), all combinations without repeated elements
import itertools
for pol in itertools.combinations(collection, 2):
print pol[0],pol[1], pol[0].touches(pol[1])
POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)) POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1)) False
POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)) POLYGON ((5 2, 8 2, 8 5, 5 5, 5 2)) False
POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1)) POLYGON ((5 2, 8 2, 8 5, 5 5, 5 2)) True
or with the suggestion of Mike T
for pol1, pol2 in itertools.combinations(collection, 2):
print pol1, pol2, pol1.touches(pol2)
POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)) POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1)) False
POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)) POLYGON ((5 2, 8 2, 8 5, 5 5, 5 2)) False
POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1)) POLYGON ((5 2, 8 2, 8 5, 5 5, 5 2)) True
Compare with
for pol in itertools.permutations(collection, 2):
print pol[0],pol[1], pol[0].touches(pol[1])
POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)) POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1)) False
POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)) POLYGON ((5 2, 8 2, 8 5, 5 5, 5 2)) False
POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1)) POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)) False
POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1)) POLYGON ((5 2, 8 2, 8 5, 5 5, 5 2)) True
POLYGON ((5 2, 8 2, 8 5, 5 5, 5 2)) POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)) False
POLYGON ((5 2, 8 2, 8 5, 5 5, 5 2)) POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1)) True
Look also at Python - Previous and next values inside a loop
from itertools import tee, islice, chain, izip
def previous_and_next(some_iterable):
prevs, items, nexts = tee(some_iterable, 3)
prevs = chain([None], prevs)
nexts = chain(islice(nexts, 1, None), [None])
return izip(prevs, items, nexts)
for previous, item, nxt in previous_and_next(collection):
print "Item is now", item, "next is", nxt, "previous is", previous
Item is now POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0)) next is POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1)) previous is None
Item is now POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1)) next is POLYGON ((5 2, 8 2, 8 5, 5 5, 5 2)) previous is POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0))
Item is now POLYGON ((5 2, 8 2, 8 5, 5 5, 5 2)) next is None previous is POLYGON ((2 -1, 5 -1, 5 2, 2 2, 2 -1))