jiayuasu opened a new issue, #2973: URL: https://github.com/apache/sedona/issues/2973
Follow-up to the Box2D epic (#2877). Adds the planar 3D bounding box type — PostGIS's `box3d` — as a first-class Sedona SQL type. ## Scope (Phase 1) Mirrors Box2D's Phase 1 shape, scoped down to JVM + SQL surface only. Cross-language bindings, GeoParquet covering interop, casts, join-planner integration, and the `ST_3DDWithin` distance predicate are all explicit follow-ups. ### Foundation - [ ] `Box3D` value class in `common/.../geometryObjects/Box3D.java` (6 doubles: `xmin, ymin, zmin, xmax, ymax, zmax`, mirroring PostGIS's storage order). - [ ] `Box3DUDT` (struct of 6 non-nullable doubles) + UDT registration. ### SQL surface - [ ] `ST_Box3D(geom)` — planar 3D bounding box of a Geometry. Geometries without Z get `zmin = zmax = 0` (matches PostGIS). - [ ] `ST_3DMakeBox(p1: PointZ, p2: PointZ)` — two-corner constructor. - [ ] `ST_3DExtent(geom)` aggregate — Box3D over a column. - [ ] `ST_ZMin(box3d)` / `ST_ZMax(box3d)` overloads (the existing Geometry-input forms stay). - [ ] `ST_XMin/YMin/XMax/YMax(box3d)` overloads. - [ ] `ST_3DBoxIntersects(box3d, box3d)` — closed-interval intersection on all three axes. Matches PostGIS `&&&` (the 3D overlap operator). - [ ] `ST_3DBoxContains(box3d, box3d)` — closed-interval containment on all three axes. Matches PostGIS `~~` on box3d. - [ ] `ST_AsText(box3d)` — `BOX3D(xmin ymin zmin, xmax ymax zmax)` text form. ### Semantics - Closed-interval (edge/face/corner-touching counts as intersecting and contained), matching Box2D's contract. - NULL for absent (no in-band empty marker). - `xmin > xmax` / `ymin > ymax` / `zmin > zmax` are explicitly rejected by predicates with `IllegalArgumentException` — same contract as Box2D. (We're not carrying forward Box2D's "reserved for future antimeridian wraparound" exception for Z; Z doesn't wraparound.) - XY-only geometries → `zmin = zmax = 0` (PostGIS-compatible default). ## Out of scope (separate follow-ups) - Python `Box3DType` bindings and Scala DataFrame helpers. - Flink bindings (scalar + aggregate + `Box3DTypeSerializer`). - R bindings. - Documentation (analogous to the Box2D docs PR #2966). - GeoParquet covering-bbox recognition for Box3D columns (the spec allows optional `zmin/zmax`). - Casts between Box2D and Box3D (lossy in either direction). - Spatial join planner integration for `ST_3DBoxIntersects` / `ST_3DBoxContains`. - Filter pushdown for Box3D predicates against Box3D columns. - `ST_3DDWithin` distance predicate (needs squared-Euclidean over 3D). ## Why Phase 1 is narrow Box2D's Phase 1 was wide because GeoParquet covering bbox interop drove concrete demand. Box3D today has no equivalent pull (see the original epic's "when a concrete user appears" note). This issue ships the foundation and the SQL surface so it's available, and defers everything that benefits from a real workload to inform design. ## Coordination Match Box2D's design choices wherever possible — the type-system contract (separate UDT, six-double struct), the closed-interval semantics, and the inverted-bounds throw should all feel parallel. -- 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]
