1
+ import geopandas as gpd
1
2
import numpy as np
3
+ import pytest
4
+ import shapely
5
+ from geopandas .testing import assert_geoseries_equal
6
+ from packaging .version import Version
2
7
3
- from ..shapes import Polygon , asShape
4
8
from ..voronoi import voronoi , voronoi_frames
5
9
6
10
7
11
class TestVoronoi :
8
12
def setup_method (self ):
9
13
self .points = [(10.2 , 5.1 ), (4.7 , 2.2 ), (5.3 , 5.7 ), (2.7 , 5.3 )]
14
+ self .points2 = [(10 , 5 ), (4 , 2 ), (5 , 5 )]
10
15
11
16
self .vertices = [
12
17
[4.21783295711061 , 4.084085778781038 ],
@@ -21,13 +26,197 @@ def setup_method(self):
21
26
[- 9.226913414477298 , - 4.58994413837245 ],
22
27
]
23
28
29
+ p1 = shapely .Polygon ([(0 , 0 ), (0 , 1 ), (1 , 1 ), (1 , 0 )])
30
+ p2 = shapely .Polygon ([(0 , 1 ), (0 , 2 ), (1 , 2 ), (1 , 1 )])
31
+ p3 = shapely .Polygon ([(1 , 1 ), (1 , 2 ), (2 , 2 ), (2 , 1 )])
32
+ p4 = shapely .Polygon ([(1 , 0 ), (1 , 1 ), (2 , 1 ), (2 , 0 )])
33
+ self .polygons = gpd .GeoSeries ([p1 , p2 , p3 , p4 ], crs = "EPSG:3857" )
34
+
35
+ self .lines = gpd .GeoSeries (
36
+ [
37
+ shapely .LineString ([(0 , 0 ), (0 , 1 )]),
38
+ shapely .LineString ([(1 , 1 ), (1 , 0 )]),
39
+ ],
40
+ crs = "EPSG:3857" ,
41
+ )
42
+
24
43
def test_voronoi (self ):
25
- regions , vertices = voronoi (self .points )
44
+ with pytest .warns (
45
+ FutureWarning , match = "The 'voronoi' function is considered private"
46
+ ):
47
+ regions , vertices = voronoi (self .points )
26
48
assert regions == [[1 , 3 , 2 ], [4 , 5 , 1 , 0 ], [0 , 1 , 7 , 6 ], [9 , 0 , 8 ]]
27
49
28
50
np .testing .assert_array_almost_equal (vertices , self .vertices )
29
51
30
- def test_voronoi_frames (self ):
31
- r_df , p_df = voronoi_frames (self .points )
32
- region = r_df .iloc [0 ]["geometry" ]
33
- assert isinstance (asShape (region ), Polygon )
52
+ def test_from_array (self ):
53
+ geoms = voronoi_frames (self .points2 , as_gdf = False , return_input = False )
54
+ expected = gpd .GeoSeries .from_wkt (
55
+ [
56
+ "POLYGON ((7.5 2.5, 7.5 5, 10 5, 10 2, 7.75 2, 7.5 2.5))" ,
57
+ "POLYGON ((7.5 2.5, 7.75 2, 4 2, 4 3.66666666, 7.5 2.5))" ,
58
+ "POLYGON ((7.5 2.5, 4 3.66666666, 4 5, 7.5 5, 7.5 2.5))" ,
59
+ ],
60
+ )
61
+ assert_geoseries_equal (
62
+ shapely .normalize (geoms ),
63
+ shapely .normalize (expected ),
64
+ check_less_precise = True ,
65
+ )
66
+
67
+ def test_from_polygons (self ):
68
+ geoms = voronoi_frames (
69
+ self .polygons , as_gdf = False , return_input = False , shrink = 0.1
70
+ )
71
+ expected = gpd .GeoSeries .from_wkt (
72
+ [
73
+ "POLYGON ((0.5 1, 1 1, 1 0.5, 1 0.1, 0.1 0.1, 0.1 1, 0.5 1))" ,
74
+ "POLYGON ((1 1.5, 1 1, 0.5 1, 0.1 1, 0.1 1.9, 1 1.9, 1 1.5))" ,
75
+ "POLYGON ((1 1.5, 1 1.9, 1.9 1.9, 1.9 1, 1.5 1, 1 1, 1 1.5))" ,
76
+ "POLYGON ((1 0.5, 1 1, 1.5 1, 1.9 1, 1.9 0.1, 1 0.1, 1 0.5))" ,
77
+ ],
78
+ crs = "EPSG:3857" ,
79
+ )
80
+ assert_geoseries_equal (
81
+ shapely .normalize (geoms ),
82
+ shapely .normalize (expected ),
83
+ check_less_precise = True ,
84
+ )
85
+
86
+ @pytest .mark .skipif (
87
+ Version (gpd .__version__ ) < Version ("0.13.0" ),
88
+ reason = "requires geopandas>=0.13.0" ,
89
+ )
90
+ def test_from_lines (self ):
91
+ geoms = voronoi_frames (
92
+ self .lines , as_gdf = False , return_input = False , segment = 0.1
93
+ )
94
+ expected = gpd .GeoSeries .from_wkt (
95
+ [
96
+ "POLYGON ((0.5 0.95, 0.5 0, 0 0, 0 1, 0.5 0.95))" ,
97
+ "POLYGON ((0.5 0.05, 0.5 1, 1 1, 1 0, 0.5 0.05))" ,
98
+ ],
99
+ crs = "EPSG:3857" ,
100
+ )
101
+ assert_geoseries_equal (geoms .simplify (0.1 ), expected , check_less_precise = True )
102
+
103
+ @pytest .mark .skipif (
104
+ Version (gpd .__version__ ) >= Version ("0.13.0" ),
105
+ reason = "requires geopandas<0.13.0" ,
106
+ )
107
+ def test_from_lines_import_error (self ):
108
+ with pytest .raises (
109
+ ImportError ,
110
+ match = "Voronoi tessellation of lines requires geopandas 0.13.0 or later." ,
111
+ ):
112
+ voronoi_frames (self .lines , as_gdf = False , return_input = False , segment = 0.1 )
113
+
114
+ def test_clip_none (self ):
115
+ geoms = voronoi_frames (
116
+ self .points2 , as_gdf = False , return_input = False , clip = None
117
+ )
118
+ expected = gpd .GeoSeries .from_wkt (
119
+ [
120
+ "POLYGON ((16 11, 16 -4, 10.75 -4, 7.5 2.5, 7.5 11, 16 11))" ,
121
+ "POLYGON ((-2 -4, -2 5.6666666, 7.5 2.5, 10.75 -4, -2 -4))" ,
122
+ "POLYGON ((-2 11, 7.5 11, 7.5 2.5, -2 5.66666666, -2 11))" ,
123
+ ],
124
+ )
125
+ assert_geoseries_equal (
126
+ shapely .normalize (geoms ),
127
+ shapely .normalize (expected ),
128
+ check_less_precise = True ,
129
+ )
130
+
131
+ def test_clip_chull (self ):
132
+ geoms = voronoi_frames (
133
+ self .points2 , as_gdf = False , return_input = False , clip = "convex_hull"
134
+ )
135
+ expected = gpd .GeoSeries .from_wkt (
136
+ [
137
+ "POLYGON ((7.5 5, 10 5, 7.5 3.75, 7.5 5))" ,
138
+ "POLYGON ((6 3, 4 2, 4.5 3.5, 6 3))" ,
139
+ "POLYGON ((7.5 3.75, 6 3, 4.5 3.5, 5 5, 7.5 5, 7.5 3.75))" ,
140
+ ],
141
+ )
142
+ assert_geoseries_equal (
143
+ shapely .normalize (geoms ),
144
+ shapely .normalize (expected ),
145
+ check_less_precise = True ,
146
+ )
147
+
148
+ def test_clip_ahull (self ):
149
+ geoms = voronoi_frames (
150
+ self .points2 , as_gdf = False , return_input = False , clip = "alpha_shape"
151
+ )
152
+ expected = gpd .GeoSeries .from_wkt (
153
+ [
154
+ "POLYGON ((7.5 5, 10 5, 7.5 3.75, 7.5 5))" ,
155
+ "POLYGON ((6 3, 4 2, 4.5 3.5, 6 3))" ,
156
+ "POLYGON ((7.5 3.75, 6 3, 4.5 3.5, 5 5, 7.5 5, 7.5 3.75))" ,
157
+ ],
158
+ )
159
+ assert_geoseries_equal (
160
+ shapely .normalize (geoms ),
161
+ shapely .normalize (expected ),
162
+ check_less_precise = True ,
163
+ )
164
+
165
+ def test_clip_polygon (self ):
166
+ geoms = voronoi_frames (
167
+ self .points2 ,
168
+ as_gdf = False ,
169
+ return_input = False ,
170
+ clip = shapely .box (- 10 , - 10 , 10 , 10 ),
171
+ )
172
+ expected = gpd .GeoSeries .from_wkt (
173
+ [
174
+ "POLYGON ((7.5 2.5, 7.5 10, 10 10, 10 -2.5, 7.5 2.5))" ,
175
+ "POLYGON ("
176
+ "(-10 8.333333, 7.5 2.5, 10 -2.5, 10 -10, -10 -10, -10 8.333333))" ,
177
+ "POLYGON ((7.5 2.5, -10 8.33333333, -10 10, 7.5 10, 7.5 2.5))" ,
178
+ ],
179
+ )
180
+ assert_geoseries_equal (
181
+ shapely .normalize (geoms ),
182
+ shapely .normalize (expected ),
183
+ check_less_precise = True ,
184
+ )
185
+
186
+ def test_clip_error (self ):
187
+ with pytest .raises (ValueError , match = "Clip type 'invalid' not understood." ):
188
+ voronoi_frames (self .points2 , clip = "invalid" )
189
+
190
+ def test_as_gdf (self ):
191
+ geoms , polys = voronoi_frames (self .polygons , as_gdf = True , return_input = True )
192
+ assert isinstance (geoms , gpd .GeoDataFrame )
193
+ assert isinstance (polys , gpd .GeoDataFrame )
194
+
195
+ with pytest .warns (
196
+ FutureWarning ,
197
+ match = "The 'as_gdf' parameter currently defaults to True but will" ,
198
+ ):
199
+ voronoi_frames (self .points2 , return_input = True )
200
+
201
+ def test_return_input (self ):
202
+ geoms , polys = voronoi_frames (self .polygons , return_input = True , as_gdf = False )
203
+ assert isinstance (geoms , gpd .GeoSeries )
204
+ assert polys is self .polygons
205
+
206
+ with pytest .warns (
207
+ FutureWarning ,
208
+ match = "The 'return_input' parameter currently defaults to True but will" ,
209
+ ):
210
+ voronoi_frames (self .points2 , as_gdf = True )
211
+
212
+ def test_radius (self ):
213
+ with pytest .warns (FutureWarning , match = "The 'radius' parameter is deprecated" ):
214
+ voronoi_frames (self .points2 , radius = 1 )
215
+
216
+ @pytest .mark .parametrize ("clip" , ["none" , "bounds" , "chull" , "ahull" ])
217
+ def test_deprecated_clip (self , clip ):
218
+ with pytest .warns (
219
+ FutureWarning ,
220
+ match = f"The '{ clip } ' option for the 'clip' parameter is deprecated" ,
221
+ ):
222
+ voronoi_frames (self .points2 , clip = clip )
0 commit comments