回答編集履歴
2
追記
test
CHANGED
@@ -1,17 +1,32 @@
|
|
1
1
|
[Shapely](https://shapely.readthedocs.io/en/stable/index.html)の[unary_union](https://shapely.readthedocs.io/en/stable/reference/shapely.unary_union.html#shapely-unary-union)が使えそうです。
|
2
2
|
結合後、直線区間中に連続する点は残りますが、それを除く方法はおそらく難しくなく、Shapelyの関数としても用意されているかもしれません。
|
3
|
+
|
4
|
+
### 追記
|
5
|
+
|
6
|
+
不要な点の削除は[normalize](https://shapely.readthedocs.io/en/stable/reference/shapely.Polygon.html#shapely.Polygon.normalize)して[simplify](https://shapely.readthedocs.io/en/stable/reference/shapely.Polygon.html#shapely.Polygon.simplify)すればよい感じです。
|
7
|
+
参考:[Simplify method can not simplify duplicated vertices of a ring #1638](https://github.com/shapely/shapely/issues/1638)
|
8
|
+
|
3
9
|
```Python
|
10
|
+
import matplotlib.pyplot as plt
|
4
11
|
import shapely
|
5
12
|
from shapely.geometry import Polygon
|
6
13
|
|
7
14
|
# ポリゴンは反時計回りで定義
|
8
15
|
p1 = Polygon([(10,0),(10,10),(20,10),(20,15),(25,15),(25,5),(30,5),(30,0)][::-1])
|
9
16
|
p2 = Polygon([(5,25),(25,25),(25,15),(20,15),(20,10),(15,10),(15,20),(5,20)][::-1])
|
17
|
+
p3 = shapely.unary_union([p1,p2])
|
10
18
|
|
11
|
-
p
|
19
|
+
plt.plot(*p3.exterior.xy, marker="o")
|
20
|
+
plt.show()
|
12
21
|
print(p3)
|
13
22
|
# POLYGON ((25 15, 25 5, 30 5, 30 0, 10 0, 10 10, 15 10, 15 20, 5 20, 5 25, 25 25, 25 15))
|
14
23
|
|
24
|
+
# 不要な点を取り除く
|
25
|
+
p3 = p3.normalize().simplify(0.1)
|
26
|
+
plt.plot(*p3.exterior.xy, marker="o")
|
27
|
+
plt.show()
|
28
|
+
print(p3)
|
29
|
+
# POLYGON ((5 20, 5 25, 25 25, 25 5, 30 5, 30 0, 10 0, 10 10, 15 10, 15 20, 5 20))
|
15
30
|
|
16
31
|
# 重ならない
|
17
32
|
p1 = Polygon([(0,0),(1,0),(1,1),(0,1),(0,0)])
|
@@ -49,4 +64,5 @@
|
|
49
64
|
print(shapely.unary_union([p1,p2]))
|
50
65
|
# POLYGON ((3 1, 3 0, 0 0, 0 1, 0 3, 3 3, 3 1), (1 1, 2 1, 2 2, 1 2, 1 1))
|
51
66
|
```
|
52
|
-
|
67
|
+
![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2023-06-20/94f090e8-4fa7-4131-a91c-53aee179df88.png)
|
68
|
+
![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2023-06-20/bd359cc7-250e-4aff-8928-51532fc0b62a.png)
|
1
追記
test
CHANGED
@@ -11,5 +11,42 @@
|
|
11
11
|
p3 = shapely.unary_union([p1,p2])
|
12
12
|
print(p3)
|
13
13
|
# POLYGON ((25 15, 25 5, 30 5, 30 0, 10 0, 10 10, 15 10, 15 20, 5 20, 5 25, 25 25, 25 15))
|
14
|
+
|
15
|
+
|
16
|
+
# 重ならない
|
17
|
+
p1 = Polygon([(0,0),(1,0),(1,1),(0,1),(0,0)])
|
18
|
+
p2 = Polygon([(2,0),(3,0),(3,1),(2,1),(2,0)])
|
19
|
+
print(shapely.unary_union([p1,p2]))
|
20
|
+
# MULTIPOLYGON (((0 0, 1 0, 1 1, 0 1, 0 0)), ((2 0, 3 0, 3 1, 2 1, 2 0)))
|
21
|
+
|
22
|
+
# 内包
|
23
|
+
p1 = Polygon([(0,0),(3,0),(3,3),(0,3),(0,0)])
|
24
|
+
p2 = Polygon([(1,1),(2,1),(2,2),(1,2),(1,1)])
|
25
|
+
print(shapely.unary_union([p1,p2]))
|
26
|
+
# POLYGON ((0 0, 0 3, 3 3, 3 0, 0 0))
|
27
|
+
|
28
|
+
# 辺で接する
|
29
|
+
p1 = Polygon([(0,0),(1,0),(1,1),(0,1),(0,0)])
|
30
|
+
p2 = Polygon([(1,0),(2,0),(2,1),(1,1),(1,0)])
|
31
|
+
print(shapely.unary_union([p1,p2]))
|
32
|
+
# POLYGON ((1 0, 0 0, 0 1, 1 1, 2 1, 2 0, 1 0))
|
33
|
+
|
34
|
+
# 点で接する
|
35
|
+
p1 = Polygon([(0,0),(1,0),(1,1),(0,1),(0,0)])
|
36
|
+
p2 = Polygon([(1,1),(2,1),(2,2),(1,2),(1,1)])
|
37
|
+
print(shapely.unary_union([p1,p2]))
|
38
|
+
# MULTIPOLYGON (((1 1, 1 0, 0 0, 0 1, 1 1)), ((1 1, 1 2, 2 2, 2 1, 1 1)))
|
39
|
+
|
40
|
+
# 重複
|
41
|
+
p1 = Polygon([(0,0),(2,0),(2,2),(0,2),(0,0)])
|
42
|
+
p2 = Polygon([(0,1),(2,1),(2,3),(0,1)])
|
43
|
+
print(shapely.unary_union([p1,p2]))
|
44
|
+
# POLYGON ((2 1, 2 0, 0 0, 0 1, 0 2, 1 2, 2 3, 2 2, 2 1))
|
45
|
+
|
46
|
+
# 穴ができる
|
47
|
+
p1 = Polygon([(0,0),(3,0),(3,1),(0,1),(0,0)])
|
48
|
+
p2 = Polygon([(2,1),(3,1),(3,3),(0,3),(0,1),(1,1),(1,2),(2,2),(2,1)])
|
49
|
+
print(shapely.unary_union([p1,p2]))
|
50
|
+
# POLYGON ((3 1, 3 0, 0 0, 0 1, 0 3, 3 3, 3 1), (1 1, 2 1, 2 2, 1 2, 1 1))
|
14
51
|
```
|
15
52
|
|