【问题标题】:Python shapely: .equals function does not always work:Python shapely:.equals 函数并不总是有效:
【发布时间】:2016-09-05 10:10:42
【问题描述】:

我在使用 shapely 库时遇到了一些问题。 现在 equals 函数似乎并不总是有效:

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))

结果为假。 知道为什么吗?

【问题讨论】:

  • 它与此stackoverflow.com/questions/9470406/… 相关 - z 坐标被忽略。如果您通过删除220.0x-coordinate 的统一值将其简化为二维问题,那么poly1.equals(poly2) 将返回True,因为它应该...

标签: python shapely


【解决方案1】:

来自文档:

Polygon 构造函数有两个位置参数。第一个是 (x, y[, z]) 点元组的有序序列,其处理方式与 LinearRing 情况完全相同。

所以在创建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

相反,您仍然会遇到此问题:

>>> Polygon(pol1_coords) == Polygon(pol2_coords)
False

【讨论】:

  • 嗯,这是一个选项,但不是一个非常直接的选项。如您所见,多边形是封闭的形状,其中第一个顶点也是最后一个顶点。因此,对于一个矩形,您有 5 个顶点。如果 2 个多边形从不同的顶点开始 - 我将不得不删除每个多边形中的最后一个顶点来进行排序。这使得整个 .equals 函数毫无意义?
  • 您需要避免在(x, y[, z]) 序列中出现重复。然后对它们进行排序并相等。以这种方式。否则 .equals 函数将毫无意义。
  • 否 - 检查 OP 上的评论 - 这是因为 Z 坐标被忽略了
【解决方案2】:

正如@ewcz 在 cmets 中所说,这是因为 Shapely 仅适用于 XY 平面中的 2D 几何。这里忽略了 Z 坐标。这些在投影到 XY 平面时不是有效的多边形,因此 Shapely 不准备同意它们相等。如果您删除(不必要的)x 坐标,它工作正常:

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

【讨论】:

    猜你喜欢
    • 2018-01-21
    • 2021-12-25
    相关资源
    最近更新 更多