jiayuasu opened a new pull request, #2969: URL: https://github.com/apache/sedona/pull/2969
## Did you read the Contributor Guide? - Yes, I have read the [Contributor Rules](https://sedona.apache.org/latest/community/rule/) and [Contributor Development Guide](https://sedona.apache.org/latest/community/develop/) ## Is this PR related to a ticket? - Yes — follow-up to the Box2D spatial-join work (#2939). That PR explicitly scoped out the distance-join case because `ST_DWithin` only accepted `(Geometry, Geometry, d)` and `(Geography, Geography, d)` overloads; this PR closes that gap. ## What changes were proposed in this PR? Adds a planar `Box2D × Box2D` overload to `ST_DWithin`. Distance joins on Box2D columns are now accepted at analysis and routed through the existing distance-join planning machinery (broadcast-index or partition-based `DistanceJoinExec`), with no new physical operator. ### Scalar implementation `Predicates.dWithin(Box2D, Box2D, double)` in `common`: - Computes the closed-interval Euclidean distance between two AABBs as `sqrt(dx² + dy²)` where `dx = max(0, max(a.xmin - b.xmax, b.xmin - a.xmax))` and similarly for `dy`. Overlapping or edge/corner-touching boxes have distance `0` and therefore match any non-negative radius. - Bails out via the squared-radius comparison if either delta already exceeds the supplied radius (avoids a `sqrt`). - Negative radius never matches (consistent with how JTS `Geometry.isWithinDistance` treats negative distance). - Inverted bounds (`xmin > xmax` or `ymin > ymax`) raise the same `IllegalArgumentException` raised by `ST_BoxIntersects` / `ST_BoxContains`. Inverted-bound values are reserved for a future antimeridian-wraparound semantics; planar predicates have no defined meaning on them. ### Catalyst wiring `ST_DWithin` in `spark/common/.../Predicates.scala`: added a fourth `inferrableFunction3` entry typed `(Box2D, Box2D, Double) => Boolean`. The pre-existing 3-arg geometry entry needed an explicit lambda because there are now two arity-3 Java overloads named `Predicates.dWithin` and Scala can't pick between them through eta-expansion alone. ### Join planner No code change needed. `JoinQueryDetector`'s `ST_DWithin(Seq(left, right, distance))` case already produces a `JoinQueryDetection` with `SpatialPredicate.INTERSECTS` and the per-row distance, and `OptimizableJoinCondition.isOptimizablePredicate` already accepts `ST_DWithin` regardless of operand types. The expansion-then-index pipeline runs through `TraitJoinQueryBase.toExpandedEnvelopeRDD`, which uses the Box2D → polygon dispatch from #2939. Per-pair refine then dispatches back to the new Box2D overload in this PR. ## How was this patch tested? - `PredicatesTest`: new `testDWithinBox2D` (overlap, edge-touching, corner-touching, separation on one axis, Pythagorean separation, negative radius) and `testDWithinBox2DRejectInvertedBounds`. 15/15 pass locally. - `Box2DJoinSuite`: four new tests covering broadcast index join at radius 1.0 and 6.0, non-broadcast `DistanceJoinExec` at radius 6.0, and zero-radius edge-touching. 12/12 pass locally (8 pre-existing + 4 new). - Regression run: `BroadcastIndexJoinSuite` + `SpatialJoinSuite` + `KnnJoinSuite` 254/254 still pass. - `mkdocs build --strict` is clean modulo pre-existing unrelated warnings. ## Did this PR include necessary documentation updates? Yes — new `docs/api/sql/box2d/Box2D-Predicates/ST_DWithin.md` page and a row in the `Box2D-Functions.md` predicates table. -- 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]
