2020-08-24 22:24:26 +02:00
|
|
|
use super::{Config, GenericError, LocationModel, TagModel};
|
|
|
|
use geo_types::Point;
|
|
|
|
use gpx::{Gpx, GpxVersion, Metadata, Person, Route, Track, TrackSegment, Waypoint};
|
|
|
|
use std::fs::File;
|
2020-08-29 01:27:23 +02:00
|
|
|
use thingy_lib::chrono::offset::Utc as UTC_ZONE;
|
|
|
|
use thingy_lib::chrono::{DateTime, NaiveDateTime, Utc};
|
2020-08-24 22:24:26 +02:00
|
|
|
|
|
|
|
pub fn generate_gpx(
|
2020-08-25 20:55:04 +02:00
|
|
|
tag: &TagModel,
|
|
|
|
locations: &Vec<(NaiveDateTime, LocationModel)>,
|
2020-08-24 22:24:26 +02:00
|
|
|
config: &Config,
|
|
|
|
) -> Result<Gpx, GenericError> {
|
|
|
|
let route = Route::default();
|
|
|
|
|
|
|
|
let mut points = Vec::new();
|
|
|
|
|
|
|
|
for location in locations {
|
|
|
|
points.push(get_waypoint(location)?);
|
|
|
|
}
|
|
|
|
|
|
|
|
let segment = TrackSegment { points };
|
|
|
|
|
|
|
|
let track = Track {
|
|
|
|
name: None,
|
|
|
|
comment: None,
|
|
|
|
description: None,
|
|
|
|
source: None,
|
|
|
|
links: Vec::new(),
|
|
|
|
_type: None,
|
|
|
|
segments: vec![segment],
|
|
|
|
};
|
|
|
|
|
|
|
|
let gpx = Gpx {
|
|
|
|
version: GpxVersion::Gpx11,
|
|
|
|
metadata: Some(get_metadata(&tag, config)?),
|
|
|
|
waypoints: Vec::new(),
|
|
|
|
tracks: vec![track],
|
|
|
|
route: route,
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(gpx)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn write_gpx(gpx: &Gpx) -> Result<(), GenericError> {
|
|
|
|
let file = File::create("test.gpx").unwrap();
|
|
|
|
gpx::write(&gpx, file)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-08-25 20:55:04 +02:00
|
|
|
fn get_waypoint(point: &(NaiveDateTime, LocationModel)) -> Result<Waypoint, GenericError> {
|
2020-08-24 22:24:26 +02:00
|
|
|
let (naive_time, location) = point;
|
|
|
|
let now = Utc::now();
|
2020-08-25 20:55:04 +02:00
|
|
|
let time: DateTime<UTC_ZONE> = DateTime::from_utc(*naive_time, now.offset().clone());
|
2020-08-24 22:24:26 +02:00
|
|
|
if let (Some(lat), Some(lon)) = (location.lat, location.lon) {
|
|
|
|
let mut waypoint = Waypoint::new(Point::new(lon, lat));
|
|
|
|
waypoint.time = Some(time);
|
2020-08-25 20:55:04 +02:00
|
|
|
waypoint.source = location.loc_type.as_ref().cloned();
|
2020-08-24 22:24:26 +02:00
|
|
|
Ok(waypoint)
|
|
|
|
} else {
|
|
|
|
Err(GenericError::MessagedError(
|
|
|
|
"No coordinates for a given point".to_owned(),
|
|
|
|
None,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_metadata(tag: &TagModel, config: &Config) -> Result<Metadata, GenericError> {
|
|
|
|
let nick_text = match tag.get_nick(config) {
|
|
|
|
Some(nick) => format!(" - {}", nick),
|
|
|
|
None => String::new(),
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(Metadata {
|
|
|
|
name: Some(format!("{}{}", tag.get_id()?, nick_text)),
|
|
|
|
description: None,
|
|
|
|
author: Some(Person {
|
|
|
|
name: Some("Sofia".to_owned()),
|
|
|
|
email: Some("sofia.talarmo@gmail.com".to_owned()),
|
|
|
|
link: None,
|
|
|
|
}),
|
|
|
|
links: Vec::new(),
|
|
|
|
time: Some(Utc::now()),
|
|
|
|
keywords: None,
|
|
|
|
bounds: None,
|
|
|
|
})
|
|
|
|
}
|