This is an automated email from the ASF dual-hosted git repository.
jiayu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/sedona-db.git
The following commit(s) were added to refs/heads/main by this push:
new bb526b7 feat(rust/sedona-expr): Implement SpatialFilter for overlaps
and crosses for geoparquet pruning (#217)
bb526b7 is described below
commit bb526b7f71460e2cc79ae15baa3975a821f469ba
Author: Peter Nguyen <[email protected]>
AuthorDate: Mon Oct 13 01:05:58 2025 -0700
feat(rust/sedona-expr): Implement SpatialFilter for overlaps and crosses
for geoparquet pruning (#217)
---
python/sedonadb/tests/io/test_parquet.py | 9 +++++++++
rust/sedona-expr/src/spatial_filter.rs | 19 +++++++++++++++----
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/python/sedonadb/tests/io/test_parquet.py
b/python/sedonadb/tests/io/test_parquet.py
index 73afbfa..8520163 100644
--- a/python/sedonadb/tests/io/test_parquet.py
+++ b/python/sedonadb/tests/io/test_parquet.py
@@ -164,6 +164,8 @@ def test_read_geoparquet_prune_points(geoarrow_data, name,
predicate):
"contains",
"covers",
"touches",
+ "crosses",
+ "overlaps",
],
)
def test_read_geoparquet_prune_polygons(sedona_testing, predicate):
@@ -176,9 +178,16 @@ def test_read_geoparquet_prune_polygons(sedona_testing,
predicate):
# A point inside of a polygon for contains / covers
wkt_filter = "POINT (33.60 -5.54)"
+ # Use a wkt_filter that will lead to non-empty results
if predicate == "touches":
# A point on the boundary of a polygon
wkt_filter = "POINT (33.90371119710453 -0.9500000000000001)"
+ elif predicate == "overlaps":
+ # A polygon that intersects the polygon but neither contain each other
+ wkt_filter = "POLYGON ((33 -1.9, 33.00 0, 34 0, 34 -1.9, 33 -1.9))"
+ elif predicate == "crosses":
+ # A linestring that intersects the polygon but is not contained by it
+ wkt_filter = "LINESTRING (33 -1.9, 33.00 0, 34 0, 34 -1.9, 33 -1.9)"
poly_filter = shapely.from_wkt(wkt_filter)
diff --git a/rust/sedona-expr/src/spatial_filter.rs
b/rust/sedona-expr/src/spatial_filter.rs
index da4baf1..f4d9781 100644
--- a/rust/sedona-expr/src/spatial_filter.rs
+++ b/rust/sedona-expr/src/spatial_filter.rs
@@ -177,7 +177,7 @@ impl SpatialFilter {
let args = parse_args(raw_args);
let fun_name = scalar_fun.fun().name();
match fun_name {
- "st_intersects" | "st_equals" | "st_touches" => {
+ "st_intersects" | "st_equals" | "st_touches" | "st_crosses" |
"st_overlaps" => {
if args.len() != 2 {
return sedona_internal_err!("unexpected argument count in
filter evaluation");
}
@@ -576,7 +576,14 @@ mod test {
#[rstest]
fn predicate_from_expr_commutative_functions(
- #[values("st_intersects", "st_equals", "st_touches")] func_name: &str,
+ #[values(
+ "st_intersects",
+ "st_equals",
+ "st_touches",
+ "st_crosses",
+ "st_overlaps"
+ )]
+ func_name: &str,
) {
let column: Arc<dyn PhysicalExpr> = Arc::new(Column::new("geometry",
0));
let storage_field = WKB_GEOMETRY.to_storage_field("", true).unwrap();
@@ -804,7 +811,9 @@ mod test {
"st_covers",
"st_within",
"st_covered_by",
- "st_coveredby"
+ "st_coveredby",
+ "st_crosses",
+ "st_overlaps"
)]
func_name: &str,
) {
@@ -846,7 +855,9 @@ mod test {
"st_covers",
"st_within",
"st_covered_by",
- "st_coveredby"
+ "st_coveredby",
+ "st_crosses",
+ "st_overlaps"
)]
func_name: &str,
) {