pub use crate::parser::time::Time;
use geo_types::{Geometry, LineString, MultiLineString, Point, Rect};
#[cfg(feature = "use-serde")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))]
#[derive(Default)]
pub enum GpxVersion {
#[default]
Unknown,
Gpx10,
Gpx11,
}
impl std::fmt::Display for GpxVersion {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
#[derive(Clone, Default, Debug, PartialEq)]
#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))]
pub struct Gpx {
pub version: GpxVersion,
pub creator: Option<String>,
pub metadata: Option<Metadata>,
pub waypoints: Vec<Waypoint>,
pub tracks: Vec<Track>,
pub routes: Vec<Route>,
}
#[derive(Clone, Default, Debug, PartialEq)]
#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))]
pub struct GpxCopyright {
pub author: Option<String>,
pub year: Option<i32>,
pub license: Option<String>,
}
#[derive(Clone, Default, Debug, PartialEq)]
#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))]
pub struct Metadata {
pub name: Option<String>,
pub description: Option<String>,
pub author: Option<Person>,
pub links: Vec<Link>,
pub time: Option<Time>,
pub keywords: Option<String>,
pub copyright: Option<GpxCopyright>,
pub bounds: Option<Rect<f64>>,
}
#[derive(Clone, Default, Debug, PartialEq)]
#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))]
pub struct Route {
pub name: Option<String>,
pub comment: Option<String>,
pub description: Option<String>,
pub source: Option<String>,
pub links: Vec<Link>,
pub number: Option<u32>,
pub type_: Option<String>,
pub points: Vec<Waypoint>,
}
impl Route {
pub fn linestring(&self) -> LineString<f64> {
self.points.iter().map(|wpt| wpt.point()).collect()
}
pub fn new() -> Route {
Default::default()
}
}
impl From<Route> for Geometry<f64> {
fn from(route: Route) -> Geometry<f64> {
Geometry::LineString(route.linestring())
}
}
#[derive(Clone, Default, Debug, PartialEq)]
#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))]
pub struct Track {
pub name: Option<String>,
pub comment: Option<String>,
pub description: Option<String>,
pub source: Option<String>,
pub links: Vec<Link>,
pub type_: Option<String>,
pub number: Option<u32>,
pub segments: Vec<TrackSegment>,
}
impl Track {
pub fn multilinestring(&self) -> MultiLineString<f64> {
self.segments.iter().map(|seg| seg.linestring()).collect()
}
pub fn new() -> Track {
Default::default()
}
}
impl From<Track> for Geometry<f64> {
fn from(track: Track) -> Geometry<f64> {
Geometry::MultiLineString(track.multilinestring())
}
}
#[derive(Clone, Default, Debug, PartialEq)]
#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))]
pub struct TrackSegment {
pub points: Vec<Waypoint>,
}
impl TrackSegment {
pub fn linestring(&self) -> LineString<f64> {
self.points.iter().map(|wpt| wpt.point()).collect()
}
pub fn new() -> TrackSegment {
Default::default()
}
}
impl From<TrackSegment> for Geometry<f64> {
fn from(track_segment: TrackSegment) -> Geometry<f64> {
Geometry::LineString(track_segment.linestring())
}
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))]
struct GpxPoint(Point<f64>);
impl Default for GpxPoint {
fn default() -> GpxPoint {
GpxPoint(Point::new(0 as f64, 0 as f64))
}
}
#[derive(Clone, Default, Debug, PartialEq)]
#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))]
pub struct Waypoint {
point: GpxPoint,
pub elevation: Option<f64>,
pub speed: Option<f64>,
pub time: Option<Time>,
pub name: Option<String>,
pub comment: Option<String>,
pub description: Option<String>,
pub source: Option<String>,
pub links: Vec<Link>,
pub symbol: Option<String>,
pub type_: Option<String>,
pub geoidheight: Option<f64>,
pub fix: Option<Fix>,
pub sat: Option<u64>,
pub hdop: Option<f64>,
pub vdop: Option<f64>,
pub pdop: Option<f64>,
#[deprecated = "Prior to gpx 0.9.0 version crate used incorrect field to parse and emit DGPS age. Use `dgps_age` instead. See https://github.com/georust/gpx/issues/21"]
pub age: Option<f64>,
pub dgps_age: Option<f64>,
pub dgpsid: Option<u16>,
}
impl Waypoint {
pub fn point(&self) -> Point<f64> {
self.point.0 }
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())
}
}
#[derive(Clone, Default, Debug, PartialEq)]
#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))]
pub struct Person {
pub name: Option<String>,
pub email: Option<String>,
pub link: Option<Link>,
}
#[derive(Clone, Default, Debug, PartialEq)]
#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))]
pub struct Link {
pub href: String,
pub text: Option<String>,
pub type_: Option<String>,
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))]
pub enum Fix {
None,
TwoDimensional,
ThreeDimensional,
DGPS,
PPS,
Other(String),
}