mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-06 22:04:06 +00:00
handle self closing elements
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<gpx version="1.1" creator="gpx.studio" xmlns="http://www.topografix.com/GPX/1/1"
|
||||||
|
xmlns:ext="https://example.com/ext/0.1">
|
||||||
|
<metadata>
|
||||||
|
<name>self closing points</name>
|
||||||
|
<desc>Points without children are self-closing elements.</desc>
|
||||||
|
<extensions>
|
||||||
|
<ext:version>2.0</ext:version>
|
||||||
|
<ext:paths/>
|
||||||
|
</extensions>
|
||||||
|
</metadata>
|
||||||
|
<wpt lat="50.0" lon="4.0"/>
|
||||||
|
<wpt lat="50.1" lon="4.1"><name>with children</name></wpt>
|
||||||
|
<wpt lat="50.2" lon="4.2"/>
|
||||||
|
<trk>
|
||||||
|
<name>track</name>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.00" lon="4.00"/>
|
||||||
|
<trkpt lat="50.01" lon="4.01"><ele>12.5</ele></trkpt>
|
||||||
|
<trkpt lat="50.02" lon="4.02"/>
|
||||||
|
</trkseg>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="51.00" lon="5.00"/>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -114,6 +114,30 @@ pub fn parse(data: &[u8], categories: &mut TrackpointCategories) -> Result<File,
|
|||||||
e if e.ends_with("width") => stack.push(GPXElement::Width),
|
e if e.ends_with("width") => stack.push(GPXElement::Width),
|
||||||
_ => (),
|
_ => (),
|
||||||
},
|
},
|
||||||
|
// Self-closing points (`<trkpt lat=".." lon=".."/>`), which have no children
|
||||||
|
Ok(Event::Empty(e)) => match e.name().as_ref() {
|
||||||
|
"trkpt" => {
|
||||||
|
if let Some(GPXElement::Segment(trkseg)) = stack.last_mut() {
|
||||||
|
trkpt_chunk.trkpt.push(Trackpoint {
|
||||||
|
coordinates: parse_coordinates(e.attributes()),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
if trkpt_chunk.is_full() {
|
||||||
|
trkseg.push(std::mem::take(&mut trkpt_chunk));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"wpt" => {
|
||||||
|
wpt_chunk.wpt.push(Waypoint {
|
||||||
|
coordinates: parse_coordinates(e.attributes()),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
if wpt_chunk.is_full() {
|
||||||
|
gpx.wpt.push(Rc::new(std::mem::take(&mut wpt_chunk)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
Ok(Event::End(e)) => match e.name().as_ref() {
|
Ok(Event::End(e)) => match e.name().as_ref() {
|
||||||
"gpx" => {
|
"gpx" => {
|
||||||
if !wpt_chunk.wpt.is_empty() {
|
if !wpt_chunk.wpt.is_empty() {
|
||||||
@@ -363,6 +387,30 @@ mod tests {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_self_closing_points() {
|
||||||
|
let gpx = parse_data("self_closing_points");
|
||||||
|
|
||||||
|
assert_eq!(gpx.info.name, "self closing points");
|
||||||
|
let wpt: Vec<_> = gpx.wpt.iter().flat_map(|chunk| &chunk.wpt).collect();
|
||||||
|
assert_eq!(wpt.len(), 3);
|
||||||
|
assert_eq!(wpt[0].coordinates.lat, 50.0);
|
||||||
|
assert_eq!(wpt[0].name, None);
|
||||||
|
assert_eq!(wpt[1].name.as_deref(), Some("with children"));
|
||||||
|
assert_eq!(wpt[2].coordinates.lng, 4.2);
|
||||||
|
|
||||||
|
assert_eq!(gpx.trk.len(), 1);
|
||||||
|
let trk = &gpx.trk[0];
|
||||||
|
assert_eq!(trk.trkseg.len(), 2);
|
||||||
|
let seg = &trk.trkseg[0];
|
||||||
|
assert_eq!(seg.len(), 3);
|
||||||
|
assert_eq!(seg[0].coordinates.lat, 50.0);
|
||||||
|
assert_eq!(seg[0].ele, 0.0);
|
||||||
|
assert_eq!(seg[1].ele, 12.5);
|
||||||
|
assert_eq!(seg[2].coordinates.lng, 4.02);
|
||||||
|
assert_eq!(trk.trkseg[1].len(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_simple() {
|
fn test_parse_simple() {
|
||||||
let gpx = parse_data("simple");
|
let gpx = parse_data("simple");
|
||||||
|
|||||||
Reference in New Issue
Block a user