yepzon-locationer/src/gpx.rs

87 lines
2.4 KiB
Rust

use super::{Config, GenericError, LocationModel, TagModel};
use geo_types::Point;
use gpx::{Gpx, GpxVersion, Metadata, Person, Route, Track, TrackSegment, Waypoint};
use std::fs::File;
use thingy_lib::chrono::offset::Utc as UTC_ZONE;
use thingy_lib::chrono::{DateTime, NaiveDateTime, Utc};
pub fn generate_gpx(
tag: &TagModel,
locations: &Vec<(NaiveDateTime, LocationModel)>,
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(())
}
fn get_waypoint(point: &(NaiveDateTime, LocationModel)) -> Result<Waypoint, GenericError> {
let (naive_time, location) = point;
let now = Utc::now();
let time: DateTime<UTC_ZONE> = DateTime::from_utc(*naive_time, now.offset().clone());
if let (Some(lat), Some(lon)) = (location.lat, location.lon) {
let mut waypoint = Waypoint::new(Point::new(lon, lat));
waypoint.time = Some(time);
waypoint.source = location.loc_type.as_ref().cloned();
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,
})
}