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
}
}
#[derive(Clone, Default, Debug)]
pub struct Gpx {
pub version: GpxVersion,
pub metadata: Option<Metadata>,
pub waypoints: Vec<Waypoint>,
pub tracks: Vec<Track>,
pub route: Route,
}
#[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<Rect<f64>>,
}
#[derive(Clone, Default, Debug)]
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)]
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 From<Track> for Geometry<f64> {
fn from(track: Track) -> Geometry<f64> {
Geometry::MultiLineString(track.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 From<TrackSegment> for Geometry<f64> {
fn from(track_segment: TrackSegment) -> Geometry<f64> {
Geometry::LineString(track_segment.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 From<Waypoint> for Geometry<f64> {
fn from(waypoint: Waypoint) -> Geometry<f64> {
Geometry::Point(waypoint.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),
}