pub trait MapCoords<T, NT> {
    type Output;

    // Required methods
    fn map_coords(
        &self,
        func: impl Fn(Coord<T>) -> Coord<NT> + Copy
    ) -> Self::Output
       where T: CoordNum,
             NT: CoordNum;
    fn try_map_coords<E>(
        &self,
        func: impl Fn(Coord<T>) -> Result<Coord<NT>, E> + Copy
    ) -> Result<Self::Output, E>
       where T: CoordNum,
             NT: CoordNum;
}
Expand description

Map a function over all the coordinates in an object, returning a new one

Required Associated Types§

Required Methods§

source

fn map_coords( &self, func: impl Fn(Coord<T>) -> Coord<NT> + Copy ) -> Self::Output
where T: CoordNum, NT: CoordNum,

Apply a function to all the coordinates in a geometric object, returning a new object.

§Examples
use geo::MapCoords;
use geo::{Coord, Point};
use approx::assert_relative_eq;

let p1 = Point::new(10., 20.);
let p2 = p1.map_coords(|Coord { x, y }| Coord { x: x + 1000., y: y * 2. });

assert_relative_eq!(p2, Point::new(1010., 40.), epsilon = 1e-6);

Note that the input and output numeric types need not match.

For example, consider OpenStreetMap’s coordinate encoding scheme, which, to save space, encodes latitude/longitude as 32bit signed integers from the floating point values to six decimal places (eg. lat/lon * 1000000).


let SCALE_FACTOR: f64 = 1000000.0;
let floating_point_geom: Point<f64> = Point::new(10.15f64, 20.05f64);
let fixed_point_geom: Point<i32> = floating_point_geom.map_coords(|Coord { x, y }| {
    Coord { x: (x * SCALE_FACTOR) as i32, y: (y * SCALE_FACTOR) as i32 }
});

assert_eq!(fixed_point_geom.x(), 10150000);

If you want only to convert between numeric types (i32 -> f64) without further transformation, consider using Convert.

source

fn try_map_coords<E>( &self, func: impl Fn(Coord<T>) -> Result<Coord<NT>, E> + Copy ) -> Result<Self::Output, E>
where T: CoordNum, NT: CoordNum,

Map a fallible function over all the coordinates in a geometry, returning a Result

§Examples
use approx::assert_relative_eq;
use geo::MapCoords;
use geo::{Coord, Point};

let p1 = Point::new(10., 20.);
let p2 = p1
    .try_map_coords(|Coord { x, y }| -> Result<_, std::convert::Infallible> {
        Ok(Coord { x: x + 1000., y: y * 2. })
    }).unwrap();

assert_relative_eq!(p2, Point::new(1010., 40.), epsilon = 1e-6);
§Advanced Example: Geometry coordinate conversion using PROJ
use approx::assert_relative_eq;
// activate the [use-proj] feature in cargo.toml in order to access proj functions
use geo::{Coord, Point};
use geo::map_coords::MapCoords;
use proj::{Coord as ProjCoord, Proj, ProjError};
// GeoJSON uses the WGS 84 coordinate system
let from = "EPSG:4326";
// The NAD83 / California zone 6 (ftUS) coordinate system
let to = "EPSG:2230";
let to_feet = Proj::new_known_crs(&from, &to, None).unwrap();
let transform = |c: Coord<f64>| -> Result<_, ProjError> {
    // proj can accept Point, Coord, Tuple, and array values, returning a Result
    let shifted = to_feet.convert(c)?;
    Ok(shifted)
};
// 👽
let usa_m = Point::new(-115.797615, 37.2647978);
let usa_ft = usa_m.try_map_coords(|coord| transform(coord)).unwrap();
assert_relative_eq!(6693625.67217475, usa_ft.x(), epsilon = 1e-6);
assert_relative_eq!(3497301.5918027186, usa_ft.y(), epsilon = 1e-6);

Object Safety§

This trait is not object safe.

Implementors§

source§

impl<T: CoordNum, NT: CoordNum> MapCoords<T, NT> for Geometry<T>

§

type Output = Geometry<NT>

source§

impl<T: CoordNum, NT: CoordNum> MapCoords<T, NT> for GeometryCollection<T>

source§

impl<T: CoordNum, NT: CoordNum> MapCoords<T, NT> for Line<T>

§

type Output = Line<NT>

source§

impl<T: CoordNum, NT: CoordNum> MapCoords<T, NT> for LineString<T>

§

type Output = LineString<NT>

source§

impl<T: CoordNum, NT: CoordNum> MapCoords<T, NT> for MultiLineString<T>

source§

impl<T: CoordNum, NT: CoordNum> MapCoords<T, NT> for MultiPoint<T>

§

type Output = MultiPoint<NT>

source§

impl<T: CoordNum, NT: CoordNum> MapCoords<T, NT> for MultiPolygon<T>

source§

impl<T: CoordNum, NT: CoordNum> MapCoords<T, NT> for Point<T>

§

type Output = Point<NT>

source§

impl<T: CoordNum, NT: CoordNum> MapCoords<T, NT> for Polygon<T>

§

type Output = Polygon<NT>

source§

impl<T: CoordNum, NT: CoordNum> MapCoords<T, NT> for Rect<T>

§

type Output = Rect<NT>

source§

impl<T: CoordNum, NT: CoordNum> MapCoords<T, NT> for Triangle<T>

§

type Output = Triangle<NT>