|
1 | 1 | import ctypes |
2 | 2 | import itertools |
3 | 3 | import json |
| 4 | +import math |
4 | 5 | import pickle |
5 | 6 | import random |
6 | 7 | from binascii import a2b_hex |
7 | 8 | from io import BytesIO |
8 | | -from unittest import mock |
| 9 | +from unittest import mock, skipIf |
9 | 10 |
|
10 | 11 | from django.contrib.gis import gdal |
11 | 12 | from django.contrib.gis.geos import ( |
@@ -241,6 +242,75 @@ def test_eq_with_srid(self): |
241 | 242 | self.assertEqual(p0, "SRID=0;POINT (5 23)") |
242 | 243 | self.assertNotEqual(p1, "SRID=0;POINT (5 23)") |
243 | 244 |
|
| 245 | + @skipIf(geos_version_tuple() < (3, 12), "GEOS >= 3.12.0 is required") |
| 246 | + def test_equals_identical(self): |
| 247 | + tests = [ |
| 248 | + # Empty inputs of different types are not equals_identical. |
| 249 | + ("POINT EMPTY", "LINESTRING EMPTY", False), |
| 250 | + # Empty inputs of different dimensions are not equals_identical. |
| 251 | + ("POINT EMPTY", "POINT Z EMPTY", False), |
| 252 | + # Non-empty inputs of different dimensions are not equals_identical. |
| 253 | + ("POINT Z (1 2 3)", "POINT M (1 2 3)", False), |
| 254 | + ("POINT ZM (1 2 3 4)", "POINT Z (1 2 3)", False), |
| 255 | + # Inputs with different structure are not equals_identical. |
| 256 | + ("LINESTRING (1 1, 2 2)", "MULTILINESTRING ((1 1, 2 2))", False), |
| 257 | + # Inputs with different types are not equals_identical. |
| 258 | + ( |
| 259 | + "GEOMETRYCOLLECTION (LINESTRING (1 1, 2 2))", |
| 260 | + "MULTILINESTRING ((1 1, 2 2))", |
| 261 | + False, |
| 262 | + ), |
| 263 | + # Same lines are equals_identical. |
| 264 | + ("LINESTRING M (1 1 0, 2 2 1)", "LINESTRING M (1 1 0, 2 2 1)", True), |
| 265 | + # Different lines are not equals_identical. |
| 266 | + ("LINESTRING M (1 1 0, 2 2 1)", "LINESTRING M (1 1 1, 2 2 1)", False), |
| 267 | + # Same polygons are equals_identical. |
| 268 | + ("POLYGON ((0 0, 1 0, 1 1, 0 0))", "POLYGON ((0 0, 1 0, 1 1, 0 0))", True), |
| 269 | + # Different polygons are not equals_identical. |
| 270 | + ("POLYGON ((0 0, 1 0, 1 1, 0 0))", "POLYGON ((1 0, 1 1, 0 0, 1 0))", False), |
| 271 | + # Different polygons (number of holes) are not equals_identical. |
| 272 | + ( |
| 273 | + "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 2 1, 2 2, 1 1))", |
| 274 | + ( |
| 275 | + "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 2 1, 2 2, 1 1), " |
| 276 | + "(3 3, 4 3, 4 4, 3 3))" |
| 277 | + ), |
| 278 | + False, |
| 279 | + ), |
| 280 | + # Same collections are equals_identical. |
| 281 | + ( |
| 282 | + "MULTILINESTRING ((1 1, 2 2), (2 2, 3 3))", |
| 283 | + "MULTILINESTRING ((1 1, 2 2), (2 2, 3 3))", |
| 284 | + True, |
| 285 | + ), |
| 286 | + # Different collections (structure) are not equals_identical. |
| 287 | + ( |
| 288 | + "MULTILINESTRING ((1 1, 2 2), (2 2, 3 3))", |
| 289 | + "MULTILINESTRING ((2 2, 3 3), (1 1, 2 2))", |
| 290 | + False, |
| 291 | + ), |
| 292 | + ] |
| 293 | + for g1, g2, is_equal_identical in tests: |
| 294 | + with self.subTest(g1=g1, g2=g2): |
| 295 | + self.assertIs( |
| 296 | + fromstr(g1).equals_identical(fromstr(g2)), is_equal_identical |
| 297 | + ) |
| 298 | + |
| 299 | + @skipIf(geos_version_tuple() < (3, 12), "GEOS >= 3.12.0 is required") |
| 300 | + def test_infinite_values_equals_identical(self): |
| 301 | + # Input with identical infinite values are equals_identical. |
| 302 | + g1 = Point(x=float("nan"), y=math.inf) |
| 303 | + g2 = Point(x=float("nan"), y=math.inf) |
| 304 | + self.assertIs(g1.equals_identical(g2), True) |
| 305 | + |
| 306 | + @mock.patch("django.contrib.gis.geos.libgeos.geos_version", lambda: b"3.11.0") |
| 307 | + def test_equals_identical_geos_version(self): |
| 308 | + g1 = fromstr("POINT (1 2 3)") |
| 309 | + g2 = fromstr("POINT (1 2 3)") |
| 310 | + msg = "GEOSGeometry.equals_identical() requires GEOS >= 3.12.0" |
| 311 | + with self.assertRaisesMessage(GEOSException, msg): |
| 312 | + g1.equals_identical(g2) |
| 313 | + |
244 | 314 | def test_points(self): |
245 | 315 | "Testing Point objects." |
246 | 316 | prev = fromstr("POINT(0 0)") |
|
0 commit comments