From 224c76c6c80e0bf6a3f183a72f396ea5d7b65f0a Mon Sep 17 00:00:00 2001 From: kirillolenev-dm Date: Sun, 21 Dec 2025 23:50:15 +0900 Subject: [PATCH 1/4] Reading and converting gx:Track and gx:coord to Geometry --- src/reader.rs | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/reader.rs b/src/reader.rs index d545ff3..d193071 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -416,6 +416,37 @@ where Ok(MultiGeometry { geometries, attrs }) } + fn read_gx_track_coords( + &mut self, + attrs: HashMap, + ) -> Result, Error> { + let mut geometries: Vec> = Vec::new(); + loop { + let mut e = self.reader.read_event_into(&mut self.buf)?; + match e { + Event::Start(ref e) => { + match e.local_name().as_ref() { + b"coord" => { + geometries.push(Geometry::Point(coords_from_str(&self + .read_str()? + .replace(" ", ","))? + .remove(0).into())); + } + _ => {} + } + } + Event::End(ref mut e) => { + if e.local_name().as_ref() == b"Track" { + break; + } + } + Event::Comment(_) => {} + _ => {}, + } + } + Ok(MultiGeometry { geometries, attrs }) + } + fn read_placemark(&mut self, attrs: HashMap) -> Result, Error> { let mut name: Option = None; let mut description: Option = None; @@ -444,6 +475,9 @@ where geometry = Some(Geometry::MultiGeometry(self.read_multi_geometry(attrs)?)) } + b"Track" => { + geometry = Some(Geometry::MultiGeometry(self.read_gx_track_coords(attrs)?)); + } _ => { let start = e.to_owned(); let start_attrs = Self::read_attrs(start.attributes()); @@ -1890,4 +1924,36 @@ mod tests { }) ); } + + #[test] + fn test_parse_kml_document_default222() { + let kml_str = r#" + + Test Placemark + + 139.74128033333332 35.60417266666666 30.099999999999998 + 139.73755016666667 35.59745483333334 36.0 + + + "#; + let kml: Kml = kml_str.parse().unwrap(); + assert_eq!( + kml, + Kml::Placemark(Placemark { + name: Some("Test Placemark".to_string()), + geometry: Some(Geometry::MultiGeometry(MultiGeometry { + geometries: vec![Geometry::Point(Point { + coord: Coord::new(139.74128033333332, 35.60417266666666, Some(30.099999999999998)), + ..Default::default() + }), Geometry::Point(Point { + coord: Coord::new(139.73755016666667, 35.59745483333334, Some(36.0)), + ..Default::default() + })], + attrs: HashMap::new() + })), + children: vec![], + ..Default::default() + }) + ); + } } From ce12720880eb06bd0333ad8ffb783f83b7c46621 Mon Sep 17 00:00:00 2001 From: kirillolenev-dm Date: Mon, 22 Dec 2025 00:10:15 +0900 Subject: [PATCH 2/4] fix: clippy/fmt --- src/reader.rs | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/reader.rs b/src/reader.rs index d193071..4fbc3fe 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -425,14 +425,12 @@ where let mut e = self.reader.read_event_into(&mut self.buf)?; match e { Event::Start(ref e) => { - match e.local_name().as_ref() { - b"coord" => { - geometries.push(Geometry::Point(coords_from_str(&self - .read_str()? - .replace(" ", ","))? - .remove(0).into())); - } - _ => {} + if e.local_name().as_ref() == b"coord" { + geometries.push(Geometry::Point( + coords_from_str(&self.read_str()?.replace(" ", ","))? + .remove(0) + .into(), + )); } } Event::End(ref mut e) => { @@ -441,7 +439,7 @@ where } } Event::Comment(_) => {} - _ => {}, + _ => {} } } Ok(MultiGeometry { geometries, attrs }) @@ -476,7 +474,8 @@ where Some(Geometry::MultiGeometry(self.read_multi_geometry(attrs)?)) } b"Track" => { - geometry = Some(Geometry::MultiGeometry(self.read_gx_track_coords(attrs)?)); + geometry = + Some(Geometry::MultiGeometry(self.read_gx_track_coords(attrs)?)); } _ => { let start = e.to_owned(); @@ -1942,13 +1941,20 @@ mod tests { Kml::Placemark(Placemark { name: Some("Test Placemark".to_string()), geometry: Some(Geometry::MultiGeometry(MultiGeometry { - geometries: vec![Geometry::Point(Point { - coord: Coord::new(139.74128033333332, 35.60417266666666, Some(30.099999999999998)), - ..Default::default() - }), Geometry::Point(Point { - coord: Coord::new(139.73755016666667, 35.59745483333334, Some(36.0)), - ..Default::default() - })], + geometries: vec![ + Geometry::Point(Point { + coord: Coord::new( + 139.74128033333332, + 35.60417266666666, + Some(30.099999999999998) + ), + ..Default::default() + }), + Geometry::Point(Point { + coord: Coord::new(139.73755016666667, 35.59745483333334, Some(36.0)), + ..Default::default() + }) + ], attrs: HashMap::new() })), children: vec![], From 34f41535098f607e6617cfa2d0331e53d1c62ed5 Mon Sep 17 00:00:00 2001 From: kirillolenev-dm Date: Wed, 24 Dec 2025 21:27:34 +0900 Subject: [PATCH 3/4] Address comments --- .gitignore | 1 + src/reader.rs | 53 ++++++++++++++++------------------------ src/types/line_string.rs | 13 ++++++++++ src/types/mod.rs | 2 ++ src/types/track.rs | 24 ++++++++++++++++++ 5 files changed, 61 insertions(+), 32 deletions(-) create mode 100644 src/types/track.rs diff --git a/.gitignore b/.gitignore index 1a9e589..7ae5d1f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /target /Cargo.lock +.idea/* **/*.rs.bk rusty-tags.emacs diff --git a/src/reader.rs b/src/reader.rs index 4fbc3fe..43afe7f 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -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 @@ -416,21 +416,15 @@ where Ok(MultiGeometry { geometries, attrs }) } - fn read_gx_track_coords( - &mut self, - attrs: HashMap, - ) -> Result, Error> { - let mut geometries: Vec> = Vec::new(); + fn read_track(&mut self, attrs: HashMap) -> Result, Error> { + let mut coords: Vec> = 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" { - geometries.push(Geometry::Point( - coords_from_str(&self.read_str()?.replace(" ", ","))? - .remove(0) - .into(), - )); + let mut coord = coords_from_str(&self.read_str()?.replace(" ", ","))?; + coords.push(coord.remove(0)); } } Event::End(ref mut e) => { @@ -442,7 +436,7 @@ where _ => {} } } - Ok(MultiGeometry { geometries, attrs }) + Ok(Track { coords, attrs }) } fn read_placemark(&mut self, attrs: HashMap) -> Result, Error> { @@ -474,8 +468,7 @@ where Some(Geometry::MultiGeometry(self.read_multi_geometry(attrs)?)) } b"Track" => { - geometry = - Some(Geometry::MultiGeometry(self.read_gx_track_coords(attrs)?)); + geometry = Some(Geometry::LineString(self.read_track(attrs)?.into())); } _ => { let start = e.to_owned(); @@ -1925,13 +1918,14 @@ mod tests { } #[test] - fn test_parse_kml_document_default222() { + fn test_parse_kml_document_with_track() { let kml_str = r#" Test Placemark 139.74128033333332 35.60417266666666 30.099999999999998 139.73755016666667 35.59745483333334 36.0 + 139.73755018666667 35.589745483333334 40.0 "#; @@ -1940,23 +1934,18 @@ mod tests { kml, Kml::Placemark(Placemark { name: Some("Test Placemark".to_string()), - geometry: Some(Geometry::MultiGeometry(MultiGeometry { - geometries: vec![ - Geometry::Point(Point { - coord: Coord::new( - 139.74128033333332, - 35.60417266666666, - Some(30.099999999999998) - ), - ..Default::default() - }), - Geometry::Point(Point { - coord: Coord::new(139.73755016666667, 35.59745483333334, Some(36.0)), - ..Default::default() - }) - ], - attrs: HashMap::new() - })), + 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.589745483333334, Some(40.0)) + ] + .into() + )), children: vec![], ..Default::default() }) diff --git a/src/types/line_string.rs b/src/types/line_string.rs index 08166ab..3689808 100644 --- a/src/types/line_string.rs +++ b/src/types/line_string.rs @@ -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 @@ -25,3 +26,15 @@ where } } } + +impl From> for LineString +where + T: CoordType + Default, +{ + fn from(track: Track) -> Self { + LineString { + coords: track.coords, + ..Default::default() + } + } +} diff --git a/src/types/mod.rs b/src/types/mod.rs index dd9470e..67afd74 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -13,6 +13,7 @@ mod orientation; mod point; mod polygon; mod scale; +mod track; mod vec2; pub use line_string::LineString; @@ -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; diff --git a/src/types/track.rs b/src/types/track.rs new file mode 100644 index 0000000..0d5e787 --- /dev/null +++ b/src/types/track.rs @@ -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 { + pub coords: Vec>, + pub attrs: HashMap, +} + +impl Track +where + T: CoordType + Default, +{ + pub fn new(coords: Vec>) -> Self { + Track { + coords, + ..Default::default() + } + } +} From db9152ba6d97550f0eaacc3f0aca30a46c86e3ab Mon Sep 17 00:00:00 2001 From: kirillolenev-dm Date: Fri, 9 Jan 2026 00:15:16 +0900 Subject: [PATCH 4/4] clippy fix --- src/reader.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/reader.rs b/src/reader.rs index 43afe7f..4bdb43e 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -1925,7 +1925,7 @@ mod tests { 139.74128033333332 35.60417266666666 30.099999999999998 139.73755016666667 35.59745483333334 36.0 - 139.73755018666667 35.589745483333334 40.0 + 139.73755018666667 35.58974548333334 40.0 "#; @@ -1942,7 +1942,7 @@ mod tests { Some(30.099999999999998) ), Coord::new(139.73755016666667, 35.59745483333334, Some(36.0)), - Coord::new(139.73755018666667, 35.589745483333334, Some(40.0)) + Coord::new(139.73755018666667, 35.58974548333334, Some(40.0)) ] .into() )),