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 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
//! generic types for GPX use geo_types::{Geometry, LineString, MultiLineString, Point, Rect}; use chrono::prelude::Utc; use chrono::DateTime; #[derive(Clone, Copy, Debug, PartialEq)] pub enum GpxVersion { Unknown, Gpx10, Gpx11, } impl Default for GpxVersion { fn default() -> GpxVersion { GpxVersion::Unknown } } /// Gpx is the root element in the XML file. #[derive(Clone, Default, Debug)] pub struct Gpx { /// Version of the Gpx file. pub version: GpxVersion, /// Metadata about the file. pub metadata: Option<Metadata>, /// A list of waypoints. pub waypoints: Vec<Waypoint>, /// A list of tracks. pub tracks: Vec<Track>, } /// Metadata is information about the GPX file, author, and copyright restrictions. /// /// Providing rich, meaningful information about your GPX files allows others to /// search for and use your GPS data. #[derive(Clone, Default, Debug)] pub struct Metadata { /// The name of the GPX file. pub name: Option<String>, /// A description of the contents of the GPX file. pub description: Option<String>, /// The person or organization who created the GPX file. pub author: Option<Person>, /// URLs associated with the location described in the file. pub links: Vec<Link>, /// The creation date of the file. pub time: Option<DateTime<Utc>>, /// Keywords associated with the file. Search engines or databases can use /// this information to classify the data. pub keywords: Option<String>, /*copyright: GpxCopyrightType,*/ /// Bounds for the tracks in the GPX. pub bounds: Option<Rect<f64>>, /*extensions: GpxExtensionsType,*/ } /// Track represents an ordered list of points describing a path. #[derive(Clone, Default, Debug)] pub struct Track { /// GPS name of track. pub name: Option<String>, /// GPS comment for track. pub comment: Option<String>, /// User description of track. pub description: Option<String>, /// Source of data. Included to give user some idea of reliability /// and accuracy of data. pub source: Option<String>, /// Links to external information about the track. pub links: Vec<Link>, /// Type (classification) of track. pub _type: Option<String>, /// A Track Segment holds a list of Track Points which are logically /// connected in order. To represent a single GPS track where GPS reception /// was lost, or the GPS receiver was turned off, start a new Track Segment /// for each continuous span of track data. pub segments: Vec<TrackSegment>, /* pub number: u8,*/ /* extensions */ /* trkSeg */ } impl Track { /// Gives the multi-linestring that this track represents, which is multiple /// linestrings. pub fn multilinestring(&self) -> MultiLineString<f64> { self.segments.iter().map(|seg| seg.linestring()).collect() } /// Creates a new Track with default values. /// /// ``` /// use gpx::{Track, TrackSegment}; /// /// let mut track: Track = Track::new(); /// /// let segment = TrackSegment::new(); /// track.segments.push(segment); pub fn new() -> Track { Default::default() } } impl From<Track> for Geometry<f64> { fn from(track: Track) -> Geometry<f64> { Geometry::MultiLineString(track.multilinestring()) } } /// TrackSegment represents a list of track points. /// /// This TrackSegment holds a list of Track Points which are logically /// connected in order. To represent a single GPS track where GPS reception /// was lost, or the GPS receiver was turned off, start a new Track Segment /// for each continuous span of track data. #[derive(Clone, Default, Debug)] pub struct TrackSegment { /// Each Waypoint holds the coordinates, elevation, timestamp, and metadata /// for a single point in a track. pub points: Vec<Waypoint>, /* extensions */ } impl TrackSegment { /// Gives the linestring of the segment's points, the sequence of points that /// comprises the track segment. pub fn linestring(&self) -> LineString<f64> { self.points.iter().map(|wpt| wpt.point()).collect() } /// Creates a new TrackSegment with default values. /// /// ``` /// extern crate gpx; /// extern crate geo_types; /// /// use gpx::{TrackSegment, Waypoint}; /// use geo_types::Point; /// /// fn main() { /// let mut trkseg: TrackSegment = TrackSegment::new(); /// /// let point = Waypoint::new(Point::new(-121.97, 37.24)); /// trkseg.points.push(point); /// } pub fn new() -> TrackSegment { Default::default() } } impl From<TrackSegment> for Geometry<f64> { fn from(track_segment: TrackSegment) -> Geometry<f64> { Geometry::LineString(track_segment.linestring()) } } // A Version of geo_types::Point that has the Default trait implemented, which // allows us to initialise the GpxPoint with default values compactly // in the Waypoint::new function below #[derive(Clone, Debug)] struct GpxPoint(Point<f64>); impl Default for GpxPoint { fn default() -> GpxPoint { GpxPoint(Point::new(0 as f64, 0 as f64)) } } /// Waypoint represents a waypoint, point of interest, or named feature on a /// map. #[derive(Clone, Default, Debug)] pub struct Waypoint { /// The geographical point. point: GpxPoint, /// Elevation (in meters) of the point. pub elevation: Option<f64>, /// Speed (in meters per second) (only in GPX 1.0) pub speed: Option<f64>, /// Creation/modification timestamp for element. Date and time in are in /// Univeral Coordinated Time (UTC), not local time! Conforms to ISO 8601 /// specification for date/time representation. Fractional seconds are /// allowed for millisecond timing in tracklogs. pub time: Option<DateTime<Utc>>, /// The GPS name of the waypoint. This field will be transferred to and /// from the GPS. GPX does not place restrictions on the length of this /// field or the characters contained in it. It is up to the receiving /// application to validate the field before sending it to the GPS. pub name: Option<String>, /// GPS waypoint comment. Sent to GPS as comment. pub comment: Option<String>, /// A text description of the element. Holds additional information about /// the element intended for the user, not the GPS. pub description: Option<String>, /// Source of data. Included to give user some idea of reliability and /// accuracy of data. "Garmin eTrex", "USGS quad Boston North", e.g. pub source: Option<String>, /// Links to additional information about the waypoint. pub links: Vec<Link>, /// Text of GPS symbol name. For interchange with other programs, use the /// exact spelling of the symbol as displayed on the GPS. If the GPS /// abbreviates words, spell them out. pub symbol: Option<String>, /// Type (classification) of the waypoint. pub _type: Option<String>, // <magvar> degreesType </magvar> [0..1] ? /// Height of geoid in meters above WGS 84. This correspond to the sea level. pub geoidheight: Option<f64>, /// Type of GPS fix. `none` means GPS had no fix. To signify "the fix info /// is unknown", leave out `fix` entirely. Value comes from the list /// `{'none'|'2d'|'3d'|'dgps'|'pps'}`, where `pps` means that the military /// signal was used. pub fix: Option<Fix>, /// Number of satellites used to calculate the GPX fix. pub sat: Option<u64>, /// Horizontal dilution of precision. pub hdop: Option<f64>, /// Vertical dilution of precision. pub vdop: Option<f64>, /// Positional dilution of precision. pub pdop: Option<f64>, /// Number of seconds since last DGPS update, from the <ageofgpsdata> element. pub age: Option<f64>, /// ID of DGPS station used in differential correction, in the range [0, 1023]. pub dgpsid: Option<u16>, // <extensions> extensionsType </extensions> [0..1] ? } impl Waypoint { /// Gives the geographical point of the waypoint. /// /// ``` /// extern crate geo_types; /// extern crate gpx; /// /// use gpx::Waypoint; /// use geo_types::Point; /// /// fn main() { /// // Kind of useless, but it shows the point. /// let wpt = Waypoint::new(Point::new(-121.97, 37.24)); /// let point = wpt.point(); /// /// println!("waypoint latitude: {}, longitude: {}", point.lat(), point.lng()); /// } /// ``` pub fn point(&self) -> Point<f64> { self.point.0 //.0 to extract the geo_types::Point from the tuple struct GpxPoint } /// Creates a new Waypoint from a given geographical point. /// /// ``` /// extern crate geo_types; /// extern crate gpx; /// /// use gpx::Waypoint; /// use geo_types::Point; /// /// fn main() { /// let point = Point::new(-121.97, 37.24); /// /// let mut wpt = Waypoint::new(point); /// wpt.elevation = Some(553.21); /// } /// ``` pub fn new(point: Point<f64>) -> Waypoint { Waypoint { point: GpxPoint(point), ..Default::default() } } } impl From<Waypoint> for Geometry<f64> { fn from(waypoint: Waypoint) -> Geometry<f64> { Geometry::Point(waypoint.point()) } } /// Person represents a person or organization. #[derive(Clone, Default, Debug)] pub struct Person { /// Name of person or organization. pub name: Option<String>, /// Email address. pub email: Option<String>, /// Link to Web site or other external information about person. pub link: Option<Link>, } /// Link represents a link to an external resource. /// /// An external resource could be a web page, digital photo, /// video clip, etc., with additional information. #[derive(Clone, Default, Debug)] pub struct Link { /// URL of hyperlink. pub href: String, /// Text of hyperlink. pub text: Option<String>, /// Mime type of content (image/jpeg) pub _type: Option<String>, } /// Type of the GPS fix. #[derive(Clone, Debug, PartialEq)] pub enum Fix { /// The GPS had no fix. To signify "the fix info is unknown", leave out the Fix entirely. None, /// 2D fix gives only longitude and latitude. It needs a minimum of 3 satellites. TwoDimensional, /// 3D fix gives longitude, latitude and altitude. It needs a minimum of 4 satellites. ThreeDimensional, /// Differential Global Positioning System. DGPS, /// Military signal. PPS, /// Other values that are not in the specification. Other(String), }