1
+ from collections .abc import Sequence
1
2
from enum import Enum
2
3
from typing import Literal , overload
3
4
4
5
from polyshell ._polyshell import *
5
6
6
- Polygon = list [tuple [float , float ]]
7
+ __all__ = [
8
+ "ReductionMethod" ,
9
+ "ReductionMode" ,
10
+ "reduce_polygon" ,
11
+ "reduce_polygon_eps" ,
12
+ "reduce_polygon_len" ,
13
+ "reduce_polygon_auto" ,
14
+ ]
15
+
16
+
17
+ Polygon = Sequence [tuple [float , float ]]
18
+
19
+
20
+ class NullClass :
21
+ pass
7
22
8
23
9
24
class ReductionMethod (str , Enum ):
@@ -18,13 +33,45 @@ class ReductionMode(str, Enum):
18
33
AUTO = "auto"
19
34
20
35
36
+ # Feature gates
37
+ try :
38
+ from shapely import Polygon as ShapelyPolygon
39
+
40
+ Polygon = Polygon | ShapelyPolygon
41
+ except ImportError :
42
+ ShapelyPolygon = NullClass
43
+
44
+ try :
45
+ from numpy .typing import NDArray
46
+ from numpy import ndarray
47
+
48
+ Polygon = Polygon | NDArray [float ]
49
+ except ImportError :
50
+ ndarray = NullClass
51
+
52
+
53
+ def into_polygon (obj : any ) -> Sequence [tuple [float , float ]]:
54
+ """Cast a polygon object into a supported type."""
55
+ match obj :
56
+ case [* _] as seq :
57
+ return seq
58
+ case ndarray () as arr :
59
+ return arr
60
+ case ShapelyPolygon (exterior = exterior ):
61
+ return exterior .coords
62
+ case _:
63
+ raise TypeError (
64
+ f"{ type (obj )} cannot be interpreted as Polygon object { ShapelyPolygon } "
65
+ )
66
+
67
+
21
68
@overload
22
69
def reduce_polygon (
23
70
polygon : Polygon ,
24
71
mode : Literal [ReductionMode .EPSILON ],
25
72
epsilon : float ,
26
73
method : ReductionMethod ,
27
- ) -> Polygon :
74
+ ) -> list [ list [ float ]] :
28
75
pass
29
76
30
77
@@ -34,14 +81,14 @@ def reduce_polygon(
34
81
mode : Literal [ReductionMode .LENGTH ],
35
82
length : int ,
36
83
method : ReductionMethod ,
37
- ) -> Polygon :
84
+ ) -> list [ list [ float ]] :
38
85
pass
39
86
40
87
41
88
@overload
42
89
def reduce_polygon (
43
90
polygon : Polygon , mode : Literal [ReductionMode .AUTO ], method : ReductionMethod
44
- ) -> Polygon :
91
+ ) -> list [ list [ float ]] :
45
92
pass
46
93
47
94
@@ -50,7 +97,7 @@ def reduce_polygon(
50
97
mode : ReductionMode ,
51
98
* args ,
52
99
** kwargs ,
53
- ) -> Polygon :
100
+ ) -> list [ list [ float ]] :
54
101
match mode :
55
102
case ReductionMode .EPSILON :
56
103
return reduce_polygon_eps (polygon , * args , ** kwargs )
@@ -66,7 +113,8 @@ def reduce_polygon(
66
113
67
114
def reduce_polygon_eps (
68
115
polygon : Polygon , epsilon : float , method : ReductionMethod
69
- ) -> Polygon :
116
+ ) -> list [list [float ]]:
117
+ polygon = into_polygon (polygon )
70
118
match method :
71
119
case ReductionMethod .CHARSHAPE :
72
120
return reduce_polygon_char (polygon , epsilon , len (polygon ))
@@ -84,7 +132,8 @@ def reduce_polygon_len(
84
132
polygon : Polygon ,
85
133
length : int ,
86
134
method : ReductionMethod ,
87
- ) -> Polygon :
135
+ ) -> list [list [float ]]:
136
+ polygon = into_polygon (polygon )
88
137
match method :
89
138
case ReductionMethod .CHARSHAPE :
90
139
return reduce_polygon_char (polygon , 0.0 , length ) # maximum length
@@ -98,11 +147,16 @@ def reduce_polygon_len(
98
147
)
99
148
100
149
101
- def reduce_polygon_auto (polygon : Polygon , method : ReductionMethod ) -> Polygon :
150
+ def reduce_polygon_auto (polygon : Polygon , method : ReductionMethod ) -> list [list [float ]]:
151
+ polygon = into_polygon (polygon )
102
152
match method :
103
153
case ReductionMethod .CHARSHAPE :
104
154
raise NotImplementedError
105
155
case ReductionMethod .RDP :
106
156
raise NotImplementedError
107
157
case ReductionMethod .VW :
108
158
raise NotImplementedError
159
+ case _:
160
+ raise ValueError (
161
+ f"Unknown reduction method. Must be one of { [e .value for e in ReductionMethod ]} "
162
+ )
0 commit comments