mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-09-24 08:27:37 +00:00
parsing continued
This commit is contained in:
@@ -1,9 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns="http://www.topografix.com/GPX/1/1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.topografix.com/GPX/gpx_style/0/2 http://www.topografix.com/GPX/gpx_style/0/2/gpx_style.xsd"
|
xmlns="http://www.topografix.com/GPX/1/1"
|
||||||
|
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd
|
||||||
|
http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd
|
||||||
|
http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd
|
||||||
|
http://www.topografix.com/GPX/gpx_style/0/2 http://www.topografix.com/GPX/gpx_style/0/2/gpx_style.xsd"
|
||||||
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"
|
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"
|
||||||
xmlns:gpx_style="http://www.topografix.com/GPX/gpx_style/0/2" version="1.1" creator="https://gpx.studio">
|
xmlns:gpx_style="http://www.topografix.com/GPX/gpx_style/0/2" version="1.1"
|
||||||
|
creator="https://gpx.studio">
|
||||||
<metadata>
|
<metadata>
|
||||||
<name>with_waypoint</name>
|
<name>with_waypoint</name>
|
||||||
<author>
|
<author>
|
||||||
@@ -13,10 +18,14 @@
|
|||||||
</metadata>
|
</metadata>
|
||||||
<wpt lat="50.7836710064975" lon="4.410764082658738">
|
<wpt lat="50.7836710064975" lon="4.410764082658738">
|
||||||
<ele>122.0</ele>
|
<ele>122.0</ele>
|
||||||
<name>Waypoint</name>
|
<name>waypoint name</name>
|
||||||
<cmt>Comment</cmt>
|
<cmt>waypoint comment</cmt>
|
||||||
<desc>Description</desc>
|
<desc>waypoint description</desc>
|
||||||
|
<link href="https://gpx.studio">
|
||||||
|
<text>waypoint link text</text>
|
||||||
|
</link>
|
||||||
<sym>Bike Trail</sym>
|
<sym>Bike Trail</sym>
|
||||||
|
<type>Bike Trail</type>
|
||||||
</wpt>
|
</wpt>
|
||||||
<trk>
|
<trk>
|
||||||
<name>with_waypoint</name>
|
<name>with_waypoint</name>
|
||||||
|
|||||||
+139
-23
@@ -1,6 +1,12 @@
|
|||||||
use crate::gpx::{Author, GPXFile, Link, Track, TrackPoint, TrackSegment};
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::gpx::{
|
||||||
|
Author, GPXFile, Link, LngLat, Track, TrackPoint, TrackPointChunk, TrackSegment, Waypoint,
|
||||||
|
WaypointChunk,
|
||||||
|
};
|
||||||
use quick_xml::Error;
|
use quick_xml::Error;
|
||||||
use quick_xml::events::Event;
|
use quick_xml::events::Event;
|
||||||
|
use quick_xml::events::attributes::Attributes;
|
||||||
use quick_xml::reader::Reader;
|
use quick_xml::reader::Reader;
|
||||||
|
|
||||||
enum GPXElement {
|
enum GPXElement {
|
||||||
@@ -15,14 +21,32 @@ enum GPXElement {
|
|||||||
TRACK(Track),
|
TRACK(Track),
|
||||||
SEGMENT(TrackSegment),
|
SEGMENT(TrackSegment),
|
||||||
TRACKPOINT(TrackPoint),
|
TRACKPOINT(TrackPoint),
|
||||||
|
WAYPOINT(Waypoint),
|
||||||
|
SYMBOL,
|
||||||
|
TYPE,
|
||||||
ELEVATION,
|
ELEVATION,
|
||||||
}
|
}
|
||||||
|
fn parse_coordinates(attributes: Attributes<'_>) -> LngLat {
|
||||||
|
let mut coordinates = LngLat::default();
|
||||||
|
for attr in attributes {
|
||||||
|
if let Ok(attr) = attr {
|
||||||
|
match attr.key.as_ref() {
|
||||||
|
"lat" => coordinates.lat = attr.value.parse().unwrap_or_default(),
|
||||||
|
"lon" => coordinates.lng = attr.value.parse().unwrap_or_default(),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
coordinates
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse(data: &[u8]) -> Result<GPXFile, Error> {
|
pub fn parse(data: &[u8]) -> Result<GPXFile, Error> {
|
||||||
let mut reader = Reader::from_reader(data);
|
let mut reader = Reader::from_reader(data);
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
let mut gpx = GPXFile::default();
|
let mut gpx = GPXFile::default();
|
||||||
let mut stack: Vec<GPXElement> = vec![];
|
let mut stack: Vec<GPXElement> = vec![];
|
||||||
|
let mut trkpt_chunk = TrackPointChunk::default();
|
||||||
|
let mut wpt_chunk = WaypointChunk::default();
|
||||||
loop {
|
loop {
|
||||||
match reader.read_event_into(&mut buf) {
|
match reader.read_event_into(&mut buf) {
|
||||||
Ok(Event::Start(e)) => match e.name().as_ref() {
|
Ok(Event::Start(e)) => match e.name().as_ref() {
|
||||||
@@ -45,28 +69,31 @@ pub fn parse(data: &[u8]) -> Result<GPXFile, Error> {
|
|||||||
}
|
}
|
||||||
"text" => stack.push(GPXElement::TEXT),
|
"text" => stack.push(GPXElement::TEXT),
|
||||||
"trk" => stack.push(GPXElement::TRACK(Track::default())),
|
"trk" => stack.push(GPXElement::TRACK(Track::default())),
|
||||||
"trkseg" => stack.push(GPXElement::SEGMENT(TrackSegment::default())),
|
"trkseg" => {
|
||||||
|
stack.push(GPXElement::SEGMENT(TrackSegment::default()));
|
||||||
|
}
|
||||||
"trkpt" => {
|
"trkpt" => {
|
||||||
let mut trkpt = TrackPoint::default();
|
let mut trkpt = TrackPoint::default();
|
||||||
for attr in e.attributes() {
|
trkpt.coordinates = parse_coordinates(e.attributes());
|
||||||
if let Ok(attr) = attr {
|
|
||||||
match attr.key.as_ref() {
|
|
||||||
"lat" => {
|
|
||||||
trkpt.coordinates.lat = attr.value.parse().unwrap_or_default()
|
|
||||||
}
|
|
||||||
"lon" => {
|
|
||||||
trkpt.coordinates.lng = attr.value.parse().unwrap_or_default()
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stack.push(GPXElement::TRACKPOINT(trkpt));
|
stack.push(GPXElement::TRACKPOINT(trkpt));
|
||||||
}
|
}
|
||||||
|
"wpt" => {
|
||||||
|
let mut wpt = Waypoint::default();
|
||||||
|
wpt.coordinates = parse_coordinates(e.attributes());
|
||||||
|
stack.push(GPXElement::WAYPOINT(wpt));
|
||||||
|
}
|
||||||
"ele" => stack.push(GPXElement::ELEVATION),
|
"ele" => stack.push(GPXElement::ELEVATION),
|
||||||
|
"sym" => stack.push(GPXElement::SYMBOL),
|
||||||
|
"type" => stack.push(GPXElement::TYPE),
|
||||||
_ => println!("{:?}", e),
|
_ => println!("{:?}", e),
|
||||||
},
|
},
|
||||||
Ok(Event::End(e)) => match e.name().as_ref() {
|
Ok(Event::End(e)) => match e.name().as_ref() {
|
||||||
|
"gpx" => {
|
||||||
|
if !wpt_chunk.wpt.is_empty() {
|
||||||
|
gpx.wpt.push(Rc::new(wpt_chunk));
|
||||||
|
wpt_chunk = WaypointChunk::default();
|
||||||
|
}
|
||||||
|
}
|
||||||
"metadata" => {
|
"metadata" => {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
}
|
}
|
||||||
@@ -84,6 +111,9 @@ pub fn parse(data: &[u8]) -> Result<GPXFile, Error> {
|
|||||||
Some(GPXElement::TRACK(trk)) => {
|
Some(GPXElement::TRACK(trk)) => {
|
||||||
trk.info.link = Some(link);
|
trk.info.link = Some(link);
|
||||||
}
|
}
|
||||||
|
Some(GPXElement::WAYPOINT(wpt)) => {
|
||||||
|
wpt.link = Some(link);
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,8 +124,12 @@ pub fn parse(data: &[u8]) -> Result<GPXFile, Error> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"trkseg" => {
|
"trkseg" => {
|
||||||
if let Some(GPXElement::SEGMENT(trkseg)) = stack.pop() {
|
if let Some(GPXElement::SEGMENT(mut trkseg)) = stack.pop() {
|
||||||
if let Some(GPXElement::TRACK(trk)) = stack.last_mut() {
|
if let Some(GPXElement::TRACK(trk)) = stack.last_mut() {
|
||||||
|
if !trkpt_chunk.trkpt.is_empty() {
|
||||||
|
trkseg.chunks.push(Rc::new(trkpt_chunk));
|
||||||
|
trkpt_chunk = TrackPointChunk::default();
|
||||||
|
}
|
||||||
trk.trkseg.push(trkseg);
|
trk.trkseg.push(trkseg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,7 +137,20 @@ pub fn parse(data: &[u8]) -> Result<GPXFile, Error> {
|
|||||||
"trkpt" => {
|
"trkpt" => {
|
||||||
if let Some(GPXElement::TRACKPOINT(trkpt)) = stack.pop() {
|
if let Some(GPXElement::TRACKPOINT(trkpt)) = stack.pop() {
|
||||||
if let Some(GPXElement::SEGMENT(trkseg)) = stack.last_mut() {
|
if let Some(GPXElement::SEGMENT(trkseg)) = stack.last_mut() {
|
||||||
trkseg.append(trkpt);
|
trkpt_chunk.trkpt.push(trkpt);
|
||||||
|
if trkpt_chunk.is_full() {
|
||||||
|
trkseg.chunks.push(Rc::new(trkpt_chunk));
|
||||||
|
trkpt_chunk = TrackPointChunk::default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"wpt" => {
|
||||||
|
if let Some(GPXElement::WAYPOINT(wpt)) = stack.pop() {
|
||||||
|
wpt_chunk.wpt.push(wpt);
|
||||||
|
if wpt_chunk.is_full() {
|
||||||
|
gpx.wpt.push(Rc::new(wpt_chunk));
|
||||||
|
wpt_chunk = WaypointChunk::default();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,6 +169,9 @@ pub fn parse(data: &[u8]) -> Result<GPXFile, Error> {
|
|||||||
Some(GPXElement::TRACK(trk)) => {
|
Some(GPXElement::TRACK(trk)) => {
|
||||||
trk.info.name = Some(e.to_string());
|
trk.info.name = Some(e.to_string());
|
||||||
}
|
}
|
||||||
|
Some(GPXElement::WAYPOINT(wpt)) => {
|
||||||
|
wpt.name = Some(e.to_string());
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,6 +181,9 @@ pub fn parse(data: &[u8]) -> Result<GPXFile, Error> {
|
|||||||
Some(GPXElement::TRACK(trk)) => {
|
Some(GPXElement::TRACK(trk)) => {
|
||||||
trk.info.cmt = Some(e.to_string());
|
trk.info.cmt = Some(e.to_string());
|
||||||
}
|
}
|
||||||
|
Some(GPXElement::WAYPOINT(wpt)) => {
|
||||||
|
wpt.cmt = Some(e.to_string());
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,6 +196,9 @@ pub fn parse(data: &[u8]) -> Result<GPXFile, Error> {
|
|||||||
Some(GPXElement::TRACK(trk)) => {
|
Some(GPXElement::TRACK(trk)) => {
|
||||||
trk.info.desc = Some(e.to_string());
|
trk.info.desc = Some(e.to_string());
|
||||||
}
|
}
|
||||||
|
Some(GPXElement::WAYPOINT(wpt)) => {
|
||||||
|
wpt.desc = Some(e.to_string());
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,9 +219,36 @@ pub fn parse(data: &[u8]) -> Result<GPXFile, Error> {
|
|||||||
}
|
}
|
||||||
Some(GPXElement::ELEVATION) => {
|
Some(GPXElement::ELEVATION) => {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
if let Some(GPXElement::TRACKPOINT(trkpt)) = stack.last_mut() {
|
match stack.last_mut() {
|
||||||
|
Some(GPXElement::TRACKPOINT(trkpt)) => {
|
||||||
trkpt.ele = e.parse().unwrap_or_default();
|
trkpt.ele = e.parse().unwrap_or_default();
|
||||||
}
|
}
|
||||||
|
Some(GPXElement::WAYPOINT(wpt)) => {
|
||||||
|
wpt.ele = e.parse().unwrap_or_default();
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(GPXElement::TYPE) => {
|
||||||
|
stack.pop();
|
||||||
|
match stack.last_mut() {
|
||||||
|
Some(GPXElement::TRACK(trk)) => {
|
||||||
|
trk.info.type_ = Some(e.to_string());
|
||||||
|
}
|
||||||
|
Some(GPXElement::WAYPOINT(wpt)) => {
|
||||||
|
wpt.type_ = Some(e.to_string());
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(GPXElement::SYMBOL) => {
|
||||||
|
stack.pop();
|
||||||
|
match stack.last_mut() {
|
||||||
|
Some(GPXElement::WAYPOINT(wpt)) => {
|
||||||
|
wpt.sym = Some(e.to_string());
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
},
|
},
|
||||||
@@ -185,12 +268,11 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse() {
|
fn test_parse_simple() {
|
||||||
let mut f = File::open("data/simple.gpx").unwrap();
|
let mut f = File::open("data/simple.gpx").unwrap();
|
||||||
let mut data = String::new();
|
let mut data = String::new();
|
||||||
let _ = f.read_to_string(&mut data);
|
let _ = f.read_to_string(&mut data);
|
||||||
let gpx = parse(data.as_bytes()).unwrap();
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
println!("{:?}", gpx);
|
|
||||||
|
|
||||||
assert_eq!(gpx.info.name, "simple");
|
assert_eq!(gpx.info.name, "simple");
|
||||||
assert!(gpx.info.desc.is_some_and(|d| d == "description"));
|
assert!(gpx.info.desc.is_some_and(|d| d == "description"));
|
||||||
@@ -210,22 +292,56 @@ mod tests {
|
|||||||
trk.info
|
trk.info
|
||||||
.desc
|
.desc
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.is_some_and(|n| n == "track description")
|
.is_some_and(|d| d == "track description")
|
||||||
);
|
);
|
||||||
assert!(trk.info.src.as_ref().is_some_and(|n| n == "track source"));
|
assert!(trk.info.src.as_ref().is_some_and(|s| s == "track source"));
|
||||||
assert!(trk.info.link.is_some());
|
assert!(trk.info.link.is_some());
|
||||||
let link = trk.info.link.as_ref().unwrap();
|
let link = trk.info.link.as_ref().unwrap();
|
||||||
assert_eq!(link.href, "https://gpx.studio");
|
assert_eq!(link.href, "https://gpx.studio");
|
||||||
assert!(link.text.as_ref().is_some_and(|t| t == "track link text"));
|
assert!(link.text.as_ref().is_some_and(|t| t == "track link text"));
|
||||||
|
assert!(trk.info.type_.as_ref().is_some_and(|c| c == "Cycling"));
|
||||||
|
|
||||||
assert_eq!(gpx.trk[0].trkseg.len(), 1);
|
assert_eq!(gpx.trk[0].trkseg.len(), 1);
|
||||||
let trkseg = &gpx.trk[0].trkseg[0];
|
let trkseg = &gpx.trk[0].trkseg[0];
|
||||||
assert_eq!(trkseg.chunks.len(), 1);
|
assert_eq!(trkseg.chunks.len(), 1);
|
||||||
let chunk = trkseg.chunks[0].borrow();
|
let chunk = &trkseg.chunks[0];
|
||||||
assert_eq!(chunk.trkpt.len(), 80);
|
assert_eq!(chunk.trkpt.len(), 80);
|
||||||
let trkpt = &chunk.trkpt[0];
|
let trkpt = &chunk.trkpt[0];
|
||||||
assert_eq!(trkpt.coordinates.lat, 50.790867);
|
assert_eq!(trkpt.coordinates.lat, 50.790867);
|
||||||
assert_eq!(trkpt.coordinates.lng, 4.404968);
|
assert_eq!(trkpt.coordinates.lng, 4.404968);
|
||||||
assert_eq!(trkpt.ele, 109.0);
|
assert_eq!(trkpt.ele, 109.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_waypoint() {
|
||||||
|
let mut f = File::open("data/with_waypoint.gpx").unwrap();
|
||||||
|
let mut data = String::new();
|
||||||
|
let _ = f.read_to_string(&mut data);
|
||||||
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
|
println!("{:?}", gpx);
|
||||||
|
|
||||||
|
assert_eq!(gpx.wpt.len(), 1);
|
||||||
|
let chunk = &gpx.wpt[0];
|
||||||
|
assert_eq!(chunk.wpt.len(), 1);
|
||||||
|
let wpt = &chunk.wpt[0];
|
||||||
|
assert_eq!(wpt.coordinates.lat, 50.7836710064975);
|
||||||
|
assert_eq!(wpt.coordinates.lng, 4.410764082658738);
|
||||||
|
assert!(wpt.name.as_ref().is_some_and(|n| n == "waypoint name"));
|
||||||
|
assert!(wpt.cmt.as_ref().is_some_and(|c| c == "waypoint comment"));
|
||||||
|
assert!(
|
||||||
|
wpt.desc
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|d| d == "waypoint description")
|
||||||
|
);
|
||||||
|
assert!(wpt.link.is_some());
|
||||||
|
let link = wpt.link.as_ref().unwrap();
|
||||||
|
assert_eq!(link.href, "https://gpx.studio");
|
||||||
|
assert!(
|
||||||
|
link.text
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|t| t == "waypoint link text")
|
||||||
|
);
|
||||||
|
assert!(wpt.sym.as_ref().is_some_and(|s| s == "Bike Trail"));
|
||||||
|
assert!(wpt.type_.as_ref().is_some_and(|t| t == "Bike Trail"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,10 @@
|
|||||||
use std::{cell::RefCell, rc::Rc};
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::gpx::TrackPoint;
|
use crate::gpx::TrackPoint;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct TrackSegment {
|
pub struct TrackSegment {
|
||||||
pub chunks: Vec<Rc<RefCell<TrackPointChunk>>>,
|
pub chunks: Vec<Rc<TrackPointChunk>>,
|
||||||
}
|
|
||||||
|
|
||||||
impl TrackSegment {
|
|
||||||
pub fn append(&mut self, trkpt: TrackPoint) {
|
|
||||||
if self
|
|
||||||
.chunks
|
|
||||||
.last()
|
|
||||||
.is_none_or(|c| c.borrow().trkpt.len() == MAX_CHUNK_SIZE)
|
|
||||||
{
|
|
||||||
self.add_chunk();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.chunks
|
|
||||||
.last_mut()
|
|
||||||
.unwrap()
|
|
||||||
.borrow_mut()
|
|
||||||
.trkpt
|
|
||||||
.push(trkpt);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_chunk(&mut self) {
|
|
||||||
self.chunks
|
|
||||||
.push(Rc::new(RefCell::new(TrackPointChunk::default())));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static MAX_CHUNK_SIZE: usize = 4096;
|
static MAX_CHUNK_SIZE: usize = 4096;
|
||||||
@@ -37,3 +13,9 @@ static MAX_CHUNK_SIZE: usize = 4096;
|
|||||||
pub struct TrackPointChunk {
|
pub struct TrackPointChunk {
|
||||||
pub trkpt: Vec<TrackPoint>,
|
pub trkpt: Vec<TrackPoint>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TrackPointChunk {
|
||||||
|
pub fn is_full(&self) -> bool {
|
||||||
|
self.trkpt.len() == MAX_CHUNK_SIZE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
use crate::gpx::{Link, LngLat};
|
use crate::gpx::{Link, LngLat};
|
||||||
|
|
||||||
pub type WaypointChunk = Vec<Waypoint>;
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Waypoint {
|
pub struct Waypoint {
|
||||||
pub coordinates: LngLat,
|
pub coordinates: LngLat,
|
||||||
@@ -14,3 +12,16 @@ pub struct Waypoint {
|
|||||||
pub sym: Option<String>,
|
pub sym: Option<String>,
|
||||||
pub type_: Option<String>,
|
pub type_: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MAX_CHUNK_SIZE: usize = 128;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct WaypointChunk {
|
||||||
|
pub wpt: Vec<Waypoint>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WaypointChunk {
|
||||||
|
pub fn is_full(&self) -> bool {
|
||||||
|
self.wpt.len() == MAX_CHUNK_SIZE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user