logo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! Contains the `Locations` enum and its associated traits. It is used to
//! specify a series of location in the form of latitude & longitude pairs,
//! or as an Encoded Polyline.

#[cfg(feature = "geo")]
mod geo_conversions;

// -----------------------------------------------------------------------------

use crate::latlng::LatLng;
use rust_decimal_macros::dec;

// -----------------------------------------------------------------------------
//
/// Defines the
/// [location(s)](https://developers.google.com/maps/documentation/elevation/intro#Locations)
/// on the earth from which to return elevation data.
///
/// This parameter takes either a single location as a latitude/longitude
/// pair, multiple latitude/longitude pairs, or an encoded polyline.

#[cfg(not(feature = "geo"))]
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)]
pub enum Locations {
    /// A single or multiple
    /// [latitude/longitude](https://developers.google.com/maps/documentation/elevation/intro#Locations)
    /// pairs.
    LatLngs(Vec<LatLng>),
    /// An [encoded
    /// polyline](https://developers.google.com/maps/documentation/utilities/polylinealgorithm).
    Polyline(String),
} // enum

// -----------------------------------------------------------------------------

#[cfg(not(feature = "geo"))]
impl std::convert::From<&Locations> for String {
    /// Converts a `Locations` enum to a `String` that contains
    /// [locations](https://developers.google.com/maps/documentation/elevation/intro#Locations).
    fn from(locations: &Locations) -> Self {

        match locations {

            Locations::LatLngs(latlngs) =>
                latlngs.iter()
                    .map(String::from)
                    .collect::<Vec<String>>()
                    .join("|"),

            Locations::Polyline(polyline) =>
                format!("enc:{}", polyline),

        } // match
    } // fn
} // impl

// -----------------------------------------------------------------------------
//
/// Defines the
/// [location(s)](https://developers.google.com/maps/documentation/elevation/intro#Locations)
/// on the earth from which to return elevation data.
///
/// This parameter takes either a single location as a latitude/longitude
/// pair, multiple latitude/longitude pairs, or an encoded polyline.

#[cfg(feature = "geo")]
#[derive(Clone, Debug, PartialEq)]
pub enum Locations {
    /// A single or multiple
    /// [latitude/longitude](https://developers.google.com/maps/documentation/elevation/intro#Locations)
    /// pairs.
    LatLngs(Vec<LatLng>),
    /// An [encoded
    /// polyline](https://developers.google.com/maps/documentation/utilities/polylinealgorithm).
    Polyline(String),
    /// This variant supports the
    /// [geo](https://crates.io/crates/geo) crate's
    /// [Line](https://docs.rs/geo/latest/geo/geometry/struct.Line.html) type.
    Line(geo_types::geometry::Line),
    /// This variant supports the
    /// [geo](https://crates.io/crates/geo) crate's
    /// [LineString](https://docs.rs/geo/latest/geo/geometry/struct.LineString.html) type.
    LineString(geo_types::geometry::LineString),
} // enum

// -----------------------------------------------------------------------------

#[cfg(feature = "geo")]
impl std::convert::From<&Locations> for String {
    /// Converts a `Locations` enum to a `String` that contains
    /// [locations](https://developers.google.com/maps/documentation/elevation/intro#Locations).
    fn from(locations: &Locations) -> Self {

        match locations {

            Locations::LatLngs(latlngs) =>
                latlngs.iter()
                    .map(String::from)
                    .collect::<Vec<String>>()
                    .join("|"),

            Locations::Polyline(polyline) =>
                format!("enc:{}", polyline),

            Locations::Line(line) =>
                format!(
                    "{start_lat},{start_lng}|{end_lat},{end_lng}",
                    start_lat=line.start.y,
                    start_lng=line.start.x,
                    end_lat=line.start.y,
                    end_lng=line.start.x,
                ), // format!

            Locations::LineString(line_string) =>
                line_string
                    .coords()
                    .map(|coordinate|
                        format!("{lat},{lng}", lat=coordinate.y, lng=coordinate.x)
                    ) // map
                    .collect::<Vec<String>>()
                    .join("|"),

        } // match

    } // fn
} // impl

// -----------------------------------------------------------------------------

impl std::default::Default for Locations {
    /// Returns a reasonable default variant for the `Locations` enum type.
    fn default() -> Self {
        Locations::LatLngs(vec![LatLng::try_from_dec(dec!(0.0), dec!(0.0)).unwrap()])
    } // fn
} // impl