Skip to content

Commit

Permalink
Merge pull request georust#498 from metasim/fix/496
Browse files Browse the repository at this point in the history
Created `enum AxisMappingStrategy` for `OSRAxisMappingStrategy` ordinals.
  • Loading branch information
metasim committed Dec 19, 2023
2 parents 4d035df + 1cbce65 commit ba43369
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 46 deletions.
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Unreleased

- Created `enum AxisMappingStrategy` for `OSRAxisMappingStrategy` ordinals.
- **Breaking**: `SpatialRef::{set_}axis_mapping_strategy` use `AxisMappingStrategy` instead of `gdal_sys::OSRAxisMappingStrategy::Type`.

- <https://github.com/georust/gdal/pull/498>

- Defers the gdal_i.lib missing message until after the pkg-config check and outputs pkg-config metadata in case of a static build.

- <https://github.com/georust/gdal/pull/492>
Expand Down
2 changes: 1 addition & 1 deletion src/raster/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ impl TryFrom<u32> for GdalDataType {
"Complex data types are not available".into(),
)),
o => Err(GdalError::BadArgument(format!(
"unknown GDALDataType ordinal' {o}'"
"unknown GDALDataType ordinal `{o}`"
))),
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/spatial_ref/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ mod transform_opts;
/// See [`OGRAxisOrientation`](https://gdal.org/api/ogr_srs_api.html#_CPPv418OGRAxisOrientation).
pub type AxisOrientationType = gdal_sys::OGRAxisOrientation::Type;

pub use srs::SpatialRef;
pub use srs::{AxisMappingStrategy, SpatialRef};
pub use transform::CoordTransform;
pub use transform_opts::CoordTransformOptions;
80 changes: 64 additions & 16 deletions src/spatial_ref/srs.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::utils::{_last_null_pointer_err, _string};
use gdal_sys::{self, OGRErr};
use gdal_sys::{self, OGRErr, OSRAxisMappingStrategy};
use std::ffi::{CStr, CString};
use std::ptr::{self};
use std::str::FromStr;
Expand Down Expand Up @@ -403,21 +403,30 @@ impl SpatialRef {
}

#[cfg(major_ge_3)]
pub fn set_axis_mapping_strategy(&mut self, strategy: gdal_sys::OSRAxisMappingStrategy::Type) {
/// Set the data axis to CRS axis mapping strategy.
///
/// # Notes
///
/// Starting with GDAL 3.5, the `OSR_DEFAULT_AXIS_MAPPING_STRATEGY` configuration option can be
/// set to `"TRADITIONAL_GIS_ORDER"` or `"AUTHORITY_COMPLIANT"` (the later being the default
/// value when the option is not set) to control the value of the data axis to CRS axis
/// mapping strategy when a [`SpatialRef`] object is created.
/// Calling [`set_axis_mapping_strategy`][Self::set_axis_mapping_strategy] will override this default value.
///
/// See: [`OSRSetAxisMappingStrategy`](https://gdal.org/api/ogrspatialref.html#_CPPv4N19OGRSpatialReference22SetAxisMappingStrategyE22OSRAxisMappingStrategy)
pub fn set_axis_mapping_strategy(&mut self, strategy: AxisMappingStrategy) {
unsafe {
gdal_sys::OSRSetAxisMappingStrategy(self.0, strategy);
gdal_sys::OSRSetAxisMappingStrategy(self.0, strategy.gdal_ordinal());
}
}

#[cfg(major_ge_3)]
#[deprecated(note = "use `axis_mapping_strategy` instead")]
pub fn get_axis_mapping_strategy(&self) -> gdal_sys::OSRAxisMappingStrategy::Type {
self.axis_mapping_strategy()
}

#[cfg(major_ge_3)]
pub fn axis_mapping_strategy(&self) -> gdal_sys::OSRAxisMappingStrategy::Type {
unsafe { gdal_sys::OSRGetAxisMappingStrategy(self.0) }
/// Return the data axis to CRS axis mapping strategy.
///
/// See: [`OSRGetAxisMappingStrategy`](https://gdal.org/api/ogrspatialref.html#_CPPv4NK19OGRSpatialReference22GetAxisMappingStrategyEv)
pub fn axis_mapping_strategy(&self) -> AxisMappingStrategy {
let id = unsafe { gdal_sys::OSRGetAxisMappingStrategy(self.0) };
id.try_into().expect("valid enumeration ordinal from GDAL")
}

#[cfg(major_ge_3)]
Expand Down Expand Up @@ -606,6 +615,47 @@ pub struct AreaOfUse {
pub name: String,
}

#[cfg(major_ge_3)]
/// Data axis to CRS axis mapping strategy.
///
/// See: [`OSRGetAxisMappingStrategy`](https://gdal.org/api/ogrspatialref.html#_CPPv4NK19OGRSpatialReference22GetAxisMappingStrategyEv)
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
#[repr(u32)]
pub enum AxisMappingStrategy {
/// For geographic CRS with lat/long order, the data will still be long/lat ordered.
/// Similarly for a projected CRS with northing/easting order, the data will still
/// be easting/northing ordered.
TraditionalGisOrder = OSRAxisMappingStrategy::OAMS_TRADITIONAL_GIS_ORDER,
/// The data axis will be identical to the CRS axis.
AuthorityCompliant = OSRAxisMappingStrategy::OAMS_AUTHORITY_COMPLIANT,
/// The data axes are custom-defined via [`gdal_sys::OSRSetDataAxisToSRSAxisMapping`].
Custom = OSRAxisMappingStrategy::OAMS_CUSTOM,
}

impl AxisMappingStrategy {
#[inline]
pub(crate) fn gdal_ordinal(&self) -> OSRAxisMappingStrategy::Type {
*self as OSRAxisMappingStrategy::Type
}
}

impl TryFrom<u32> for AxisMappingStrategy {
type Error = GdalError;

fn try_from(value: u32) -> std::result::Result<Self, Self::Error> {
use OSRAxisMappingStrategy::*;

match value {
OAMS_TRADITIONAL_GIS_ORDER => Ok(Self::TraditionalGisOrder),
OAMS_AUTHORITY_COMPLIANT => Ok(Self::AuthorityCompliant),
OAMS_CUSTOM => Ok(Self::Custom),
o => Err(GdalError::BadArgument(format!(
"unknown OSRAxisMappingStrategy ordinal '{o}'"
))),
}
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -751,14 +801,12 @@ mod tests {
let mut spatial_ref = SpatialRef::from_epsg(4326).unwrap();
assert_eq!(
spatial_ref.axis_mapping_strategy(),
gdal_sys::OSRAxisMappingStrategy::OAMS_AUTHORITY_COMPLIANT
);
spatial_ref.set_axis_mapping_strategy(
gdal_sys::OSRAxisMappingStrategy::OAMS_TRADITIONAL_GIS_ORDER,
AxisMappingStrategy::AuthorityCompliant
);
spatial_ref.set_axis_mapping_strategy(AxisMappingStrategy::TraditionalGisOrder);
assert_eq!(
spatial_ref.axis_mapping_strategy(),
gdal_sys::OSRAxisMappingStrategy::OAMS_TRADITIONAL_GIS_ORDER
AxisMappingStrategy::TraditionalGisOrder
);
}

Expand Down
37 changes: 10 additions & 27 deletions src/spatial_ref/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ impl CoordTransform {
mod tests {
use super::*;
use crate::assert_almost_eq;
use crate::spatial_ref::srs::AxisMappingStrategy;
use crate::vector::Geometry;

#[cfg(all(major_ge_3, minor_ge_4))]
Expand Down Expand Up @@ -244,9 +245,7 @@ mod tests {
assert_almost_eq(out_bounds[3], bounds[3]);

// force EPSG:4326 into x,y order to match source SpatialRef
spatial_ref2.set_axis_mapping_strategy(
gdal_sys::OSRAxisMappingStrategy::OAMS_TRADITIONAL_GIS_ORDER,
);
spatial_ref2.set_axis_mapping_strategy(AxisMappingStrategy::TraditionalGisOrder);
transform = CoordTransform::new(&spatial_ref1, &spatial_ref2).unwrap();
out_bounds = transform.transform_bounds(&bounds, 21).unwrap();
assert_almost_eq(out_bounds[0], bounds[0]);
Expand Down Expand Up @@ -277,13 +276,9 @@ mod tests {

// TODO: handle axis order in tests
#[cfg(major_ge_3)]
spatial_ref1.set_axis_mapping_strategy(
gdal_sys::OSRAxisMappingStrategy::OAMS_TRADITIONAL_GIS_ORDER,
);
spatial_ref1.set_axis_mapping_strategy(AxisMappingStrategy::TraditionalGisOrder);
#[cfg(major_ge_3)]
spatial_ref2.set_axis_mapping_strategy(
gdal_sys::OSRAxisMappingStrategy::OAMS_TRADITIONAL_GIS_ORDER,
);
spatial_ref2.set_axis_mapping_strategy(AxisMappingStrategy::TraditionalGisOrder);

let transform = CoordTransform::new(&spatial_ref1, &spatial_ref2).unwrap();
let mut xs = [23.43, 23.50];
Expand Down Expand Up @@ -314,13 +309,9 @@ mod tests {

// TODO: handle axis order in tests
#[cfg(major_ge_3)]
spatial_ref1.set_axis_mapping_strategy(
gdal_sys::OSRAxisMappingStrategy::OAMS_TRADITIONAL_GIS_ORDER,
);
spatial_ref1.set_axis_mapping_strategy(AxisMappingStrategy::TraditionalGisOrder);
#[cfg(major_ge_3)]
spatial_ref2.set_axis_mapping_strategy(
gdal_sys::OSRAxisMappingStrategy::OAMS_TRADITIONAL_GIS_ORDER,
);
spatial_ref2.set_axis_mapping_strategy(AxisMappingStrategy::TraditionalGisOrder);

let htransform = CoordTransform::new(&spatial_ref2, &spatial_ref1).unwrap();
geom.transform_inplace(&htransform).unwrap();
Expand All @@ -334,13 +325,9 @@ mod tests {

// TODO: handle axis order in tests
#[cfg(major_ge_3)]
wgs84.set_axis_mapping_strategy(
gdal_sys::OSRAxisMappingStrategy::OAMS_TRADITIONAL_GIS_ORDER,
);
wgs84.set_axis_mapping_strategy(AxisMappingStrategy::TraditionalGisOrder);
#[cfg(major_ge_3)]
dhd_2.set_axis_mapping_strategy(
gdal_sys::OSRAxisMappingStrategy::OAMS_TRADITIONAL_GIS_ORDER,
);
dhd_2.set_axis_mapping_strategy(AxisMappingStrategy::TraditionalGisOrder);

let mut x = [1979105.06, 0.0];
let mut y = [5694052.67, 0.0];
Expand All @@ -355,13 +342,9 @@ mod tests {

// TODO: handle axis order in tests
#[cfg(major_ge_3)]
wgs84.set_axis_mapping_strategy(
gdal_sys::OSRAxisMappingStrategy::OAMS_TRADITIONAL_GIS_ORDER,
);
wgs84.set_axis_mapping_strategy(AxisMappingStrategy::TraditionalGisOrder);
#[cfg(major_ge_3)]
webmercator.set_axis_mapping_strategy(
gdal_sys::OSRAxisMappingStrategy::OAMS_TRADITIONAL_GIS_ORDER,
);
webmercator.set_axis_mapping_strategy(AxisMappingStrategy::TraditionalGisOrder);

let mut x = [1000000.0];
let mut y = [1000000.0];
Expand Down
3 changes: 2 additions & 1 deletion src/vector/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,7 @@ impl Dataset {
mod tests {
use super::{LayerCaps::*, *};
use crate::options::DatasetOptions;
use crate::spatial_ref::AxisMappingStrategy;
use crate::test_utils::{fixture, open_gpkg_for_update, SuppressGDALErrorLog, TempFixture};
use crate::vector::feature::FeatureIterator;
use crate::{assert_almost_eq, Dataset, DriverManager, GdalOpenFlags};
Expand Down Expand Up @@ -1470,7 +1471,7 @@ mod tests {
let geom_field = layer.defn().geom_fields().next().unwrap();
let mut spatial_ref2 = SpatialRef::from_epsg(4326).unwrap();
#[cfg(major_ge_3)]
spatial_ref2.set_axis_mapping_strategy(0);
spatial_ref2.set_axis_mapping_strategy(AxisMappingStrategy::TraditionalGisOrder);

assert_eq!(geom_field.spatial_ref().unwrap(), spatial_ref2);
}
Expand Down

0 comments on commit ba43369

Please sign in to comment.