paleolimbot commented on code in PR #816:
URL: https://github.com/apache/sedona-db/pull/816#discussion_r3230297915
##########
python/sedonadb/tests/geography/test_geog_predicates.py:
##########
@@ -49,3 +236,395 @@ def test_st_intersects(eng, geom1, geom2, expected):
f"SELECT ST_Intersects({geog_or_null(geom1)}, {geog_or_null(geom2)})",
expected,
)
+
+
[email protected]("eng", [SedonaDB, BigQuery])
[email protected](
+ ("geom1", "geom2", "expected"),
+ [
+ # Nulls
+ pytest.param(None, "POINT EMPTY", None, id="null_contains"),
+ pytest.param("POINT EMPTY", None, None, id="contains_null"),
+ pytest.param(None, None, None, id="null_contains_null"),
+ # Empties
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "POINT EMPTY",
+ False,
+ id="contains_empty",
+ ),
+ pytest.param(
+ "POINT EMPTY",
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ False,
+ id="empty_contains",
+ ),
+ # Polygon contains interior point
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "POINT (0.25 0.25)",
+ True,
+ id="polygon_contains_point",
+ ),
+ # Point does not contain anything
+ pytest.param(
+ "POINT (0.25 0.25)",
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ False,
+ id="point_not_contains_polygon",
+ ),
+ # Point definitely not in polygon (outside the covering)
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "POINT (-30 -30)",
+ False,
+ id="polygon_not_contains_distant_point",
+ ),
+ # Point definitely not in polygon (probably inside the covering)
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "POINT (1.01 1.01)",
+ False,
+ id="polygon_not_contains_close_point",
+ ),
+ # Polygon does not contain boundary point
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "POINT (0 0)",
+ False,
+ id="polygon_not_contains_boundary_point",
+ ),
+ # Polygon contains interior sub-polygon
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "POLYGON ((0.1 0.1, 0.5 0.1, 0.1 0.5, 0.1 0.1))",
+ True,
+ id="polygon_contains_polygon",
+ ),
+ # Interior polygon does not contain Polygon
+ pytest.param(
+ "POLYGON ((0.1 0.1, 0.5 0.1, 0.1 0.5, 0.1 0.1))",
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ False,
+ id="polygon_does_not_contain_polygon",
+ ),
+ # Polygon contains interior linestring
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "LINESTRING (0.25 0.25, 0.5 0.5)",
+ True,
+ id="polygon_contains_interior_linestring",
+ ),
+ # Polygon does not contain linestring that crosses boundary
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "LINESTRING (0.25 0.25, 3 3)",
+ False,
+ id="polygon_not_contains_crossing_linestring",
+ ),
+ # Polygon does not contain exterior linestring
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "LINESTRING (3 3, 4 4)",
+ False,
+ id="polygon_not_contains_exterior_linestring",
+ ),
+ # Linestring does not contain point
+ pytest.param(
+ "LINESTRING (0 0, 1 0)",
+ "POINT (10 10)",
+ False,
+ id="linestring_not_contains_point",
+ ),
+ # Linestring does not contain linestring
+ pytest.param(
+ "LINESTRING (0 0, 2 0)",
+ "LINESTRING (10 10, 11 10)",
+ False,
+ id="linestring_not_contains_linestring",
+ ),
+ # Polygon does not contain overlapping polygon
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "POLYGON ((0.1 0.1, 3 0.1, 0.1 3, 0.1 0.1))",
+ False,
+ id="polygon_not_contains_overlapping_polygon",
+ ),
+ # Polygon does not contain distant polygon
+ pytest.param(
+ "POLYGON ((0 0, 1 0, 0 1, 0 0))",
+ "POLYGON ((30 30, 31 30, 30 31, 30 30))",
+ False,
+ id="polygon_not_contains_distant_polygon",
+ ),
+ # GEOMETRYCOLLECTION tests
+ pytest.param(
+ "GEOMETRYCOLLECTION (POINT (30 30), LINESTRING (40 40, 41 40),
POLYGON ((0 0, 2 0, 0 2, 0 0)))",
+ "POINT (0.25 0.25)",
+ True,
+ id="gc_contains_point",
+ ),
+ pytest.param(
+ "GEOMETRYCOLLECTION (POINT (30 30), POLYGON ((0 0, 2 0, 0 2, 0
0)))",
+ "LINESTRING (0.25 0.25, 0.5 0.5)",
+ True,
+ id="gc_contains_linestring",
+ ),
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "GEOMETRYCOLLECTION (POINT (0.25 0.25), LINESTRING (0.3 0.3, 0.4
0.4))",
+ True,
+ id="polygon_contains_gc",
+ ),
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "GEOMETRYCOLLECTION (POINT (30 30), LINESTRING (0.3 0.3, 0.4
0.4))",
+ False,
+ id="polygon_not_contains_gc_point_outside",
+ ),
+ pytest.param(
+ "GEOMETRYCOLLECTION (POINT (30 30), POLYGON ((0 0, 2 0, 0 2, 0
0)))",
+ "POLYGON ((0.1 0.1, 3 0.1, 0.1 3, 0.1 0.1))",
+ False,
+ id="gc_not_contains_crossing_polygon",
+ ),
+ ],
+)
+def test_st_contains(eng, geom1, geom2, expected):
+ eng = eng.create_or_skip()
+ eng.assert_query_result(
+ f"SELECT ST_Contains({geog_or_null(geom1)}, {geog_or_null(geom2)})",
+ expected,
+ )
+
+
[email protected]("eng", [SedonaDB, BigQuery])
[email protected](
+ ("geom1", "geom2", "expected"),
+ [
+ # Within is the reverse of Contains
+ # Point within polygon
+ pytest.param(
+ "POINT (0.25 0.25)",
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ True,
+ id="point_within_polygon",
+ ),
+ # Point not within polygon (outside)
+ pytest.param(
+ "POINT (-1 -1)",
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ False,
+ id="point_not_within_polygon",
+ ),
+ # Polygon is not within point
+ pytest.param(
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ "POINT (0.25 0.25)",
+ False,
+ id="polygon_not_within_point",
+ ),
+ # Null handling
+ pytest.param(None, "POLYGON ((0 0, 2 0, 0 2, 0 0))", None,
id="null_within"),
+ pytest.param("POINT (0 0)", None, None, id="within_null"),
+ # Interior linestring within polygon
+ pytest.param(
+ "LINESTRING (0.25 0.25, 0.5 0.5)",
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ True,
+ id="linestring_within_polygon",
+ ),
+ # Crossing linestring not within polygon
+ pytest.param(
+ "LINESTRING (0.25 0.25, 3 3)",
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ False,
+ id="crossing_linestring_not_within_polygon",
+ ),
+ # Interior polygon within larger polygon
+ pytest.param(
+ "POLYGON ((0.1 0.1, 0.5 0.1, 0.1 0.5, 0.1 0.1))",
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ True,
+ id="polygon_within_polygon",
+ ),
+ # Boundary point not within polygon
+ pytest.param(
+ "POINT (0 0)",
+ "POLYGON ((0 0, 2 0, 0 2, 0 0))",
+ False,
+ id="boundary_point_not_within_polygon",
+ ),
+ ],
+)
+def test_st_within(eng, geom1, geom2, expected):
+ eng = eng.create_or_skip()
+ eng.assert_query_result(
+ f"SELECT ST_Within({geog_or_null(geom1)}, {geog_or_null(geom2)})",
+ expected,
+ )
+
+
[email protected]("eng", [SedonaDB, BigQuery])
[email protected](
+ ("geom1", "geom2", "expected"),
+ [
+ # Nulls
+ pytest.param(None, "POINT EMPTY", None, id="null_equals"),
+ pytest.param("POINT EMPTY", None, None, id="equals_null"),
+ pytest.param(None, None, None, id="null_equals_null"),
+ # Empties
+ pytest.param("POINT (0 0)", "POINT EMPTY", False, id="equals_empty"),
+ pytest.param("POINT EMPTY", "POINT (0 0)", False, id="empty_equals"),
+ pytest.param(
+ "POINT EMPTY", "POINT EMPTY", True,
id="empty_point_equals_empty_point"
+ ),
+ pytest.param(
+ "POINT EMPTY",
+ "LINESTRING EMPTY",
+ True,
+ id="empty_point_equals_empty_linestring",
+ ),
+ # Fast path for identical values
+ pytest.param(
Review Comment:
I added one for wraparound for the predicates (the equals one had to go in
the bug overflow bin to fix in s2geography)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]