Skip to content

Commit 47f7bee

Browse files
feat(rust/sedona-proj): Let ST_Transform() handle 3D coordinates (#544)
1 parent c38dbc6 commit 47f7bee

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

c/sedona-proj/src/proj.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,17 @@ impl Proj {
371371
Ok((xyzt_out.0, xyzt_out.1))
372372
}
373373

374+
/// Transform XYZ coordinates
375+
pub(crate) fn transform_xyz(
376+
&mut self,
377+
point: (f64, f64, f64),
378+
) -> Result<(f64, f64, f64), SedonaProjError> {
379+
// Filling extra dimensions with zeroes is what PostGIS does
380+
let xyzt = (point.0, point.1, point.2, 0.0);
381+
let xyzt_out = self.transform(xyzt)?;
382+
Ok((xyzt_out.0, xyzt_out.1, xyzt_out.2))
383+
}
384+
374385
/// Transform XYZT coordinates
375386
pub(crate) fn transform(
376387
&mut self,

c/sedona-proj/src/transform.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,18 @@ impl CrsTransform for ProjTransform {
228228
coord.1 = res.1;
229229
Ok(())
230230
}
231+
232+
fn transform_coord_3d(&self, coord: &mut (f64, f64, f64)) -> Result<(), SedonaGeometryError> {
233+
let res = self.proj.borrow_mut().transform_xyz(*coord).map_err(|e| {
234+
SedonaGeometryError::Invalid(format!(
235+
"PROJ coordinate transformation failed with error: {e}"
236+
))
237+
})?;
238+
coord.0 = res.0;
239+
coord.1 = res.1;
240+
coord.2 = res.2;
241+
Ok(())
242+
}
231243
}
232244

233245
#[cfg(test)]

python/sedonadb/tests/functions/test_transforms.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ def test_st_transform(eng):
3131
)
3232

3333

34+
@pytest.mark.parametrize("eng", [SedonaDB, PostGIS])
35+
def test_st_transform_3d(eng):
36+
eng = eng.create_or_skip()
37+
eng.assert_query_result(
38+
"SELECT ST_Transform(ST_GeomFromText('POINT Z (1 1 1)'), 'EPSG:4979', 'EPSG:4978')",
39+
"POINT Z (6376201.805927448 111297.016517882 110568.792276973)",
40+
wkt_precision=9,
41+
)
42+
43+
3444
@pytest.mark.parametrize("eng", [SedonaDB, PostGIS])
3545
@pytest.mark.parametrize(
3646
("geom", "srid", "expected_srid"),

0 commit comments

Comments
 (0)