@@ -16,7 +16,7 @@ def test_antimeridian_split() -> None:
1616 (
1717 shapely .geometry .box (170 , 40 , 180 , 50 ),
1818 shapely .geometry .box (- 180 , 40 , - 170 , 50 ),
19- )
19+ ),
2020 )
2121 for actual , expected in zip (split .geoms , expected .geoms ):
2222 assert actual .exterior .is_ccw
@@ -27,15 +27,15 @@ def test_antimeridian_split() -> None:
2727 assert split is None
2828
2929 canonical_other_way = Polygon (
30- ((- 170 , 40 ), (170 , 40 ), (170 , 50 ), (- 170 , 50 ), (- 170 , 40 ))
30+ ((- 170 , 40 ), (170 , 40 ), (170 , 50 ), (- 170 , 50 ), (- 170 , 40 )),
3131 )
3232 split = antimeridian .split (canonical_other_way )
3333 assert split
3434 expected = MultiPolygon (
3535 (
3636 shapely .geometry .box (- 180 , 40 , - 170 , 50 ),
3737 shapely .geometry .box (170 , 40 , 180 , 50 ),
38- )
38+ ),
3939 )
4040 for actual , expected in zip (split .geoms , expected .geoms ):
4141 assert actual .exterior .is_ccw
@@ -44,7 +44,7 @@ def test_antimeridian_split() -> None:
4444
4545def test_antimeridian_split_complicated () -> None :
4646 complicated = Polygon (
47- ((170 , 40 ), (170 , 50 ), (- 170 , 50 ), (170 , 45 ), (- 170 , 40 ), (170 , 40 ))
47+ ((170 , 40 ), (170 , 50 ), (- 170 , 50 ), (170 , 45 ), (- 170 , 40 ), (170 , 40 )),
4848 )
4949 split = antimeridian .split (complicated )
5050 assert split
@@ -57,7 +57,7 @@ def test_antimeridian_split_complicated() -> None:
5757 (170.0 , 45.0 ),
5858 (170.0 , 40.0 ),
5959 (180.0 , 40.0 ),
60- ]
60+ ],
6161 ),
6262 Polygon ([(- 180.0 , 42.5 ), (- 180.0 , 40.0 ), (- 170.0 , 40.0 ), (- 180.0 , 42.5 )]),
6363 Polygon (
@@ -67,10 +67,10 @@ def test_antimeridian_split_complicated() -> None:
6767 (170.0 , 50.0 ),
6868 (170.0 , 45.0 ),
6969 (180.0 , 47.5 ),
70- ]
70+ ],
7171 ),
7272 Polygon ([(- 180.0 , 50.0 ), (- 180.0 , 47.5 ), (- 170.0 , 50.0 ), (- 180.0 , 50.0 )]),
73- )
73+ ),
7474 )
7575 for actual , expected in zip (split .geoms , expected .geoms ):
7676 assert actual .exterior .is_ccw
@@ -86,7 +86,7 @@ def test_antimeridian_normalize() -> None:
8686 assert normalized .equals (expected ), f"actual={ normalized } , expected={ expected } "
8787
8888 canonical_other_way = Polygon (
89- ((- 170 , 40 ), (170 , 40 ), (170 , 50 ), (- 170 , 50 ), (- 170 , 40 ))
89+ ((- 170 , 40 ), (170 , 40 ), (170 , 50 ), (- 170 , 50 ), (- 170 , 40 )),
9090 )
9191 normalized = antimeridian .normalize (canonical_other_way )
9292 assert normalized
@@ -129,10 +129,11 @@ def test_item_fix_antimeridian_split() -> None:
129129 (
130130 shapely .geometry .box (170 , 40 , 180 , 50 ),
131131 shapely .geometry .box (- 180 , 40 , - 170 , 50 ),
132- )
132+ ),
133133 )
134134 for actual , expected in zip (
135- shapely .geometry .shape (fix .geometry ).geoms , expected .geoms
135+ shapely .geometry .shape (fix .geometry ).geoms ,
136+ expected .geoms ,
136137 ):
137138 assert actual .equals (expected )
138139 assert fix .bbox == [170 , 40 , - 170 , 50 ]
@@ -159,7 +160,7 @@ def test_item_fix_antimeridian_multipolygon_ok() -> None:
159160 (
160161 shapely .geometry .box (170 , 40 , 180 , 50 ),
161162 shapely .geometry .box (- 180 , 40 , - 170 , 50 ),
162- )
163+ ),
163164 )
164165 item = Item (
165166 "an-id" ,
@@ -177,7 +178,7 @@ def test_antimeridian_multipolygon() -> None:
177178 [
178179 Polygon (((170 , 40 ), (170 , 42 ), (- 170 , 42 ), (- 170 , 40 ), (170 , 40 ))),
179180 Polygon (((170 , 48 ), (170 , 50 ), (- 170 , 50 ), (- 170 , 48 ), (170 , 48 ))),
180- ]
181+ ],
181182 )
182183 split = antimeridian .split_multipolygon (multi_polygon )
183184 assert split
@@ -187,7 +188,7 @@ def test_antimeridian_multipolygon() -> None:
187188 shapely .geometry .box (- 180 , 40 , - 170 , 42 ),
188189 shapely .geometry .box (170 , 48 , 180 , 50 ),
189190 shapely .geometry .box (- 180 , 48 , - 170 , 50 ),
190- )
191+ ),
191192 )
192193 for actual , expected in zip (split .geoms , expected .geoms ):
193194 assert actual .exterior .is_ccw
@@ -199,8 +200,77 @@ def test_antimeridian_multipolygon() -> None:
199200 (
200201 Polygon (((170 , 40 ), (170 , 42 ), (190 , 42 ), (190 , 40 ), (170 , 40 ))),
201202 Polygon (((170 , 48 ), (170 , 50 ), (190 , 50 ), (190 , 48 ), (170 , 48 ))),
202- )
203+ ),
203204 )
204205 for actual , expected in zip (normalized .geoms , expected .geoms ):
205206 assert actual .exterior .is_ccw
206207 assert actual .equals (expected ), f"actual={ actual } , expected={ expected } "
208+
209+
210+ def test_antimeridian_enclose_poles () -> None :
211+ before = Polygon (((170 , 40 ), (- 170 , 50 ), (- 170 , - 50 ), (170 , - 40 ), (170 , 40 )))
212+ after = antimeridian .enclose_poles (before )
213+ assert after == Polygon (
214+ (
215+ (170 , 40 ),
216+ (180 , 45 ),
217+ (180 , 90 ),
218+ (- 180 , 90 ),
219+ (- 180 , 45 ),
220+ (- 170 , 50 ),
221+ (- 170 , - 50 ),
222+ (- 180 , - 45 ),
223+ (- 180 , - 90 ),
224+ (180 , - 90 ),
225+ (180 , - 45 ),
226+ (170 , - 40 ),
227+ (170 , 40 ),
228+ )
229+ )
230+
231+
232+ def test_antimeridian_enclose_poles_extra_crossing () -> None :
233+ before = Polygon (
234+ ((170 , 40 ), (- 170 , 50 ), (- 170 , - 50 ), (170 , - 40 ), (- 175 , 0 ), (170 , 40 ))
235+ )
236+ after = antimeridian .enclose_poles (before )
237+ assert after == Polygon (
238+ (
239+ (170 , 40 ),
240+ (180 , 45 ),
241+ (180 , 90 ),
242+ (- 180 , 90 ),
243+ (- 180 , 45 ),
244+ (- 170 , 50 ),
245+ (- 170 , - 50 ),
246+ (- 180 , - 45 ),
247+ (- 180 , - 90 ),
248+ (180 , - 90 ),
249+ (180 , - 45 ),
250+ (170 , - 40 ),
251+ (- 175 , 0 ),
252+ (170 , 40 ),
253+ )
254+ )
255+
256+
257+ def test_antimeridian_enclose_poles_both_northern_hemisphere () -> None :
258+ before = Polygon (((170 , 80 ), (- 170 , 80 ), (- 170 , 10 ), (170 , 10 ), (170 , 80 )))
259+ after = antimeridian .enclose_poles (before )
260+ assert after == Polygon (
261+ (
262+ (170 , 80 ),
263+ (180 , 80 ),
264+ (180 , 90 ),
265+ (- 180 , 90 ),
266+ (- 180 , 80 ),
267+ (- 170 , 80 ),
268+ (- 170 , 10 ),
269+ (- 180 , 10 ),
270+ (- 180 , - 90 ),
271+ (180 , - 90 ),
272+ (180 , 10 ),
273+ (170 , 10 ),
274+ (170 , 80 ),
275+ )
276+ )
0 commit comments