我将问题简化为一些 MWE,以便可以重现它。我正在使用 Shapely 2.0 我想用线 L 将多边形 P 分成两部分。
POLYGON ((292718.0381447676 6638193.414029885, 292694.50537013356 6637994.803334004, 292718.0381447676 6638193.414029885, 292718.9708331647 6638193.303518486, 292722.0992155936 6638192.97038651, 292725.48975053953 6638192.648911643, 292729.16966360115 6638192.34135049, 292733.16283984896 6638192.050457474, 292737.48817684915 6638191.779469689, 292742.1600771896 6638191.532042792, 292747.1894678763 6638191.312155023, 292752.58358723175 6638191.124185786, 292758.34681013395 6638190.973003162, 292753.9574101781 6637991.021175833, 292758.34681013395 6638190.973003162, 292753.9574101781 6637991.021175833, 292694.50537013356 6637994.803334004, 292718.0381447676 6638193.414029885))
首先,我得到 P 和 L 之间的交集。结果是预期的 LineString L2 :
LINESTRING (292756.2221414001 6638094.18724655, 292743.0611 6638095.284, 292709.9881 6638095.284, 292706.4410368586 6638095.537357549)
其次,我将 P 除以 L2,我希望它返回 2 个多边形 P1 和 P2。
from shapely.ops import split
box = wkt.loads(my_polygon_as_str)
line = wt.loads(my_line_as_str)
result = split(box, line) # should return 2 polygons
然而,由于某种原因,
split()
方法只返回一个多边形,这是原始的P形状。
POLYGON ((292694.50537013356 6637994.803334004, 292718.0381447676 6638193.414029885, 292718.9708331647 6638193.303518486, 292722.0992155936 6638192.97038651, 292725.48975053953 6638192.648911643, 292729.16966360115 6638192.34135049, 292733.16283984896 6638192.050457474, 292737.48817684915 6638191.779469689, 292742.1600771896 6638191.532042792, 292747.1894678763 6638191.312155023, 292752.58358723175 6638191.124185786, 292758.34681013395 6638190.973003162, 292753.9574101781 6637991.021175833, 292694.50537013356 6637994.803334004))
这里发生了什么?考虑到 L2 边界在 P 边上不完全相交,这是否是 Shapely 浮点的问题? 如果是这样,我怎样才能用现实世界的数据实现这样的操作?
P.S:我想对数百个多边形实现这一点,并且随机分割对其中的一些(大约 10%)有效,这确实令人困惑。
正如评论中已经提到的,您应该分割整条原始线,而不是首先将其与多边形相交。
这样做的原因是,首先相交可能会遇到“鲁棒性问题”。当计算两条线之间的交点时,它们交叉的确切点有时需要比计算机使用的精度更多的数字才能“精确”。因此,计算出的直线和多边形之间的交点将略有偏差(最多几纳米)。根据点的确切结束位置,这可能会导致线不再穿过多边形,因此分割将失败。
参考:GEOS常见问题解答