簡體   English   中英

為什么Shapely.Geometry庫的symmetric_difference和相交運算顯然不一致?

[英]Why are the symmetric_difference and intersection operations for the Shapely.Geometry library apparently inconsistent?

我在python腳本中使用Shapely來確定LinearRings和2D中Polygons之間的對稱差之間的交集。 我遇到了我認為是公差問題的問題,並且在Shapely參考中找不到有關此問題的任何信息。 現在,我將介紹我到目前為止所做的一切,以便確定正在發生的事情。

from shapely.geometry import LinearRing, Polygon

ls_blue = LinearRing( [ [25.16,-88.42], [26.24,-87.34], [26.0,-88.42] ] )
ls_red  = LinearRing( [ [24.04, -89.54], [27.32, -86.26], [26.0, -89] ] )
inter = ls_blue.intersection(ls_red) 

-inter在感興趣的段(下圖中[25.16,-88.42],[26.24,-87.34]中看到的幾乎重疊的段)上未顯示線相交,並且所有預期結果

p_blue = Polygon( [ [25.16,-88.42], [26.24,-87.34], [26.0,-88.42] ] )
p_red  = Polygon( [ [ [24.04, -89.54], [27.32, -86.26], [26.0, -89] ] ] )
p_xor = p_blue.symmetric_difference(p_red) 

感興趣的段(在下圖[25.16,-88.42],[26.24,-87.34]中看到的幾乎重疊的段)包含在p_xor多邊形之一中,並且所有結果都是預期的

請注意,LinearRing僅是多邊形的邊界。

樣本LinearRings /多邊形圖: http ://imgur.com/PAsdGNJ

在這種情況下,按預期計算對稱差異多邊形和交點。

但是,此示例實際上是一些較大點系列的子集。 在這些較大的點系列中,未按預期計算XOR多邊形和線的交點。

兩點系列如下:

c_upper = Polygon([[ -38.68 ,  -116.82 ], [ -37.6 ,  -116.79 ], [ 45.72 ,  -116.79 ], [ 45.96 ,  -116.59 ], [ 46.26 ,  -115.51 ], [ 46.26 ,  -74.39 ], [ 45.75 ,  -73.31 ], [ 45.72 ,  -73.27 ], [ 44.53 ,  -74.39 ], [ 43.55 ,  -75.26 ], [ 42.47 ,  -76.14 ], [ 41.39 ,  -76.59 ], [ 40.27 ,  -77.64 ], [ 39.22 ,  -78.51 ], [ 37.06 ,  -79.77 ], [ 35.98 ,  -80.67 ], [ 33.81 ,  -81.93 ], [ 32.73 ,  -82.79 ], [ 31.65 ,  -83.2 ], [ 29.49 ,  -85.0 ], [ 28.4 ,  -85.62 ], [ 27.32 ,  -86.26 ], [ 24.04 ,  -89.54 ], [ 23.03 ,  -90.62 ], [ 22.6 ,  -91.7 ], [ 21.76 ,  -92.78 ], [ 20.86 ,  -93.87 ], [ 20.67 ,  -94.95 ], [ 19.71 ,  -96.03 ], [ 19.52 ,  -97.11 ], [ 18.67 ,  -98.16 ], [ 18.63 ,  -98.19 ], [ 18.32 ,  -99.28 ], [ 17.49 ,  -100.36 ], [ 17.01 ,  -101.44 ], [ 16.5 ,  -102.28 ], [ 16.34 ,  -102.52 ], [ 15.51 ,  -103.6 ], [ 15.16 ,  -104.69 ], [ 14.34 ,  -105.67 ], [ 14.24 ,  -105.77 ], [ 13.97 ,  -106.85 ], [ 13.25 ,  -107.72 ], [ 13.1 ,  -107.93 ], [ 12.14 ,  -109.01 ], [ 11.5 ,  -110.1 ], [ 11.09 ,  -110.57 ], [ 10.43 ,  -111.18 ], [ 8.93 ,  -112.29 ], [ 7.84 ,  -112.86 ], [ 6.82 ,  -113.34 ], [ 6.76 ,  -113.38 ], [ 5.68 ,  -113.58 ], [ 4.6 ,  -113.67 ], [ 3.52 ,  -113.38 ], [ 2.43 ,  -112.97 ], [ 1.35 ,  -112.36 ], [ 1.24 ,  -112.26 ], [ 0.27 ,  -111.55 ], [ -0.32 ,  -111.18 ], [ -0.81 ,  -110.81 ], [ -1.89 ,  -109.66 ], [ -2.43 ,  -109.01 ], [ -3.01 ,  -107.93 ], [ -4.92 ,  -105.77 ], [ -5.74 ,  -104.69 ], [ -6.19 ,  -103.6 ], [ -7.09 ,  -102.52 ], [ -7.91 ,  -101.44 ], [ -8.35 ,  -100.36 ], [ -9.26 ,  -99.28 ], [ -9.92 ,  -98.19 ], [ -10.52 ,  -97.11 ], [ -11.54 ,  -96.03 ], [ -12.44 ,  -94.95 ], [ -13.22 ,  -93.87 ], [ -13.83 ,  -92.78 ], [ -14.88 ,  -91.74 ], [ -15.96 ,  -91.03 ], [ -17.04 ,  -90.29 ], [ -17.94 ,  -89.54 ], [ -19.21 ,  -88.42 ], [ -20.99 ,  -87.37 ], [ -21.37 ,  -87.16 ], [ -22.45 ,  -86.26 ], [ -23.53 ,  -85.81 ], [ -24.62 ,  -85.06 ], [ -25.7 ,  -84.1 ], [ -26.78 ,  -83.78 ], [ -27.74 ,  -83.05 ], [ -28.94 ,  -82.0 ], [ -30.03 ,  -81.69 ], [ -31.11 ,  -80.79 ], [ -32.19 ,  -79.83 ], [ -33.27 ,  -79.64 ], [ -34.35 ,  -78.68 ], [ -35.44 ,  -77.79 ], [ -36.52 ,  -77.37 ], [ -37.6 ,  -76.46 ], [ -38.68 ,  -75.51 ], [ -39.76 ,  -75.06 ], [ -40.08 ,  -75.47 ], [ -40.31 ,  -76.55 ], [ -40.31 ,  -77.64 ], [ -40.29 ,  -78.72 ], [ -40.29 ,  -114.42 ], [ -40.31 ,  -115.51 ], [ -39.76 ,  -116.56 ], [ -39.72 ,  -116.59 ]])

c_lower = Polygon([[ -38.68 ,  -116.82 ], [ -37.6 ,  -116.79 ], [ 45.72 ,  -116.79 ], [ 45.96 ,  -116.59 ], [ 46.26 ,  -115.51 ], [ 46.26 ,  -73.31 ], [ 45.72 ,  -72.26 ], [ 44.63 ,  -73.27 ], [ 43.52 ,  -74.39 ], [ 42.47 ,  -75.38 ], [ 41.39 ,  -76.34 ], [ 40.31 ,  -77.22 ], [ 39.22 ,  -77.67 ], [ 38.11 ,  -78.72 ], [ 37.06 ,  -79.59 ], [ 36.68 ,  -79.8 ], [ 34.9 ,  -80.85 ], [ 33.81 ,  -81.81 ], [ 32.73 ,  -82.63 ], [ 31.65 ,  -83.08 ], [ 30.46 ,  -84.13 ], [ 29.49 ,  -84.94 ], [ 29.04 ,  -85.21 ], [ 27.32 ,  -86.33 ], [ 26.24 ,  -87.34 ], [ 25.16 ,  -88.42 ], [ 24.11 ,  -89.54 ], [ 23.66 ,  -90.62 ], [ 22.9 ,  -91.7 ], [ 21.95 ,  -92.78 ], [ 21.75 ,  -93.87 ], [ 20.8 ,  -94.95 ], [ 20.61 ,  -96.03 ], [ 19.71 ,  -97.11 ], [ 19.42 ,  -98.19 ], [ 18.57 ,  -99.28 ], [ 18.15 ,  -100.36 ], [ 17.49 ,  -101.44 ], [ 16.66 ,  -102.52 ], [ 16.29 ,  -103.6 ], [ 15.39 ,  -104.69 ], [ 15.13 ,  -105.77 ], [ 14.24 ,  -106.85 ], [ 13.29 ,  -107.93 ], [ 12.86 ,  -109.01 ], [ 11.95 ,  -110.1 ], [ 11.09 ,  -111.01 ], [ 10.01 ,  -111.97 ], [ 8.93 ,  -112.55 ], [ 7.84 ,  -113.17 ], [ 6.76 ,  -113.31 ], [ 5.68 ,  -113.57 ], [ 4.6 ,  -113.57 ], [ 3.52 ,  -113.25 ], [ 2.43 ,  -112.9 ], [ 0.27 ,  -111.93 ], [ -0.63 ,  -111.18 ], [ -0.81 ,  -111.01 ], [ -2.81 ,  -109.01 ], [ -2.98 ,  -108.83 ], [ -3.73 ,  -107.93 ], [ -4.47 ,  -106.85 ], [ -5.14 ,  -105.73 ], [ -6.06 ,  -104.69 ], [ -6.95 ,  -103.6 ], [ -7.27 ,  -102.52 ], [ -8.29 ,  -101.44 ], [ -9.12 ,  -100.36 ], [ -9.44 ,  -99.28 ], [ -10.4 ,  -98.19 ], [ -11.22 ,  -97.11 ], [ -11.6 ,  -96.03 ], [ -12.62 ,  -94.95 ], [ -13.8 ,  -93.6 ], [ -14.39 ,  -92.78 ], [ -14.88 ,  -92.17 ], [ -15.32 ,  -91.7 ], [ -15.96 ,  -91.1 ], [ -16.54 ,  -90.62 ], [ -18.12 ,  -89.38 ], [ -19.17 ,  -88.46 ], [ -20.29 ,  -87.41 ], [ -21.37 ,  -87.1 ], [ -22.45 ,  -86.2 ], [ -23.53 ,  -85.24 ], [ -24.62 ,  -84.94 ], [ -25.59 ,  -84.13 ], [ -26.78 ,  -83.08 ], [ -27.86 ,  -82.82 ], [ -30.03 ,  -80.92 ], [ -30.13 ,  -80.88 ], [ -31.11 ,  -80.61 ], [ -32.08 ,  -79.8 ], [ -33.27 ,  -78.69 ], [ -34.35 ,  -78.3 ], [ -35.44 ,  -77.48 ], [ -36.52 ,  -76.52 ], [ -37.6 ,  -75.51 ], [ -38.68 ,  -74.96 ], [ -39.39 ,  -74.39 ], [ -39.76 ,  -74.12 ], [ -40.01 ,  -74.39 ], [ -40.31 ,  -75.47 ], [ -40.29 ,  -77.64 ], [ -40.29 ,  -114.42 ], [ -40.31 ,  -115.51 ], [ -39.76 ,  -116.56 ], [ -39.72 ,  -116.59 ]])

當計算的方式與以前相同時,感興趣的段([25.16,-88.42],[26.24,-87.34])不包括在XOR多邊形中或作為線相交,盡管其兩個端點都是相交點。

我的算法依賴於這樣的想法,即不相交的線段將成為由symmetric_difference函數生成的多邊形的一部分,因此,顯然上述情況會產生不良結果,我發現這頗令人不安。

我的問題是:什么導致案例之間的相交和對稱差操作之間出現差異?

PS:如果需要更多圖像以實現可視化,請告訴我,我將創建它們。

這是一個精度問題,因為紅色的節點不是藍色的一部分。 插補直線上的點在計算上並不精確。 您可以通過在精度誤差內將一個幾何圖形捕捉到另一個幾何圖形來解決此問題。 請參見shapely的snap功能來執行此操作。

from shapely.ops import snap

print(ls_blue.intersection(snap(ls_red, ls_blue, 1e-8)))
# LINESTRING (25.16 -88.42, 26.24 -87.34)

# or try
p_blue.symmetric_difference(snap(p_red, p_blue, 1e-8))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM