Last active
November 26, 2015 07:20
-
-
Save eeeeeta/f2ae3545fde094d04f32 to your computer and use it in GitHub Desktop.
first bit of rust code - parses GPX trackpoints. probably quite buggy :P
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate xml; | |
extern crate chrono; | |
use std::fs::File; | |
use std::io::BufReader; | |
use std::vec::Vec; | |
use chrono::*; | |
use xml::reader::{EventReader, XmlEvent}; | |
fn indent(size: usize) -> String { | |
const INDENT: &'static str = " "; | |
(0..size).map(|_| INDENT) | |
.fold(String::with_capacity(size*INDENT.len()), |r, s| r + s) | |
} | |
struct GPXPoint { | |
lat: f64, | |
lon: f64, | |
elev: Option<f64>, | |
time: Option<DateTime<FixedOffset>> | |
} | |
fn main() { | |
let file = File::open("file.xml").unwrap(); | |
let file = BufReader::new(file); | |
let parser = EventReader::new(file); | |
let mut depth = 0; | |
let mut pts: Vec<GPXPoint> = Vec::new(); | |
let mut elem: Option<GPXPoint> = None; | |
let mut curname: String = "blarg.".to_string(); | |
for e in parser { | |
match e { | |
Ok(XmlEvent::StartElement { name, attributes, .. }) => { | |
println!("{} START {}", indent(depth), name); | |
curname = name.local_name; | |
if curname.contains("trkpt") { | |
println!("trkpt found"); | |
let mut pt = GPXPoint { lat: 0.0f64, lon: 0.0f64, elev: None, time: None }; | |
for attr in attributes { | |
println!("{} ATTR: {} = {}", indent(depth + 1), attr.name, attr.value); | |
match attr.name.local_name.as_ref() { | |
"lat" => { | |
pt.lat = attr.value.parse().unwrap(); | |
println!("lat: {}", pt.lat); | |
} | |
"lon" => { | |
pt.lon = attr.value.parse().unwrap(); | |
println!("lon: {}", pt.lon); | |
} | |
_ => { | |
println!("warn: unknown attr {}", attr.name); | |
} | |
} | |
} | |
elem = Some(pt); | |
} | |
depth += 1; | |
} | |
Ok(XmlEvent::EndElement { name }) => { | |
depth -= 1; | |
if name.local_name.contains("trkpt") { | |
match elem { | |
Some(pt) => { | |
println!("pushing trkpt: {}, {}, {:?}, {:?}", pt.lat, pt.lon, pt.elev, pt.time); | |
pts.push(pt); | |
}, | |
None => {} | |
} | |
elem = None; | |
} | |
println!("{}-{}", indent(depth), name); | |
} | |
Ok(XmlEvent::CData(string)) => { | |
println!("{} CDATA: {}", indent(depth), string); | |
} | |
Ok(XmlEvent::Characters(string)) => { | |
println!("{} {} CHARS: {}", indent(depth), curname, string); | |
match elem { | |
Some(ref mut pt) => { | |
match curname.as_ref() { | |
"ele" => { | |
println!("ele: {}", string); | |
pt.elev = Some(string.parse().unwrap()); | |
}, | |
"time" => { | |
println!("time: {}", string); | |
let result = DateTime::parse_from_rfc3339(&string); | |
match result { | |
Ok(time) => { | |
println!("time parsed\n"); | |
pt.time = Some(time); | |
} | |
Err(e) => { | |
panic!("error parsing time: {}", e); | |
} | |
} | |
}, | |
_ => {} | |
} | |
} | |
None => {} | |
} | |
} | |
Err(e) => { | |
println!("Error: {}", e); | |
break; | |
} | |
_ => {} | |
} | |
} | |
println!("====\nPARSE COMPLETE\n====\n\n"); | |
for pt in &pts { | |
println!("Trackpoint: [{}, {}] at elev {:?} at time {:?}", pt.lat, pt.lon, pt.elev, pt.time); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment