Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/target
/Cargo.lock
.idea/*
**/*.rs.bk
rusty-tags.emacs
63 changes: 62 additions & 1 deletion src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::types::{
Geometry, Icon, IconStyle, Kml, KmlDocument, KmlVersion, LabelStyle, LineString, LineStyle,
LinearRing, Link, LinkTypeIcon, ListStyle, Location, MultiGeometry, Orientation, Pair,
Placemark, Point, PolyStyle, Polygon, RefreshMode, ResourceMap, Scale, SchemaData,
SimpleArrayData, SimpleData, Style, StyleMap, Units, Vec2, ViewRefreshMode,
SimpleArrayData, SimpleData, Style, StyleMap, Track, Units, Vec2, ViewRefreshMode,
};

/// Main struct for reading KML documents
Expand Down Expand Up @@ -416,6 +416,29 @@ where
Ok(MultiGeometry { geometries, attrs })
}

fn read_track(&mut self, attrs: HashMap<String, String>) -> Result<Track<T>, Error> {
let mut coords: Vec<Coord<T>> = Vec::new();
loop {
let mut e = self.reader.read_event_into(&mut self.buf)?;
match e {
Event::Start(ref e) => {
if e.local_name().as_ref() == b"coord" {
let mut coord = coords_from_str(&self.read_str()?.replace(" ", ","))?;
coords.push(coord.remove(0));
}
}
Event::End(ref mut e) => {
if e.local_name().as_ref() == b"Track" {
break;
}
}
Event::Comment(_) => {}
_ => {}
}
}
Ok(Track { coords, attrs })
}

fn read_placemark(&mut self, attrs: HashMap<String, String>) -> Result<Placemark<T>, Error> {
let mut name: Option<String> = None;
let mut description: Option<String> = None;
Expand Down Expand Up @@ -444,6 +467,9 @@ where
geometry =
Some(Geometry::MultiGeometry(self.read_multi_geometry(attrs)?))
}
b"Track" => {
geometry = Some(Geometry::LineString(self.read_track(attrs)?.into()));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be able to reference .coords here instead of the Track itself since LineString already has a From implementation for Vec<Coord<T>>

}
_ => {
let start = e.to_owned();
let start_attrs = Self::read_attrs(start.attributes());
Expand Down Expand Up @@ -1890,4 +1916,39 @@ mod tests {
})
);
}

#[test]
fn test_parse_kml_document_with_track() {
let kml_str = r#"
<Placemark>
<name>Test Placemark</name>
<gx:Track>
<gx:coord>139.74128033333332 35.60417266666666 30.099999999999998</gx:coord>
<gx:coord>139.73755016666667 35.59745483333334 36.0</gx:coord>
<gx:coord>139.73755018666667 35.58974548333334 40.0</gx:coord>
</gx:Track>
</Placemark>
"#;
let kml: Kml = kml_str.parse().unwrap();
assert_eq!(
kml,
Kml::Placemark(Placemark {
name: Some("Test Placemark".to_string()),
geometry: Some(Geometry::LineString(
vec![
Coord::new(
139.74128033333332,
35.60417266666666,
Some(30.099999999999998)
),
Coord::new(139.73755016666667, 35.59745483333334, Some(36.0)),
Coord::new(139.73755018666667, 35.58974548333334, Some(40.0))
]
.into()
)),
children: vec![],
..Default::default()
})
);
}
}
13 changes: 13 additions & 0 deletions src/types/line_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::HashMap;

use crate::types::altitude_mode::AltitudeMode;
use crate::types::coord::{Coord, CoordType};
use crate::types::Track;

/// `kml:LineString`, [10.7](http://docs.opengeospatial.org/is/12-007r2/12-007r2.html#488) in the
/// KML specification
Expand All @@ -25,3 +26,15 @@ where
}
}
}

impl<T> From<Track<T>> for LineString<T>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a use case for converting to kml::LineString over geo_types::Geometry::LineString? It seems like that's what we'd be looking for and is easier to work with

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pjsier i'm looking into this now, and in my case I have KML files where Track is inside Placemark, similar to the example I made for unit test
But the Placemark uses kml::Geometry internally, so that's why I've initially added a conversion to kml::LineString

Yeah, I'm going to add the general conversion to geo_types::Geometry::LineString but not sure how to deal with the use case above, pls advise..

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks for flagging that! I think that also highlights a gap we can clean up here.

Right now we're only parsing child elements in geo_types::Geometry<T>::try_from for Kml::Folder, Kml::KmlDocument, and Kml::Document. Kml::Placemark is only checking geometry like you mentioned here.

I'll open a quick PR in a bit, and then you should just be able to add a branch to the segment in TryFrom that adds this specific element

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@agent10 on second though, I looked into this more, and it would be a much more substantial change. To keep this simple and avoid mixing the items up too much I added a comment below, and then in a separate PR I might need to rethink how Placemark is implemented

where
T: CoordType + Default,
{
fn from(track: Track<T>) -> Self {
LineString {
coords: track.coords,
..Default::default()
}
}
}
2 changes: 2 additions & 0 deletions src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod orientation;
mod point;
mod polygon;
mod scale;
mod track;
mod vec2;

pub use line_string::LineString;
Expand All @@ -23,6 +24,7 @@ pub use orientation::Orientation;
pub use point::Point;
pub use polygon::Polygon;
pub use scale::Scale;
pub use track::Track;
pub use vec2::{Units, Vec2};

mod element;
Expand Down
24 changes: 24 additions & 0 deletions src/types/track.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use std::collections::HashMap;

use crate::types::coord::CoordType;
use crate::types::Coord;

/// `kml:Track`, [10.15](https://docs.ogc.org/is/12-007r2/12-007r2.html#611) in the KML
/// specification
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Track<T: CoordType = f64> {
pub coords: Vec<Coord<T>>,
pub attrs: HashMap<String, String>,
}

impl<T> Track<T>
where
T: CoordType + Default,
{
pub fn new(coords: Vec<Coord<T>>) -> Self {
Track {
coords,
..Default::default()
}
}
}
Loading