1+ import geopandas as gpd
12import numpy as np
3+ import pytest
4+ import shapely
5+ from geopandas .testing import assert_geoseries_equal
6+ from packaging .version import Version
27
3- from ..shapes import Polygon , asShape
48from ..voronoi import voronoi , voronoi_frames
59
610
711class TestVoronoi :
812 def setup_method (self ):
913 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 )]
1015
1116 self .vertices = [
1217 [4.21783295711061 , 4.084085778781038 ],
@@ -21,13 +26,197 @@ def setup_method(self):
2126 [- 9.226913414477298 , - 4.58994413837245 ],
2227 ]
2328
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+
2443 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 )
2648 assert regions == [[1 , 3 , 2 ], [4 , 5 , 1 , 0 ], [0 , 1 , 7 , 6 ], [9 , 0 , 8 ]]
2749
2850 np .testing .assert_array_almost_equal (vertices , self .vertices )
2951
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