You need to iterate at some level. (Update: I've edited to remove all "for" loops, except for one list comprehension)
# imports used throughout this example
from shapely.geometry import Point
from shapely.ops import cascaded_union
from itertools import combinations
# Here are your input shapes (circles A, B, C)
A = Point(3, 6).buffer(4)
B = Point(6, 2).buffer(4)
C = Point(1, 2).buffer(4)
# list the shapes so they are iterable
shapes = [A, B, C]
First you need the union of all intersections (use a cascaded union), using the combination pair of each shape. Then you remove (via difference
) the intersections from the union of all shapes.
# All intersections
inter = cascaded_union([pair[0].intersection(pair[1]) for pair in combinations(shapes, 2)])
# Remove from union of all shapes
nonoverlap = cascaded_union(shapes).difference(inter)
Here is what nonoverlap
looks like (via JTS Test Builder):
With your solution:
print polygon.wkt
'POLYGON ((40.6499999999999986 -114.0699999999999932, 40.2100000000000009 -112.9599999999999937, 40.0000000000000000 -112.6599999999999966, 39.3999999999999986 -112.7000000000000028, 39.3900000000000006 -113.2800000000000011, 39.6799999999999997 -113.9399999999999977, 40.4200000000000017 -114.2600000000000051, 40.6000000000000014 -114.2199999999999989, 40.6499999999999986 -114.0699999999999932))'
path = LineString([(42.049999,-96.25), (38.0880979565,-119.609216457)])
print path.wkt
'LINESTRING (42.0499989999999997 -96.2500000000000000, 38.0880979565000004 -119.6092164570000023)'
The result in Google Maps is really meaningless (obtained image with the OpenLayers plugin of QGIS)
So, it seems to me that there is an inversion in the coordinates of the points:
40.65 is the latitude of the point -> y
-114.07 is the longitude of the point -> x
and
from shapely.geometry import Polygon, LineString
l = "40.65:-114.07 40.21:-112.96 40:-112.66 39.4:-112.7 39.39:-113.28 39.68:-113.94 40.42:-114.26 40.6:-114.22"
# swapping the coordinates:
points = [[float(x) for x in c.split(":")[::-1]] for c in l.split(" ")]
print points
[-114.06999999999999, 40.649999999999999], [-112.95999999999999, 40.210000000000001], [-112.66, 40.0], [-112.7, 39.399999999999999], [-113.28, 39.390000000000001], [-113.94, 39.68], [-114.26000000000001, 40.420000000000002], [-114.22, 40.600000000000001]]
polygon = Polygon(points)
path = LineString([(-96.25,42.049999), (-119.609216457,38.0880979565)])
path.intersects(polygon)
False
I can plot the geometries in Google Maps and I see no intersection:
Best Answer
If small changes in the shape that cannot be visually detected are not important, try this way:
You may need to change
d
andcf
values. This is not a perfect solution but it can solve your thin rectangle problem by small changes.