-
Notifications
You must be signed in to change notification settings - Fork 96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH: Add CoordTransform::transform_bounds() #272
Changes from 3 commits
6e9c7c7
9061914
1ce3a5e
79464ab
3ed0474
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
use crate::utils::{_last_cpl_err, _last_null_pointer_err, _string}; | ||
use gdal_sys::{self, CPLErr, OGRCoordinateTransformationH, OGRErr, OGRSpatialReferenceH}; | ||
use libc::{c_char, c_int}; | ||
use libc::{c_char, c_double, c_int}; | ||
use std::ffi::{CStr, CString}; | ||
use std::ptr::{self, null_mut}; | ||
use std::str::FromStr; | ||
|
@@ -33,6 +33,61 @@ impl CoordTransform { | |
}) | ||
} | ||
|
||
/// Transform bounding box, densifying the edges to account for nonlinear | ||
/// transformations. | ||
/// | ||
/// # Arguments | ||
/// * bounds - array of [axis0_min, axis1_min, axis0_max, axis1_min], | ||
/// interpreted in the axis order of the source SpatialRef, | ||
/// typically [xmin, ymin, xmax, ymax] | ||
/// * densify_pts - number of points per edge (recommended: 21) | ||
/// | ||
/// # Returns | ||
/// Some([f64; 4]) with bounds in axis order of target SpatialRef | ||
/// None if there is an error. | ||
#[cfg(all(major_ge_3, minor_ge_4))] | ||
pub fn transform_bounds(&self, bounds: &[f64; 4], densify_pts: i32) -> Result<([f64; 4])> { | ||
let mut out_xmin: f64 = 0.; | ||
let mut out_ymin: f64 = 0.; | ||
let mut out_xmax: f64 = 0.; | ||
let mut out_ymax: f64 = 0.; | ||
|
||
let ret_val = unsafe { | ||
gdal_sys::OCTTransformBounds( | ||
self.inner, | ||
bounds[0] as c_double, | ||
bounds[1] as c_double, | ||
bounds[2] as c_double, | ||
bounds[3] as c_double, | ||
&mut out_xmin as *mut c_double, | ||
&mut out_ymin as *mut c_double, | ||
&mut out_xmax as *mut c_double, | ||
&mut out_ymax as *mut c_double, | ||
densify_pts as c_int, | ||
) == 1 | ||
}; | ||
|
||
if ret_val { | ||
Ok([out_xmin, out_ymin, out_xmax, out_ymax]) | ||
} else { | ||
let err = _last_cpl_err(CPLErr::CE_Failure); | ||
let msg = if let GdalError::CplError { msg, .. } = err { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was copy-pasted from I'd probably also want to invert the logic a little bit so that only the error case is in the conditional and have a bare
But didn't do so in this PR out of consistency. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Right, it's fine either way. |
||
if msg.trim().is_empty() { | ||
None | ||
} else { | ||
Some(msg) | ||
} | ||
} else { | ||
return Err(err); | ||
}; | ||
Err(GdalError::InvalidCoordinateRange { | ||
from: self.from.clone(), | ||
to: self.to.clone(), | ||
msg, | ||
}) | ||
} | ||
} | ||
|
||
/// Transform coordinates in place. | ||
/// | ||
/// # Arguments | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll have to move the
use
here to avoid the warning. Or you might be able to skip the casts, like intransform_coords
, I'm not sure.