1

I am having a few issues with the shapely library. Now the equals function seem not to always work:

poly1 =  Polygon(([220.0, 400, 500], [220.0, 20, 500], [220.0, 20, 0], [220.0, 400, 0], [220.0, 400, 500]))
poly2 =  Polygon(([220.0, 20, 500], [220.0, 400, 500], [220.0, 400, 0], [220.0, 20, 0], [220.0, 20, 500]))

print (poly1.equals(poly2))

Results with a false. Any idea why?

Yair
  • 859
  • 2
  • 12
  • 27
  • 2
    it's related with this http://stackoverflow.com/questions/9470406/python-shapely-intersection-parallel-planes - the z-coordinate is ignored. If you reduce it to 2D problem by removing the uniform value of `x-`coordinate of `220.0` then `poly1.equals(poly2)` returns `True` as it should... – ewcz Sep 05 '16 at 11:03

2 Answers2

2

From docs:

The Polygon constructor takes two positional parameters. The first is an ordered sequence of (x, y[, z]) point tuples and is treated exactly as in the LinearRing case.

So try to sort them first (tuples) before create Polygon:

>>> pol1_coords = ([0, 1, 2], [3, 4, 5], [6, 7, 8])
>>> pol2_coords = ([0, 1, 2], [6, 7, 8], [3, 4, 5])
>>> Polygon(sorted(pol1_coords)) == Polygon(sorted(pol2_coords))
True

instead you'll still have this issue:

>>> Polygon(pol1_coords) == Polygon(pol2_coords)
False
turkus
  • 4,637
  • 2
  • 24
  • 28
  • Well, that is an option but not a very straight forward one. As you can see, Polygons are closed shapes, in which the first vertex is also the last one. So, for a rectangle you have 5 vertices. If the 2 polygons start from a different vertex - I will have to remove the last vertex in each to do the sorting. Which makes the whole .equals function pointless? – Yair Sep 05 '16 at 10:29
  • You need to avoid duplicates in ``(x, y[, z])`` sequences. Then sort them and equal. In that way. Otherwise .equals function will be pointless. – turkus Sep 05 '16 at 10:43
  • No - check the comment on the OP - it's because the Z coordinate is being ignored – strubbly Sep 05 '16 at 11:24
1

As @ewcz says in the comments, this is because Shapely only really works with 2D geometry in the XY plane. It is ignoring the Z coordinate here. These are not valid Polygons when projected into the XY plane so Shapely is not prepared to agree that they are equal. It works fine if you remove the (unnecessary) x coordinate:

from shapely.geometry import Polygon

poly1 =  Polygon(([220.0, 400, 500], [220.0, 20, 500], [220.0, 20, 0], [220.0, 400, 0], [220.0, 400, 500]))
poly2 =  Polygon(([220.0, 20, 500], [220.0, 400, 500], [220.0, 400, 0], [220.0, 20, 0], [220.0, 20, 500]))

print (poly1.equals(poly2)) # False

print poly1.is_valid  # False
print poly2.is_valid  # False

poly1 =  Polygon(([400, 500], [20, 500], [20, 0], [400, 0], [400, 500]))
poly2 =  Polygon(([20, 500], [400, 500], [400, 0], [20, 0], [20, 500]))

print (poly1.equals(poly2)) # True

print poly1.is_valid  # True
print poly2.is_valid  # True

poly1 =  Polygon(([220.0, 400], [220.0, 20], [220.0, 20], [220.0, 400], [220.0, 400]))
poly2 =  Polygon(([220.0, 20], [220.0, 400], [220.0, 400], [220.0, 20], [220.0, 20]))

print (poly1.equals(poly2)) # False

print poly1.is_valid  # False
print poly2.is_valid  # False
strubbly
  • 3,347
  • 3
  • 24
  • 36