use geo::{Bbox, LineString, MultiLineString, Point};
use geo::{Geometry, ToGeo};
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
}
}
#[derive(Clone, Default, Debug)]
pub struct Gpx {
pub version: GpxVersion,
pub metadata: Option<Metadata>,
pub waypoints: Vec<Waypoint>,
pub tracks: Vec<Track>,
}
#[derive(Clone, Default, Debug)]
pub struct Metadata {
pub name: Option<String>,
pub description: Option<String>,
pub author: Option<Person>,
pub links: Vec<Link>,
pub time: Option<DateTime<Utc>>,
pub keywords: Option<String>,
pub bounds: Option<Bbox<f64>>,
}
#[derive(Clone, Default, Debug)]
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 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 ToGeo<f64> for Track {
fn to_geo(&self) -> Geometry<f64> {
Geometry::MultiLineString(self.multilinestring())
}
}
#[derive(Clone, Default, Debug)]
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 ToGeo<f64> for TrackSegment {
fn to_geo(&self) -> Geometry<f64> {
Geometry::LineString(self.linestring())
}
}
#[derive(Clone, Debug)]
struct GpxPoint(Point<f64>);
impl Default for GpxPoint {
fn default() -> GpxPoint {
GpxPoint(Point::new(0 as f64, 0 as f64))
}
}
#[derive(Clone, Default, Debug)]
pub struct Waypoint {
point: GpxPoint,
pub elevation: Option<f64>,
pub speed: Option<f64>,
pub time: Option<DateTime<Utc>>,
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>,
pub 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 ToGeo<f64> for Waypoint {
fn to_geo(&self) -> Geometry<f64> {
Geometry::Point(self.point())
}
}
#[derive(Clone, Default, Debug)]
pub struct Person {
pub name: Option<String>,
pub email: Option<String>,
pub link: Option<Link>,
}
#[derive(Clone, Default, Debug)]
pub struct Link {
pub href: String,
pub text: Option<String>,
pub _type: Option<String>,
}
#[derive(Clone, Debug, PartialEq)]
pub enum Fix {
None,
TwoDimensional,
ThreeDimensional,
DGPS,
PPS,
Other(String),
}