Skip to content

Commit 435c033

Browse files
bors[bot]rmanoka
andauthored
Merge #216
216: Support 2D in CoordTransform r=rmanoka a=rmanoka - [x] I agree to follow the project's [code of conduct](https://github.com/georust/gdal/blob/master/CODE_OF_CONDUCT.md). - [x] I added an entry to `CHANGES.md` if knowledge of this change could be valuable to users. --- Currently `CoordTransform::transform` accepts three `&mut [f64]` slices (for x, y, and z coordinates). This prevents us from using it for 2D transform (whereas in the C api, we would have passed null ptr for z). This PR supports that by checking if the z slice is empty, and passes null_ptr instead. Also, currently we only check if the x and y slices have the same length. This causes sigsegv when passing incorrect z slice. We've also added a assertion for that. Modified one of the existing tests that didn't use the z coordinate to instead pass an empty slice. Co-authored-by: Rajsekar Manokaran <[email protected]> Co-authored-by: rmanoka <[email protected]>
2 parents 6ad95e7 + 80b8b4d commit 435c033

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

src/spatial_ref/srs.rs

+26-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::utils::{_last_cpl_err, _last_null_pointer_err, _string};
22
use gdal_sys::{self, CPLErr, OGRCoordinateTransformationH, OGRErr, OGRSpatialReferenceH};
33
use libc::{c_char, c_int};
44
use std::ffi::{CStr, CString};
5-
use std::ptr;
5+
use std::ptr::{self, null_mut};
66
use std::str::FromStr;
77

88
use crate::errors::*;
@@ -33,16 +33,39 @@ impl CoordTransform {
3333
})
3434
}
3535

36+
/// Transform coordinates in place.
37+
///
38+
/// # Arguments
39+
/// * x - slice of x coordinates
40+
/// * y - slice of y coordinates (must match x in length)
41+
/// * z - slice of z coordinates, or an empty slice to ignore
3642
pub fn transform_coords(&self, x: &mut [f64], y: &mut [f64], z: &mut [f64]) -> Result<()> {
3743
let nb_coords = x.len();
38-
assert_eq!(nb_coords, y.len());
44+
assert_eq!(
45+
nb_coords,
46+
y.len(),
47+
"transform coordinate slices have different lengths: {} != {}",
48+
nb_coords,
49+
y.len()
50+
);
3951
let ret_val = unsafe {
4052
gdal_sys::OCTTransform(
4153
self.inner,
4254
nb_coords as c_int,
4355
x.as_mut_ptr(),
4456
y.as_mut_ptr(),
45-
z.as_mut_ptr(),
57+
if z.is_empty() {
58+
null_mut()
59+
} else {
60+
assert_eq!(
61+
nb_coords,
62+
z.len(),
63+
"transform coordinate slices have different lengths: {} != {}",
64+
nb_coords,
65+
z.len()
66+
);
67+
z.as_mut_ptr()
68+
},
4669
) == 1
4770
};
4871

src/spatial_ref/tests.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,13 @@ fn transform_coordinates() {
8080
let transform = CoordTransform::new(&spatial_ref1, &spatial_ref2).unwrap();
8181
let mut xs = [23.43, 23.50];
8282
let mut ys = [37.58, 37.70];
83+
let mut zs = [32.0, 20.0];
8384
transform
84-
.transform_coords(&mut xs, &mut ys, &mut [0.0, 0.0])
85+
.transform_coords(&mut xs, &mut ys, &mut zs)
8586
.unwrap();
8687
assert_almost_eq(xs[0], 5509543.1508097);
8788
assert_almost_eq(ys[0], 1716062.1916192223);
89+
assert_almost_eq(zs[0], 32.0);
8890
}
8991

9092
#[test]
@@ -169,10 +171,9 @@ fn failing_transformation() {
169171

170172
let mut x = [1000000.0];
171173
let mut y = [1000000.0];
172-
let mut z = [0.0, 0.0];
173174

174175
let trafo = CoordTransform::new(&wgs84, &webmercator).unwrap();
175-
let r = trafo.transform_coords(&mut x, &mut y, &mut z);
176+
let r = trafo.transform_coords(&mut x, &mut y, &mut []);
176177

177178
assert!(r.is_err());
178179
if let GdalError::InvalidCoordinateRange { .. } = r.unwrap_err() {

0 commit comments

Comments
 (0)