Multipolygon.intersection 失败

Multipolygon.intersection fails

以下代码创建不同版本的多边形,然后计算它们与另一个多边形的交集。坐标是真实程序在崩溃之前取的一长串,困扰我。

为什么multipolygon1.intersection(multipolygon2)会失败,而multipolygon1的所有其他变体都能成功与multipolygon2相交?

更重要的是,由于多边形都是由 shapely 的 uniondifference 运算符创建的,我该如何避免这个问题?我是否应该总是期望 shapely 会创建不起作用的多边形?

详情如下

multipolygon1的变化是3:

起初我认为 multipolygon1 是一个无效的形状多边形,所以我尝试缓冲它,它起作用了。并且与缓冲版本的交集也起作用。所以 multipolygon1 似乎是有效的。

然后我删除了最后一个多边形并且相交成功了。我以为我发现了问题:我需要修复最后一个多边形。

然后我用前三个和最后一个创建了另一个版本,它成功了。所以最后一个没有什么可以解决的。

结论:multipolygon1 是有效的,因为可以 buffered,没有最后一个的所有多边形都有效,最后一个有一些其他多边形的有效,所以我不知道哪里有问题。

我注意到有些多边形非常小。例如 polygons1[12].area = 1.4210854715202004e-14,但它们都是由 uniondifference 的序列创建的。它们做得很匀称,所以它们应该是有效的。

这里是代码

import shapely.geometry

mp1 = [[(22.13354026441686, 0.0),
        (0.0, 0.0),
        (0.0, 13.242081447963805),
        (0.056818181818172775, 13.278846153846153),
        (17.25, 13.278846153846153),
        (17.25, 11.853846153846154),
        (17.375, 11.853846153846154),
        (17.375, 13.278846153846153),
        (18.8, 13.278846153846153),
        (18.8, 13.403846153846153),
        (17.375, 13.403846153846153),
        (17.375, 24.48472850678734),
        (18.551333743585833, 25.24588563498994),
        (18.483427333816174, 25.350831904633957),
        (17.375, 24.63361421804702),
        (17.375, 25.95384615384616),
        (17.25, 25.95384615384616),
        (17.25, 24.552731865105844),
        (0.019903900780485984, 13.403846153846153),
        (0.0, 13.403846153846153),
        (0.0, 15.285503429011813),
        (0.12499999999999992, 15.366385781952989),
        (0.125, 14.046153846153844),
        (0.25, 14.046153846153844),
        (0.24999999999999992, 15.447268134894166),
        (17.48009609921951, 26.596153846153857),
        (18.8, 26.596153846153857),
        (18.8, 26.721153846153857),
        (17.67327791740133, 26.721153846153857),
        (18.619240153355495, 27.33324705765361),
        (18.551333743585836, 27.43819332729763),
        (18.25, 27.243212669683263),
        (18.25, 28.601114288740316),
        (35.480096099219516, 39.75),
        (36.8, 39.75),
        (36.8, 39.875),
        (35.673277917401336, 39.875),
        (35.866459735583156, 40.0),
        (40.0, 40.0),
        (40.0, 28.95022624434389),
        (39.94318181818183, 28.913461538461544),
        (22.75, 28.913461538461533),
        (22.75, 30.338461538461534),
        (22.625, 30.338461538461534),
        (22.625, 28.913461538461533),
        (21.2, 28.913461538461533),
        (21.2, 28.788461538461533),
        (22.625, 28.788461538461533),
        (22.625, 17.70757918552036),
        (21.448666256414164, 16.94642205731776),
        (21.516572666183823, 16.841475787673744),
        (22.625, 17.558693474260682),
        (22.625, 16.238461538461536),
        (22.75, 16.238461538461536),
        (22.75, 17.63957582720186),
        (39.980096099219516, 28.788461538461544),
        (40.0, 28.788461538461544),
        (40.0, 26.906804263295886),
        (39.875, 26.825921910354708),
        (39.875, 28.146153846153847),
        (39.75, 28.146153846153847),
        (39.75, 26.74503955741353),
        (22.5199039007805, 15.596153846153847),
        (21.2, 15.596153846153847),
        (21.2, 15.471153846153847),
        (22.32672208259868, 15.471153846153847),
        (21.38075984664451, 14.859060634654089),
        (21.448666256414167, 14.75411436501007),
        (21.75, 14.949095022624432),
        (21.75, 13.59119340356747),
        (21.71308571896216, 13.56730769230769),
        (21.2, 13.56730769230769),
        (21.2, 13.44230769230769),
        (21.519903900780342, 13.44230769230769),
        (4.519903900780493, 2.4423076923076925),
        (3.1999999999999993, 2.4423076923076925),
        (3.1999999999999993, 2.3173076923076925),
        (4.3267220825986765, 2.3173076923076925),
        (3.3807598466445077, 1.7052144808079315),
        (3.4486662564141675, 1.6002682111639128),
        (4.55681818181818, 2.3173076923076925),
        (21.75, 2.3173076923076925),
        (21.75, 1.795248868778278),
        (21.448666256414167, 1.600268211163916),
        (21.516572666183826, 1.495321941519897),
        (21.75, 1.6463631575185977),
        (21.75, 0.892307692307693),
        (21.875, 0.892307692307693),
        (21.875, 1.7272455104597744),
        (22.625, 2.2125396281068337),
        (22.625, 0.8923076923076909),
        (22.75, 0.8923076923076909),
        (22.75, 2.2934219810480094),
        (22.786914281037692, 2.3173076923076925),
        (23.3, 2.3173076923076925),
        (23.3, 2.4423076923076925),
        (22.98009609921951, 2.4423076923076925),
        (39.98009609921951, 13.442307692307693),
        (40.0, 13.442307692307693),
        (40.0, 11.560650417142032),
        (39.875, 11.479768064200856),
        (39.875, 12.8),
        (39.75, 12.8),
        (39.75, 11.39888571125968),
        (22.519903900780495, 0.25),
        (21.2, 0.25),
        (21.2, 0.125),
        (22.32672208259868, 0.125),
        (22.13354026441686, 0.0)],
       [(0.0, 15.434389140271493),
        (0.0, 26.596153846153847),
        (0.12499999999999921, 26.596153846153847),
        (0.1249999999999999, 15.51527149321267),
        (0.0, 15.434389140271493)],
       [(0.0, 26.721153846153847),
        (0.0, 40.0),
        (18.125, 40.0),
        (18.125, 39.875),
        (16.7, 39.875),
        (16.7, 39.75),
        (18.125, 39.75),
        (18.125, 28.66911764705882),
        (16.948666256414167, 27.90796051885622),
        (17.016572666183826, 27.803014249212204),
        (18.125, 28.52023193579914),
        (18.125, 27.199999999999996),
        (18.183216783216764, 27.199999999999996),
        (17.443181818181824, 26.721153846153857),
        (0.2499999999999992, 26.721153846153847),
        (0.2499999999999991, 28.146153846153847),
        (0.12499999999999911, 28.146153846153847),
        (0.1249999999999992, 26.721153846153847),
        (0.0, 26.721153846153847)],
       [(18.25, 40.0),
        (35.63636363636365, 40.0),
        (35.44318181818183, 39.875),
        (18.25, 39.875),
        (18.25, 40.0)],
       [(21.816783216783378, 14.992307692307794),
        (22.556818181818187, 15.471153846153847),
        (39.75, 15.471153846153847),
        (39.75, 14.046153846153846),
        (39.875, 14.046153846153846),
        (39.875, 15.471153846153847),
        (40.0, 15.471153846153847),
        (40.0, 13.604072398190045),
        (39.94318181818182, 13.567307692307693),
        (22.75, 13.56730769230769),
        (22.75, 14.089366515837206),
        (23.051333743585833, 14.28434717345157),
        (22.983427333816174, 14.389293443095589),
        (22.75, 14.238252227096886),
        (22.75, 14.99230769230769),
        (22.625, 14.99230769230769),
        (22.625, 14.15736987415571),
        (21.875, 13.672075756508647),
        (21.875, 14.992307692307794),
        (21.816783216783378, 14.992307692307794)],
       [(22.625, 14.008484162896028),
        (22.625, 13.56730769230769),
        (21.943181818181664, 13.56730769230769),
        (22.625, 14.008484162896028)],
       [(21.875, 13.44230769230769),
        (22.625, 13.44230769230769),
        (22.625, 2.4423076923076925),
        (21.875, 2.4423076923076925),
        (21.875, 13.44230769230769)],
       [(22.556818181818187, 2.3173076923076925),
        (21.875, 1.8761312217194543),
        (21.875, 2.3173076923076925),
        (22.556818181818187, 2.3173076923076925)],
       [(40.0, 26.7579185520362),
        (40.0, 15.596153846153847),
        (39.875, 15.596153846153847),
        (39.875, 26.677036199095024),
        (40.0, 26.7579185520362)],
       [(39.75, 0.0),
        (22.363636363636367, 0.0),
        (22.556818181818183, 0.125),
        (39.75, 0.125),
        (39.75, 0.0)],
       [(40.0, 0.125),
        (40.0, 0.0),
        (39.875, 0.0),
        (39.875, 0.125),
        (40.0, 0.125)],
       [(40.0, 11.41176470588235),
        (40.0, 0.25),
        (39.875, 0.25),
        (39.875, 11.330882352941174),
        (40.0, 11.41176470588235)],
       [(39.75, 13.442307692307693),
        (22.750000000000004, 2.4423076923076925),
        (22.75, 2.4423076923076925),
        (39.75, 13.442307692307693)],
       [(22.75, 28.788461538461533),
        (39.75000000000001, 28.788461538461544),
        (34.083333333333336, 25.121794871794876),
        (39.75, 28.78846153846154),
        (22.75, 28.788461538461533)],
       [(4.75, 2.4423076923076925),
        (4.749999999999997, 2.4423076923076925),
        (11.125, 6.56730769230773),
        (4.75, 2.4423076923076925)],
       [(35.25, 39.75),
        (35.25000000000001, 39.75),
        (18.25, 28.749999999999993),
        (18.25, 28.749999999999996),
        (35.25, 39.75)],
       [(17.25, 13.403846153846155),
        (17.25, 13.403846153846153),
        (0.2499999999999929, 13.403846153846153),
        (17.25, 24.403846153846164),
        (17.25, 24.40384615384616),
        (0.25, 13.403846153846155),
        (17.25, 13.403846153846155)],
       [(0.25, 15.596153846153847),
        (0.2499999999999999, 15.596153846153847),
        (0.2499999999999992, 26.596153846153847),
        (17.250000000000007, 26.596153846153857),
        (8.750000000000002, 21.09615384615385),
        (17.25, 26.596153846153854),
        (0.25, 26.596153846153847),
        (0.25, 15.596153846153847)]]

mp2 = [[(0.25, 0.25),
        (39.75, 0.25),
        (39.75, 39.75),
        (0.25, 39.75),
        (0.25, 0.25)]]

polygons1 = [shapely.geometry.Polygon(pg) for pg in mp1]
polygons2 = [shapely.geometry.Polygon(pg) for pg in mp2]

multipolygon1 = shapely.geometry.MultiPolygon(polygons1)
multipolygon1_buffered = multipolygon1.buffer(0.001)
multipolygon1_without_last_polygon = shapely.geometry.MultiPolygon(polygons1[:-1])
multipolygon1_with_first_3_and_last = shapely.geometry.MultiPolygon(polygons1[:3] + polygons1[-1:])

multipolygon2 = shapely.geometry.MultiPolygon(polygons2)

for mp in [multipolygon1, 
           multipolygon1_buffered, 
           multipolygon1_without_last_polygon, 
           multipolygon1_with_first_3_and_last]:
    try:
        mp.intersection(multipolygon2)
    except Exception as e:
        print('fail:', e)
    else:
        print('success')

最后一环自相交

详情见GitHub:https://github.com/Toblerity/Shapely/issues/344