Skip to content

Commit bb526b7

Browse files
authored
feat(rust/sedona-expr): Implement SpatialFilter for overlaps and crosses for geoparquet pruning (#217)
1 parent df21442 commit bb526b7

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

python/sedonadb/tests/io/test_parquet.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ def test_read_geoparquet_prune_points(geoarrow_data, name, predicate):
164164
"contains",
165165
"covers",
166166
"touches",
167+
"crosses",
168+
"overlaps",
167169
],
168170
)
169171
def test_read_geoparquet_prune_polygons(sedona_testing, predicate):
@@ -176,9 +178,16 @@ def test_read_geoparquet_prune_polygons(sedona_testing, predicate):
176178
# A point inside of a polygon for contains / covers
177179
wkt_filter = "POINT (33.60 -5.54)"
178180

181+
# Use a wkt_filter that will lead to non-empty results
179182
if predicate == "touches":
180183
# A point on the boundary of a polygon
181184
wkt_filter = "POINT (33.90371119710453 -0.9500000000000001)"
185+
elif predicate == "overlaps":
186+
# A polygon that intersects the polygon but neither contain each other
187+
wkt_filter = "POLYGON ((33 -1.9, 33.00 0, 34 0, 34 -1.9, 33 -1.9))"
188+
elif predicate == "crosses":
189+
# A linestring that intersects the polygon but is not contained by it
190+
wkt_filter = "LINESTRING (33 -1.9, 33.00 0, 34 0, 34 -1.9, 33 -1.9)"
182191

183192
poly_filter = shapely.from_wkt(wkt_filter)
184193

rust/sedona-expr/src/spatial_filter.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl SpatialFilter {
177177
let args = parse_args(raw_args);
178178
let fun_name = scalar_fun.fun().name();
179179
match fun_name {
180-
"st_intersects" | "st_equals" | "st_touches" => {
180+
"st_intersects" | "st_equals" | "st_touches" | "st_crosses" | "st_overlaps" => {
181181
if args.len() != 2 {
182182
return sedona_internal_err!("unexpected argument count in filter evaluation");
183183
}
@@ -576,7 +576,14 @@ mod test {
576576

577577
#[rstest]
578578
fn predicate_from_expr_commutative_functions(
579-
#[values("st_intersects", "st_equals", "st_touches")] func_name: &str,
579+
#[values(
580+
"st_intersects",
581+
"st_equals",
582+
"st_touches",
583+
"st_crosses",
584+
"st_overlaps"
585+
)]
586+
func_name: &str,
580587
) {
581588
let column: Arc<dyn PhysicalExpr> = Arc::new(Column::new("geometry", 0));
582589
let storage_field = WKB_GEOMETRY.to_storage_field("", true).unwrap();
@@ -804,7 +811,9 @@ mod test {
804811
"st_covers",
805812
"st_within",
806813
"st_covered_by",
807-
"st_coveredby"
814+
"st_coveredby",
815+
"st_crosses",
816+
"st_overlaps"
808817
)]
809818
func_name: &str,
810819
) {
@@ -846,7 +855,9 @@ mod test {
846855
"st_covers",
847856
"st_within",
848857
"st_covered_by",
849-
"st_coveredby"
858+
"st_coveredby",
859+
"st_crosses",
860+
"st_overlaps"
850861
)]
851862
func_name: &str,
852863
) {

0 commit comments

Comments
 (0)