Repository: holoviz/spatialpandas (language: python)

Issue:
Geometry test failures in CI
We are seeing some `geometry` intersection test failures in CI. Originally we thought it was related to `pandas 2.1` (issue #124, PR #125) but it isn't. What is happening is that our code is behaving the same as ever, but we compare some geometry results with that produced by `geopandas` and we have started getting slightly different results for intersection tests with a rectangle of zero area. The `geopandas` code for such either calls `shapely` or `pygeos` or handles the test itself.

I have a fix for this in progress.


Discussion / hints:

Fix patch:
diff --git a/setup.py b/setup.py
index 4fe8366..22cd702 100644
--- a/setup.py
+++ b/setup.py
@@ -34,7 +34,7 @@
     'dask',
     'fsspec',
     'numba',
-    'pandas',
+    'pandas <2.1',
     'param',
     'pyarrow >=1.0',
     'retrying',


Test patch:
diff --git a/spatialpandas/tests/geometry/algorithms/test_intersection.py b/spatialpandas/tests/geometry/algorithms/test_intersection.py
index 884de67..c52e712 100644
--- a/spatialpandas/tests/geometry/algorithms/test_intersection.py
+++ b/spatialpandas/tests/geometry/algorithms/test_intersection.py
@@ -62,6 +62,8 @@ def test_segment_intersection(ax0, ay0, ax1, ay1, bx0, by0, bx1, by1):
     assert result1 == result2
 
     # Use shapely polygon to compute expected intersection
+    if (ax0 == ax1 == bx0 == bx1) or (ay0 == ay1 == by0 == by1):
+        return
     line1 = sg.LineString([(ax0, ay0), (ax1, ay1)])
     line2 = sg.LineString([(bx0, by0), (bx1, by1)])
     expected = line1.intersects(line2)
@@ -132,6 +134,9 @@ def test_multipoint_intersects_rect(gp_multipoint, rect):
 @given(st_line_array(), st_bounds())
 @hyp_settings
 def test_line_intersects_rect(gp_line, rect):
+    x0, y0, x1, y1 = rect
+    if x0 == x1 or y0 == y1:
+        return
     sg_rect = sg.box(*rect)
 
     expected = gp_line.intersects(sg_rect)
@@ -154,6 +159,9 @@ def test_line_intersects_rect(gp_line, rect):
 @given(st_multiline_array(), st_bounds())
 @hyp_settings
 def test_multiline_intersects_rect(gp_multiline, rect):
+    x0, y0, x1, y1 = rect
+    if x0 == x1 or y0 == y1:
+        return
     sg_rect = sg.box(*rect)
 
     expected = gp_multiline.intersects(sg_rect)
@@ -186,6 +194,9 @@ def test_multiline_intersects_rect(gp_multiline, rect):
 )
 @hyp_settings
 def test_polygon_intersects_rect(gp_polygon, rect):
+    x0, y0, x1, y1 = rect
+    if x0 == x1 or y0 == y1:
+        return
     sg_rect = sg.box(*rect)
 
     expected = gp_polygon.intersects(sg_rect)
@@ -216,6 +227,9 @@ def test_polygon_intersects_rect(gp_polygon, rect):
 )
 @hyp_settings
 def test_multipolygon_intersects_rect(gp_multipolygon, rect):
+    x0, y0, x1, y1 = rect
+    if x0 == x1 or y0 == y1:
+        return
     sg_rect = sg.box(*rect)
 
     expected = gp_multipolygon.intersects(sg_rect)
diff --git a/spatialpandas/tests/geometry/test_cx.py b/spatialpandas/tests/geometry/test_cx.py
index b3db000..6f14d9f 100644
--- a/spatialpandas/tests/geometry/test_cx.py
+++ b/spatialpandas/tests/geometry/test_cx.py
@@ -59,6 +59,8 @@ def test_line_cx_selection(gp_line, rect):
     x0, y0, x1, y1 = rect
     for xslice in get_slices(x0, x1):
         for yslice in get_slices(y0, y1):
+            if xslice.start == xslice.stop or yslice.start == yslice.stop:
+                continue
             expected = LineArray.from_geopandas(gp_line.cx[xslice, yslice])
             result = LineArray.from_geopandas(gp_line).cx[xslice, yslice]
             assert all(expected == result)
@@ -71,6 +73,8 @@ def test_multiline_cx_selection(gp_multiline, rect):
     x0, y0, x1, y1 = rect
     for xslice in get_slices(x0, x1):
         for yslice in get_slices(y0, y1):
+            if xslice.start == xslice.stop or yslice.start == yslice.stop:
+                continue
             expected = MultiLineArray.from_geopandas(gp_multiline.cx[xslice, yslice])
             result = MultiLineArray.from_geopandas(gp_multiline).cx[xslice, yslice]
             assert all(expected == result)
@@ -88,6 +92,8 @@ def test_polygon_cx_selection(gp_polygon, rect):
     x0, y0, x1, y1 = rect
     for xslice in get_slices(x0, x1):
         for yslice in get_slices(y0, y1):
+            if xslice.start == xslice.stop or yslice.start == yslice.stop:
+                continue
             expected = PolygonArray.from_geopandas(gp_polygon.cx[xslice, yslice])
             result = PolygonArray.from_geopandas(gp_polygon).cx[xslice, yslice]
             assert all(expected == result)
@@ -105,6 +111,8 @@ def test_multipolygon_cx_selection(gp_multipolygon, rect):
     x0, y0, x1, y1 = rect
     for xslice in get_slices(x0, x1):
         for yslice in get_slices(y0, y1):
+            if xslice.start == xslice.stop or yslice.start == yslice.stop:
+                continue
             expected = MultiPolygonArray.from_geopandas(
                 gp_multipolygon.cx[xslice, yslice]
             )