diff --git a/gpx-rs/Cargo.lock b/gpx-rs/Cargo.lock
index a8239360d..30a36cebc 100644
--- a/gpx-rs/Cargo.lock
+++ b/gpx-rs/Cargo.lock
@@ -18,9 +18,16 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
name = "gpx-rs"
version = "0.1.0"
dependencies = [
+ "quick-xml",
"wasm-bindgen",
]
+[[package]]
+name = "memchr"
+version = "2.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
+
[[package]]
name = "once_cell"
version = "1.21.4"
@@ -36,6 +43,15 @@ dependencies = [
"unicode-ident",
]
+[[package]]
+name = "quick-xml"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41b1177fdf999d2321d3fb46ff47159d9c1fb9ad66a4879f8c50a0b504615e9b"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "quote"
version = "1.0.46"
diff --git a/gpx-rs/Cargo.toml b/gpx-rs/Cargo.toml
index 769904f90..bf76571c5 100644
--- a/gpx-rs/Cargo.toml
+++ b/gpx-rs/Cargo.toml
@@ -7,4 +7,5 @@ edition = "2024"
crate-type = ["cdylib"]
[dependencies]
-wasm-bindgen = "0.2"
\ No newline at end of file
+quick-xml = "0.42.0"
+wasm-bindgen = "0.2"
diff --git a/gpx-rs/data/simple.gpx b/gpx-rs/data/simple.gpx
new file mode 100644
index 000000000..c73a67fb5
--- /dev/null
+++ b/gpx-rs/data/simple.gpx
@@ -0,0 +1,274 @@
+
+
+
+ simple
+ description
+
+ gpx.studio
+
+ link text
+
+
+
+
+ track name
+ track comment
+ track description
+ track source
+
+ track link text
+
+ Cycling
+
+
+ 109.0
+
+
+ 110.8
+
+
+ 110.3
+
+
+ 110.0
+
+
+ 110.3
+
+
+ 109.3
+
+
+ 107.0
+
+
+ 106.0
+
+
+ 108.5
+
+
+ 109.8
+
+
+ 110.8
+
+
+ 112.0
+
+
+ 112.8
+
+
+ 113.5
+
+
+ 114.3
+
+
+ 115.3
+
+
+ 114.8
+
+
+ 114.3
+
+
+ 114.3
+
+
+ 114.5
+
+
+ 115.0
+
+
+ 115.8
+
+
+ 115.8
+
+
+ 116.0
+
+
+ 115.8
+
+
+ 115.5
+
+
+ 114.5
+
+
+ 112.5
+
+
+ 110.8
+
+
+ 109.0
+
+
+ 106.3
+
+
+ 104.3
+
+
+ 104.0
+
+
+ 103.8
+
+
+ 103.3
+
+
+ 103.5
+
+
+ 103.8
+
+
+ 104.8
+
+
+ 105.8
+
+
+ 106.8
+
+
+ 107.8
+
+
+ 108.5
+
+
+ 109.3
+
+
+ 110.0
+
+
+ 110.5
+
+
+ 110.8
+
+
+ 111.8
+
+
+ 112.8
+
+
+ 113.3
+
+
+ 113.5
+
+
+ 113.5
+
+
+ 113.8
+
+
+ 114.8
+
+
+ 115.8
+
+
+ 118.5
+
+
+ 119.5
+
+
+ 121.3
+
+
+ 122.0
+
+
+ 122.8
+
+
+ 123.5
+
+
+ 126.3
+
+
+ 128.0
+
+
+ 129.0
+
+
+ 130.0
+
+
+ 130.8
+
+
+ 131.8
+
+
+ 132.3
+
+
+ 132.8
+
+
+ 135.8
+
+
+ 135.5
+
+
+ 132.5
+
+
+ 134.0
+
+
+ 136.8
+
+
+ 137.5
+
+
+ 137.3
+
+
+ 137.5
+
+
+ 137.3
+
+
+ 134.8
+
+
+ 132.3
+
+
+ 129.5
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/data/with_cad.gpx b/gpx-rs/data/with_cad.gpx
new file mode 100644
index 000000000..1ac66703b
--- /dev/null
+++ b/gpx-rs/data/with_cad.gpx
@@ -0,0 +1,660 @@
+
+
+
+ with_cad
+
+ gpx.studio
+
+
+
+
+ with_cad
+ Cycling
+
+
+ 109.0
+
+
+ 80
+
+
+
+
+ 110.8
+
+
+ 80
+
+
+
+
+ 110.3
+
+
+ 80
+
+
+
+
+ 110.0
+
+
+ 80
+
+
+
+
+ 110.3
+
+
+ 80
+
+
+
+
+ 109.3
+
+
+ 80
+
+
+
+
+ 107.0
+
+
+ 80
+
+
+
+
+ 106.0
+
+
+ 80
+
+
+
+
+ 108.5
+
+
+ 80
+
+
+
+
+ 109.8
+
+
+ 80
+
+
+
+
+ 110.8
+
+
+ 80
+
+
+
+
+ 112.0
+
+
+ 80
+
+
+
+
+ 112.8
+
+
+ 80
+
+
+
+
+ 113.5
+
+
+ 80
+
+
+
+
+ 114.3
+
+
+ 80
+
+
+
+
+ 115.3
+
+
+ 80
+
+
+
+
+ 114.8
+
+
+ 80
+
+
+
+
+ 114.3
+
+
+ 80
+
+
+
+
+ 114.3
+
+
+ 80
+
+
+
+
+ 114.5
+
+
+ 80
+
+
+
+
+ 115.0
+
+
+ 80
+
+
+
+
+ 115.8
+
+
+ 80
+
+
+
+
+ 115.8
+
+
+ 80
+
+
+
+
+ 116.0
+
+
+ 80
+
+
+
+
+ 115.8
+
+
+ 80
+
+
+
+
+ 115.5
+
+
+ 80
+
+
+
+
+ 114.5
+
+
+ 80
+
+
+
+
+ 112.5
+
+
+ 80
+
+
+
+
+ 110.8
+
+
+ 80
+
+
+
+
+ 109.0
+
+
+ 80
+
+
+
+
+ 106.3
+
+
+ 80
+
+
+
+
+ 104.3
+
+
+ 80
+
+
+
+
+ 104.0
+
+
+ 80
+
+
+
+
+ 103.8
+
+
+ 80
+
+
+
+
+ 103.3
+
+
+ 80
+
+
+
+
+ 103.5
+
+
+ 80
+
+
+
+
+ 103.8
+
+
+ 80
+
+
+
+
+ 104.8
+
+
+ 80
+
+
+
+
+ 105.8
+
+
+ 80
+
+
+
+
+ 106.8
+
+
+ 80
+
+
+
+
+ 107.8
+
+
+ 80
+
+
+
+
+ 108.5
+
+
+ 80
+
+
+
+
+ 109.3
+
+
+ 80
+
+
+
+
+ 110.0
+
+
+ 80
+
+
+
+
+ 110.5
+
+
+ 80
+
+
+
+
+ 110.8
+
+
+ 80
+
+
+
+
+ 111.8
+
+
+ 80
+
+
+
+
+ 112.8
+
+
+ 80
+
+
+
+
+ 113.3
+
+
+ 80
+
+
+
+
+ 113.5
+
+
+ 80
+
+
+
+
+ 113.5
+
+
+ 80
+
+
+
+
+ 113.8
+
+
+ 80
+
+
+
+
+ 114.8
+
+
+ 80
+
+
+
+
+ 115.8
+
+
+ 80
+
+
+
+
+ 118.5
+
+
+ 80
+
+
+
+
+ 119.5
+
+
+ 80
+
+
+
+
+ 121.3
+
+
+ 80
+
+
+
+
+ 122.0
+
+
+ 80
+
+
+
+
+ 122.8
+
+
+ 80
+
+
+
+
+ 123.5
+
+
+ 80
+
+
+
+
+ 126.3
+
+
+ 80
+
+
+
+
+ 128.0
+
+
+ 80
+
+
+
+
+ 129.0
+
+
+ 80
+
+
+
+
+ 130.0
+
+
+ 80
+
+
+
+
+ 130.8
+
+
+ 80
+
+
+
+
+ 131.8
+
+
+ 80
+
+
+
+
+ 132.3
+
+
+ 80
+
+
+
+
+ 132.8
+
+
+ 80
+
+
+
+
+ 135.8
+
+
+ 80
+
+
+
+
+ 135.5
+
+
+ 80
+
+
+
+
+ 132.5
+
+
+ 80
+
+
+
+
+ 134.0
+
+
+ 80
+
+
+
+
+ 136.8
+
+
+ 80
+
+
+
+
+ 137.5
+
+
+ 80
+
+
+
+
+ 137.3
+
+
+ 80
+
+
+
+
+ 137.5
+
+
+ 80
+
+
+
+
+ 137.3
+
+
+ 80
+
+
+
+
+ 134.8
+
+
+ 80
+
+
+
+
+ 132.3
+
+
+ 80
+
+
+
+
+ 129.5
+
+
+ 90
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/data/with_hr.gpx b/gpx-rs/data/with_hr.gpx
new file mode 100644
index 000000000..f2c566a59
--- /dev/null
+++ b/gpx-rs/data/with_hr.gpx
@@ -0,0 +1,660 @@
+
+
+
+ with_hr
+
+ gpx.studio
+
+
+
+
+ with_hr
+ Cycling
+
+
+ 109.0
+
+
+ 150
+
+
+
+
+ 110.8
+
+
+ 150
+
+
+
+
+ 110.3
+
+
+ 150
+
+
+
+
+ 110.0
+
+
+ 150
+
+
+
+
+ 110.3
+
+
+ 150
+
+
+
+
+ 109.3
+
+
+ 150
+
+
+
+
+ 107.0
+
+
+ 150
+
+
+
+
+ 106.0
+
+
+ 150
+
+
+
+
+ 108.5
+
+
+ 150
+
+
+
+
+ 109.8
+
+
+ 150
+
+
+
+
+ 110.8
+
+
+ 150
+
+
+
+
+ 112.0
+
+
+ 150
+
+
+
+
+ 112.8
+
+
+ 150
+
+
+
+
+ 113.5
+
+
+ 150
+
+
+
+
+ 114.3
+
+
+ 150
+
+
+
+
+ 115.3
+
+
+ 150
+
+
+
+
+ 114.8
+
+
+ 150
+
+
+
+
+ 114.3
+
+
+ 150
+
+
+
+
+ 114.3
+
+
+ 150
+
+
+
+
+ 114.5
+
+
+ 150
+
+
+
+
+ 115.0
+
+
+ 150
+
+
+
+
+ 115.8
+
+
+ 150
+
+
+
+
+ 115.8
+
+
+ 150
+
+
+
+
+ 116.0
+
+
+ 150
+
+
+
+
+ 115.8
+
+
+ 150
+
+
+
+
+ 115.5
+
+
+ 150
+
+
+
+
+ 114.5
+
+
+ 150
+
+
+
+
+ 112.5
+
+
+ 150
+
+
+
+
+ 110.8
+
+
+ 150
+
+
+
+
+ 109.0
+
+
+ 150
+
+
+
+
+ 106.3
+
+
+ 150
+
+
+
+
+ 104.3
+
+
+ 150
+
+
+
+
+ 104.0
+
+
+ 150
+
+
+
+
+ 103.8
+
+
+ 150
+
+
+
+
+ 103.3
+
+
+ 150
+
+
+
+
+ 103.5
+
+
+ 150
+
+
+
+
+ 103.8
+
+
+ 150
+
+
+
+
+ 104.8
+
+
+ 150
+
+
+
+
+ 105.8
+
+
+ 150
+
+
+
+
+ 106.8
+
+
+ 150
+
+
+
+
+ 107.8
+
+
+ 150
+
+
+
+
+ 108.5
+
+
+ 150
+
+
+
+
+ 109.3
+
+
+ 150
+
+
+
+
+ 110.0
+
+
+ 150
+
+
+
+
+ 110.5
+
+
+ 150
+
+
+
+
+ 110.8
+
+
+ 150
+
+
+
+
+ 111.8
+
+
+ 150
+
+
+
+
+ 112.8
+
+
+ 150
+
+
+
+
+ 113.3
+
+
+ 150
+
+
+
+
+ 113.5
+
+
+ 150
+
+
+
+
+ 113.5
+
+
+ 150
+
+
+
+
+ 113.8
+
+
+ 150
+
+
+
+
+ 114.8
+
+
+ 150
+
+
+
+
+ 115.8
+
+
+ 150
+
+
+
+
+ 118.5
+
+
+ 150
+
+
+
+
+ 119.5
+
+
+ 150
+
+
+
+
+ 121.3
+
+
+ 150
+
+
+
+
+ 122.0
+
+
+ 150
+
+
+
+
+ 122.8
+
+
+ 150
+
+
+
+
+ 123.5
+
+
+ 150
+
+
+
+
+ 126.3
+
+
+ 150
+
+
+
+
+ 128.0
+
+
+ 150
+
+
+
+
+ 129.0
+
+
+ 150
+
+
+
+
+ 130.0
+
+
+ 150
+
+
+
+
+ 130.8
+
+
+ 150
+
+
+
+
+ 131.8
+
+
+ 150
+
+
+
+
+ 132.3
+
+
+ 150
+
+
+
+
+ 132.8
+
+
+ 150
+
+
+
+
+ 135.8
+
+
+ 150
+
+
+
+
+ 135.5
+
+
+ 150
+
+
+
+
+ 132.5
+
+
+ 150
+
+
+
+
+ 134.0
+
+
+ 150
+
+
+
+
+ 136.8
+
+
+ 150
+
+
+
+
+ 137.5
+
+
+ 150
+
+
+
+
+ 137.3
+
+
+ 150
+
+
+
+
+ 137.5
+
+
+ 150
+
+
+
+
+ 137.3
+
+
+ 150
+
+
+
+
+ 134.8
+
+
+ 150
+
+
+
+
+ 132.3
+
+
+ 150
+
+
+
+
+ 129.5
+
+
+ 160
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/data/with_power_1.gpx b/gpx-rs/data/with_power_1.gpx
new file mode 100644
index 000000000..5c6407762
--- /dev/null
+++ b/gpx-rs/data/with_power_1.gpx
@@ -0,0 +1,500 @@
+
+
+
+ with_power
+
+ gpx.studio
+
+
+
+
+ with_power
+ Cycling
+
+
+ 109.0
+
+ 200
+
+
+
+ 110.8
+
+ 200
+
+
+
+ 110.3
+
+ 200
+
+
+
+ 110.0
+
+ 200
+
+
+
+ 110.3
+
+ 200
+
+
+
+ 109.3
+
+ 200
+
+
+
+ 107.0
+
+ 200
+
+
+
+ 106.0
+
+ 200
+
+
+
+ 108.5
+
+ 200
+
+
+
+ 109.8
+
+ 200
+
+
+
+ 110.8
+
+ 200
+
+
+
+ 112.0
+
+ 200
+
+
+
+ 112.8
+
+ 200
+
+
+
+ 113.5
+
+ 200
+
+
+
+ 114.3
+
+ 200
+
+
+
+ 115.3
+
+ 200
+
+
+
+ 114.8
+
+ 200
+
+
+
+ 114.3
+
+ 200
+
+
+
+ 114.3
+
+ 200
+
+
+
+ 114.5
+
+ 200
+
+
+
+ 115.0
+
+ 200
+
+
+
+ 115.8
+
+ 200
+
+
+
+ 115.8
+
+ 200
+
+
+
+ 116.0
+
+ 200
+
+
+
+ 115.8
+
+ 200
+
+
+
+ 115.5
+
+ 200
+
+
+
+ 114.5
+
+ 200
+
+
+
+ 112.5
+
+ 200
+
+
+
+ 110.8
+
+ 200
+
+
+
+ 109.0
+
+ 200
+
+
+
+ 106.3
+
+ 200
+
+
+
+ 104.3
+
+ 200
+
+
+
+ 104.0
+
+ 200
+
+
+
+ 103.8
+
+ 200
+
+
+
+ 103.3
+
+ 200
+
+
+
+ 103.5
+
+ 200
+
+
+
+ 103.8
+
+ 200
+
+
+
+ 104.8
+
+ 200
+
+
+
+ 105.8
+
+ 200
+
+
+
+ 106.8
+
+ 200
+
+
+
+ 107.8
+
+ 200
+
+
+
+ 108.5
+
+ 200
+
+
+
+ 109.3
+
+ 200
+
+
+
+ 110.0
+
+ 200
+
+
+
+ 110.5
+
+ 200
+
+
+
+ 110.8
+
+ 200
+
+
+
+ 111.8
+
+ 200
+
+
+
+ 112.8
+
+ 200
+
+
+
+ 113.3
+
+ 200
+
+
+
+ 113.5
+
+ 200
+
+
+
+ 113.5
+
+ 200
+
+
+
+ 113.8
+
+ 200
+
+
+
+ 114.8
+
+ 200
+
+
+
+ 115.8
+
+ 200
+
+
+
+ 118.5
+
+ 200
+
+
+
+ 119.5
+
+ 200
+
+
+
+ 121.3
+
+ 200
+
+
+
+ 122.0
+
+ 200
+
+
+
+ 122.8
+
+ 200
+
+
+
+ 123.5
+
+ 200
+
+
+
+ 126.3
+
+ 200
+
+
+
+ 128.0
+
+ 200
+
+
+
+ 129.0
+
+ 200
+
+
+
+ 130.0
+
+ 200
+
+
+
+ 130.8
+
+ 200
+
+
+
+ 131.8
+
+ 200
+
+
+
+ 132.3
+
+ 200
+
+
+
+ 132.8
+
+ 200
+
+
+
+ 135.8
+
+ 200
+
+
+
+ 135.5
+
+ 200
+
+
+
+ 132.5
+
+ 200
+
+
+
+ 134.0
+
+ 200
+
+
+
+ 136.8
+
+ 200
+
+
+
+ 137.5
+
+ 200
+
+
+
+ 137.3
+
+ 200
+
+
+
+ 137.5
+
+ 200
+
+
+
+ 137.3
+
+ 200
+
+
+
+ 134.8
+
+ 200
+
+
+
+ 132.3
+
+ 200
+
+
+
+ 129.5
+
+ 210
+
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/data/with_power_2.gpx b/gpx-rs/data/with_power_2.gpx
new file mode 100644
index 000000000..b0a530733
--- /dev/null
+++ b/gpx-rs/data/with_power_2.gpx
@@ -0,0 +1,660 @@
+
+
+
+ with_power
+
+ gpx.studio
+
+
+
+
+ with_power
+ Cycling
+
+
+ 109.0
+
+
+ 200
+
+
+
+
+ 110.8
+
+
+ 200
+
+
+
+
+ 110.3
+
+
+ 200
+
+
+
+
+ 110.0
+
+
+ 200
+
+
+
+
+ 110.3
+
+
+ 200
+
+
+
+
+ 109.3
+
+
+ 200
+
+
+
+
+ 107.0
+
+
+ 200
+
+
+
+
+ 106.0
+
+
+ 200
+
+
+
+
+ 108.5
+
+
+ 200
+
+
+
+
+ 109.8
+
+
+ 200
+
+
+
+
+ 110.8
+
+
+ 200
+
+
+
+
+ 112.0
+
+
+ 200
+
+
+
+
+ 112.8
+
+
+ 200
+
+
+
+
+ 113.5
+
+
+ 200
+
+
+
+
+ 114.3
+
+
+ 200
+
+
+
+
+ 115.3
+
+
+ 200
+
+
+
+
+ 114.8
+
+
+ 200
+
+
+
+
+ 114.3
+
+
+ 200
+
+
+
+
+ 114.3
+
+
+ 200
+
+
+
+
+ 114.5
+
+
+ 200
+
+
+
+
+ 115.0
+
+
+ 200
+
+
+
+
+ 115.8
+
+
+ 200
+
+
+
+
+ 115.8
+
+
+ 200
+
+
+
+
+ 116.0
+
+
+ 200
+
+
+
+
+ 115.8
+
+
+ 200
+
+
+
+
+ 115.5
+
+
+ 200
+
+
+
+
+ 114.5
+
+
+ 200
+
+
+
+
+ 112.5
+
+
+ 200
+
+
+
+
+ 110.8
+
+
+ 200
+
+
+
+
+ 109.0
+
+
+ 200
+
+
+
+
+ 106.3
+
+
+ 200
+
+
+
+
+ 104.3
+
+
+ 200
+
+
+
+
+ 104.0
+
+
+ 200
+
+
+
+
+ 103.8
+
+
+ 200
+
+
+
+
+ 103.3
+
+
+ 200
+
+
+
+
+ 103.5
+
+
+ 200
+
+
+
+
+ 103.8
+
+
+ 200
+
+
+
+
+ 104.8
+
+
+ 200
+
+
+
+
+ 105.8
+
+
+ 200
+
+
+
+
+ 106.8
+
+
+ 200
+
+
+
+
+ 107.8
+
+
+ 200
+
+
+
+
+ 108.5
+
+
+ 200
+
+
+
+
+ 109.3
+
+
+ 200
+
+
+
+
+ 110.0
+
+
+ 200
+
+
+
+
+ 110.5
+
+
+ 200
+
+
+
+
+ 110.8
+
+
+ 200
+
+
+
+
+ 111.8
+
+
+ 200
+
+
+
+
+ 112.8
+
+
+ 200
+
+
+
+
+ 113.3
+
+
+ 200
+
+
+
+
+ 113.5
+
+
+ 200
+
+
+
+
+ 113.5
+
+
+ 200
+
+
+
+
+ 113.8
+
+
+ 200
+
+
+
+
+ 114.8
+
+
+ 200
+
+
+
+
+ 115.8
+
+
+ 200
+
+
+
+
+ 118.5
+
+
+ 200
+
+
+
+
+ 119.5
+
+
+ 200
+
+
+
+
+ 121.3
+
+
+ 200
+
+
+
+
+ 122.0
+
+
+ 200
+
+
+
+
+ 122.8
+
+
+ 200
+
+
+
+
+ 123.5
+
+
+ 200
+
+
+
+
+ 126.3
+
+
+ 200
+
+
+
+
+ 128.0
+
+
+ 200
+
+
+
+
+ 129.0
+
+
+ 200
+
+
+
+
+ 130.0
+
+
+ 200
+
+
+
+
+ 130.8
+
+
+ 200
+
+
+
+
+ 131.8
+
+
+ 200
+
+
+
+
+ 132.3
+
+
+ 200
+
+
+
+
+ 132.8
+
+
+ 200
+
+
+
+
+ 135.8
+
+
+ 200
+
+
+
+
+ 135.5
+
+
+ 200
+
+
+
+
+ 132.5
+
+
+ 200
+
+
+
+
+ 134.0
+
+
+ 200
+
+
+
+
+ 136.8
+
+
+ 200
+
+
+
+
+ 137.5
+
+
+ 200
+
+
+
+
+ 137.3
+
+
+ 200
+
+
+
+
+ 137.5
+
+
+ 200
+
+
+
+
+ 137.3
+
+
+ 200
+
+
+
+
+ 134.8
+
+
+ 200
+
+
+
+
+ 132.3
+
+
+ 200
+
+
+
+
+ 129.5
+
+
+ 210
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/data/with_routes.gpx b/gpx-rs/data/with_routes.gpx
new file mode 100644
index 000000000..fd55a291d
--- /dev/null
+++ b/gpx-rs/data/with_routes.gpx
@@ -0,0 +1,253 @@
+
+
+
+ with_routes
+
+ gpx.studio
+
+
+
+
+ route 1
+ Cycling
+
+ 109.0
+
+
+ 110.8
+
+
+ 110.3
+
+
+ 110.0
+
+
+ 110.3
+
+
+ 109.3
+
+
+ 107.0
+
+
+ 106.0
+
+
+ 108.5
+
+
+ 109.8
+
+
+ 110.8
+
+
+ 112.0
+
+
+ 112.8
+
+
+ 113.5
+
+
+ 114.3
+
+
+ 115.3
+
+
+ 114.8
+
+
+ 114.3
+
+
+ 114.3
+
+
+ 114.5
+
+
+ 115.0
+
+
+ 115.8
+
+
+ 115.8
+
+
+ 116.0
+
+
+ 115.8
+
+
+ 115.5
+
+
+ 114.5
+
+
+ 112.5
+
+
+ 110.8
+
+
+ 109.0
+
+
+ 106.3
+
+
+ 104.3
+
+
+ 104.0
+
+
+ 103.8
+
+
+ 103.3
+
+
+ 103.5
+
+
+ 103.8
+
+
+ 104.8
+
+
+ 105.8
+
+
+ 106.8
+
+
+ 107.8
+
+
+ 108.5
+
+
+ 109.3
+
+
+ 110.0
+
+
+ 110.5
+
+
+ 110.8
+
+
+ 111.8
+
+
+ 112.8
+
+
+ 113.3
+
+
+
+ route 2
+ Cycling
+
+ 115.5
+
+
+ 115.8
+
+
+ 118.5
+
+
+ 119.5
+
+
+ 121.3
+
+
+ 122.0
+
+
+ 122.8
+
+
+ 123.5
+
+
+ 126.3
+
+
+ 128.0
+
+
+ 129.0
+
+
+ 130.0
+
+
+ 130.8
+
+
+ 131.8
+
+
+ 132.3
+
+
+ 132.8
+
+
+ 135.8
+
+
+ 135.5
+
+
+ 132.5
+
+
+ 134.0
+
+
+ 136.8
+
+
+ 137.5
+
+
+ 137.3
+
+
+ 137.5
+
+
+ 137.3
+
+
+ 134.8
+
+
+ 132.3
+
+
+ 129.5
+
+
+
diff --git a/gpx-rs/data/with_segments.gpx b/gpx-rs/data/with_segments.gpx
new file mode 100644
index 000000000..05690acb5
--- /dev/null
+++ b/gpx-rs/data/with_segments.gpx
@@ -0,0 +1,253 @@
+
+
+
+ with_segments
+
+ gpx.studio
+
+
+
+
+ with_segments
+ Cycling
+
+
+ 109.0
+
+
+ 110.8
+
+
+ 110.3
+
+
+ 110.0
+
+
+ 110.3
+
+
+ 109.3
+
+
+ 107.0
+
+
+ 106.0
+
+
+ 108.5
+
+
+ 109.8
+
+
+ 110.8
+
+
+ 112.0
+
+
+ 112.8
+
+
+ 113.5
+
+
+ 114.3
+
+
+ 115.3
+
+
+ 114.8
+
+
+ 114.3
+
+
+ 114.3
+
+
+ 114.5
+
+
+ 115.0
+
+
+ 115.8
+
+
+ 115.8
+
+
+ 116.0
+
+
+ 115.8
+
+
+ 115.5
+
+
+ 114.5
+
+
+ 112.5
+
+
+ 110.8
+
+
+ 109.0
+
+
+ 106.3
+
+
+ 104.3
+
+
+ 104.0
+
+
+ 103.8
+
+
+ 103.3
+
+
+ 103.5
+
+
+ 103.8
+
+
+ 104.8
+
+
+ 105.8
+
+
+ 106.8
+
+
+ 107.8
+
+
+ 108.5
+
+
+ 109.3
+
+
+ 110.0
+
+
+ 110.5
+
+
+ 110.8
+
+
+ 111.8
+
+
+ 112.8
+
+
+ 113.3
+
+
+
+
+ 115.5
+
+
+ 115.8
+
+
+ 118.5
+
+
+ 119.5
+
+
+ 121.3
+
+
+ 122.0
+
+
+ 122.8
+
+
+ 123.5
+
+
+ 126.3
+
+
+ 128.0
+
+
+ 129.0
+
+
+ 130.0
+
+
+ 130.8
+
+
+ 131.8
+
+
+ 132.3
+
+
+ 132.8
+
+
+ 135.8
+
+
+ 135.5
+
+
+ 132.5
+
+
+ 134.0
+
+
+ 136.8
+
+
+ 137.5
+
+
+ 137.3
+
+
+ 137.5
+
+
+ 137.3
+
+
+ 134.8
+
+
+ 132.3
+
+
+ 129.5
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/data/with_style.gpx b/gpx-rs/data/with_style.gpx
new file mode 100644
index 000000000..98b5e7fc4
--- /dev/null
+++ b/gpx-rs/data/with_style.gpx
@@ -0,0 +1,267 @@
+
+
+
+ with_style
+
+ gpx.studio
+
+
+
+
+ with_style
+ Cycling
+
+
+ 2d3ee9
+ 0.5
+ 6
+
+
+
+
+ 109.0
+
+
+ 110.8
+
+
+ 110.3
+
+
+ 110.0
+
+
+ 110.3
+
+
+ 109.3
+
+
+ 107.0
+
+
+ 106.0
+
+
+ 108.5
+
+
+ 109.8
+
+
+ 110.8
+
+
+ 112.0
+
+
+ 112.8
+
+
+ 113.5
+
+
+ 114.3
+
+
+ 115.3
+
+
+ 114.8
+
+
+ 114.3
+
+
+ 114.3
+
+
+ 114.5
+
+
+ 115.0
+
+
+ 115.8
+
+
+ 115.8
+
+
+ 116.0
+
+
+ 115.8
+
+
+ 115.5
+
+
+ 114.5
+
+
+ 112.5
+
+
+ 110.8
+
+
+ 109.0
+
+
+ 106.3
+
+
+ 104.3
+
+
+ 104.0
+
+
+ 103.8
+
+
+ 103.3
+
+
+ 103.5
+
+
+ 103.8
+
+
+ 104.8
+
+
+ 105.8
+
+
+ 106.8
+
+
+ 107.8
+
+
+ 108.5
+
+
+ 109.3
+
+
+ 110.0
+
+
+ 110.5
+
+
+ 110.8
+
+
+ 111.8
+
+
+ 112.8
+
+
+ 113.3
+
+
+ 113.5
+
+
+ 113.5
+
+
+ 113.8
+
+
+ 114.8
+
+
+ 115.8
+
+
+ 118.5
+
+
+ 119.5
+
+
+ 121.3
+
+
+ 122.0
+
+
+ 122.8
+
+
+ 123.5
+
+
+ 126.3
+
+
+ 128.0
+
+
+ 129.0
+
+
+ 130.0
+
+
+ 130.8
+
+
+ 131.8
+
+
+ 132.3
+
+
+ 132.8
+
+
+ 135.8
+
+
+ 135.5
+
+
+ 132.5
+
+
+ 134.0
+
+
+ 136.8
+
+
+ 137.5
+
+
+ 137.3
+
+
+ 137.5
+
+
+ 137.3
+
+
+ 134.8
+
+
+ 132.3
+
+
+ 129.5
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/data/with_surface.gpx b/gpx-rs/data/with_surface.gpx
new file mode 100644
index 000000000..a4d539100
--- /dev/null
+++ b/gpx-rs/data/with_surface.gpx
@@ -0,0 +1,820 @@
+
+
+
+ with_surface
+
+ gpx.studio
+
+
+
+
+ with_surface
+ Cycling
+
+
+ 109.0
+
+
+
+ asphalt
+
+
+
+
+
+ 110.8
+
+
+
+ asphalt
+
+
+
+
+
+ 110.3
+
+
+
+ asphalt
+
+
+
+
+
+ 110.0
+
+
+
+ asphalt
+
+
+
+
+
+ 110.3
+
+
+
+ asphalt
+
+
+
+
+
+ 109.3
+
+
+
+ asphalt
+
+
+
+
+
+ 107.0
+
+
+
+ asphalt
+
+
+
+
+
+ 106.0
+
+
+
+ asphalt
+
+
+
+
+
+ 108.5
+
+
+
+ asphalt
+
+
+
+
+
+ 109.8
+
+
+
+ asphalt
+
+
+
+
+
+ 110.8
+
+
+
+ asphalt
+
+
+
+
+
+ 112.0
+
+
+
+ asphalt
+
+
+
+
+
+ 112.8
+
+
+
+ asphalt
+
+
+
+
+
+ 113.5
+
+
+
+ asphalt
+
+
+
+
+
+ 114.3
+
+
+
+ asphalt
+
+
+
+
+
+ 115.3
+
+
+
+ asphalt
+
+
+
+
+
+ 114.8
+
+
+
+ asphalt
+
+
+
+
+
+ 114.3
+
+
+
+ asphalt
+
+
+
+
+
+ 114.3
+
+
+
+ asphalt
+
+
+
+
+
+ 114.5
+
+
+
+ asphalt
+
+
+
+
+
+ 115.0
+
+
+
+ asphalt
+
+
+
+
+
+ 115.8
+
+
+
+ asphalt
+
+
+
+
+
+ 115.8
+
+
+
+ asphalt
+
+
+
+
+
+ 116.0
+
+
+
+ asphalt
+
+
+
+
+
+ 115.8
+
+
+
+ asphalt
+
+
+
+
+
+ 115.5
+
+
+
+ asphalt
+
+
+
+
+
+ 114.5
+
+
+
+ asphalt
+
+
+
+
+
+ 112.5
+
+
+
+ asphalt
+
+
+
+
+
+ 110.8
+
+
+
+ asphalt
+
+
+
+
+
+ 109.0
+
+
+
+ asphalt
+
+
+
+
+
+ 106.3
+
+
+
+ asphalt
+
+
+
+
+
+ 104.3
+
+
+
+ asphalt
+
+
+
+
+
+ 104.0
+
+
+
+ asphalt
+
+
+
+
+
+ 103.8
+
+
+
+ asphalt
+
+
+
+
+
+ 103.3
+
+
+
+ asphalt
+
+
+
+
+
+ 103.5
+
+
+
+ asphalt
+
+
+
+
+
+ 103.8
+
+
+
+ asphalt
+
+
+
+
+
+ 104.8
+
+
+
+ asphalt
+
+
+
+
+
+ 105.8
+
+
+
+ asphalt
+
+
+
+
+
+ 106.8
+
+
+
+ asphalt
+
+
+
+
+
+ 107.8
+
+
+
+ asphalt
+
+
+
+
+
+ 108.5
+
+
+
+ asphalt
+
+
+
+
+
+ 109.3
+
+
+
+ asphalt
+
+
+
+
+
+ 110.0
+
+
+
+ asphalt
+
+
+
+
+
+ 110.5
+
+
+
+ asphalt
+
+
+
+
+
+ 110.8
+
+
+
+ asphalt
+
+
+
+
+
+ 111.8
+
+
+
+ asphalt
+
+
+
+
+
+ 112.8
+
+
+
+ asphalt
+
+
+
+
+
+ 113.3
+
+
+
+ asphalt
+
+
+
+
+
+ 113.5
+
+
+
+ asphalt
+
+
+
+
+
+ 113.5
+
+
+
+ asphalt
+
+
+
+
+
+ 113.8
+
+
+
+ asphalt
+
+
+
+
+
+ 114.8
+
+
+
+ asphalt
+
+
+
+
+
+ 115.8
+
+
+
+ asphalt
+
+
+
+
+
+ 118.5
+
+
+
+ asphalt
+
+
+
+
+
+ 119.5
+
+
+
+ asphalt
+
+
+
+
+
+ 121.3
+
+
+
+ asphalt
+
+
+
+
+
+ 122.0
+
+
+
+ asphalt
+
+
+
+
+
+ 122.8
+
+
+
+ asphalt
+
+
+
+
+
+ 123.5
+
+
+
+ asphalt
+
+
+
+
+
+ 126.3
+
+
+
+ asphalt
+
+
+
+
+
+ 128.0
+
+
+
+ asphalt
+
+
+
+
+
+ 129.0
+
+
+
+ asphalt
+
+
+
+
+
+ 130.0
+
+
+
+ asphalt
+
+
+
+
+
+ 130.8
+
+
+
+ asphalt
+
+
+
+
+
+ 131.8
+
+
+
+ asphalt
+
+
+
+
+
+ 132.3
+
+
+
+ asphalt
+
+
+
+
+
+ 132.8
+
+
+
+ asphalt
+
+
+
+
+
+ 135.8
+
+
+
+ asphalt
+
+
+
+
+
+ 135.5
+
+
+
+ asphalt
+
+
+
+
+
+ 132.5
+
+
+
+ asphalt
+
+
+
+
+
+ 134.0
+
+
+
+ asphalt
+
+
+
+
+
+ 136.8
+
+
+
+ asphalt
+
+
+
+
+
+ 137.5
+
+
+
+ asphalt
+
+
+
+
+
+ 137.3
+
+
+
+ asphalt
+
+
+
+
+
+ 137.5
+
+
+
+ asphalt
+
+
+
+
+
+ 137.3
+
+
+
+ asphalt
+
+
+
+
+
+ 134.8
+
+
+
+ asphalt
+
+
+
+
+
+ 132.3
+
+
+
+ asphalt
+
+
+
+
+
+ 129.5
+
+
+
+ cobblestone
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/data/with_temp.gpx b/gpx-rs/data/with_temp.gpx
new file mode 100644
index 000000000..b827235c6
--- /dev/null
+++ b/gpx-rs/data/with_temp.gpx
@@ -0,0 +1,660 @@
+
+
+
+ with_temp
+
+ gpx.studio
+
+
+
+
+ with_temp
+ Cycling
+
+
+ 109.0
+
+
+ 21
+
+
+
+
+ 110.8
+
+
+ 21
+
+
+
+
+ 110.3
+
+
+ 21
+
+
+
+
+ 110.0
+
+
+ 21
+
+
+
+
+ 110.3
+
+
+ 21
+
+
+
+
+ 109.3
+
+
+ 21
+
+
+
+
+ 107.0
+
+
+ 21
+
+
+
+
+ 106.0
+
+
+ 21
+
+
+
+
+ 108.5
+
+
+ 21
+
+
+
+
+ 109.8
+
+
+ 21
+
+
+
+
+ 110.8
+
+
+ 21
+
+
+
+
+ 112.0
+
+
+ 21
+
+
+
+
+ 112.8
+
+
+ 21
+
+
+
+
+ 113.5
+
+
+ 21
+
+
+
+
+ 114.3
+
+
+ 21
+
+
+
+
+ 115.3
+
+
+ 21
+
+
+
+
+ 114.8
+
+
+ 21
+
+
+
+
+ 114.3
+
+
+ 21
+
+
+
+
+ 114.3
+
+
+ 21
+
+
+
+
+ 114.5
+
+
+ 21
+
+
+
+
+ 115.0
+
+
+ 21
+
+
+
+
+ 115.8
+
+
+ 21
+
+
+
+
+ 115.8
+
+
+ 21
+
+
+
+
+ 116.0
+
+
+ 21
+
+
+
+
+ 115.8
+
+
+ 21
+
+
+
+
+ 115.5
+
+
+ 21
+
+
+
+
+ 114.5
+
+
+ 21
+
+
+
+
+ 112.5
+
+
+ 21
+
+
+
+
+ 110.8
+
+
+ 21
+
+
+
+
+ 109.0
+
+
+ 21
+
+
+
+
+ 106.3
+
+
+ 21
+
+
+
+
+ 104.3
+
+
+ 21
+
+
+
+
+ 104.0
+
+
+ 21
+
+
+
+
+ 103.8
+
+
+ 21
+
+
+
+
+ 103.3
+
+
+ 21
+
+
+
+
+ 103.5
+
+
+ 21
+
+
+
+
+ 103.8
+
+
+ 21
+
+
+
+
+ 104.8
+
+
+ 21
+
+
+
+
+ 105.8
+
+
+ 21
+
+
+
+
+ 106.8
+
+
+ 21
+
+
+
+
+ 107.8
+
+
+ 21
+
+
+
+
+ 108.5
+
+
+ 21
+
+
+
+
+ 109.3
+
+
+ 21
+
+
+
+
+ 110.0
+
+
+ 21
+
+
+
+
+ 110.5
+
+
+ 21
+
+
+
+
+ 110.8
+
+
+ 21
+
+
+
+
+ 111.8
+
+
+ 21
+
+
+
+
+ 112.8
+
+
+ 21
+
+
+
+
+ 113.3
+
+
+ 21
+
+
+
+
+ 113.5
+
+
+ 21
+
+
+
+
+ 113.5
+
+
+ 21
+
+
+
+
+ 113.8
+
+
+ 21
+
+
+
+
+ 114.8
+
+
+ 21
+
+
+
+
+ 115.8
+
+
+ 21
+
+
+
+
+ 118.5
+
+
+ 21
+
+
+
+
+ 119.5
+
+
+ 21
+
+
+
+
+ 121.3
+
+
+ 21
+
+
+
+
+ 122.0
+
+
+ 21
+
+
+
+
+ 122.8
+
+
+ 21
+
+
+
+
+ 123.5
+
+
+ 21
+
+
+
+
+ 126.3
+
+
+ 21
+
+
+
+
+ 128.0
+
+
+ 21
+
+
+
+
+ 129.0
+
+
+ 21
+
+
+
+
+ 130.0
+
+
+ 21
+
+
+
+
+ 130.8
+
+
+ 21
+
+
+
+
+ 131.8
+
+
+ 21
+
+
+
+
+ 132.3
+
+
+ 21
+
+
+
+
+ 132.8
+
+
+ 21
+
+
+
+
+ 135.8
+
+
+ 21
+
+
+
+
+ 135.5
+
+
+ 21
+
+
+
+
+ 132.5
+
+
+ 21
+
+
+
+
+ 134.0
+
+
+ 21
+
+
+
+
+ 136.8
+
+
+ 21
+
+
+
+
+ 137.5
+
+
+ 21
+
+
+
+
+ 137.3
+
+
+ 21
+
+
+
+
+ 137.5
+
+
+ 21
+
+
+
+
+ 137.3
+
+
+ 21
+
+
+
+
+ 134.8
+
+
+ 21
+
+
+
+
+ 132.3
+
+
+ 21
+
+
+
+
+ 129.5
+
+
+ 22
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/data/with_time.gpx b/gpx-rs/data/with_time.gpx
new file mode 100644
index 000000000..f39d90ad3
--- /dev/null
+++ b/gpx-rs/data/with_time.gpx
@@ -0,0 +1,340 @@
+
+
+
+ with_time
+
+ gpx.studio
+
+
+
+
+ with_time
+ Cycling
+
+
+ 109.0
+
+
+
+ 110.8
+
+
+
+ 110.3
+
+
+
+ 110.0
+
+
+
+ 110.3
+
+
+
+ 109.3
+
+
+
+ 107.0
+
+
+
+ 106.0
+
+
+
+ 108.5
+
+
+
+ 109.8
+
+
+
+ 110.8
+
+
+
+ 112.0
+
+
+
+ 112.8
+
+
+
+ 113.5
+
+
+
+ 114.3
+
+
+
+ 115.3
+
+
+
+ 114.8
+
+
+
+ 114.3
+
+
+
+ 114.3
+
+
+
+ 114.5
+
+
+
+ 115.0
+
+
+
+ 115.8
+
+
+
+ 115.8
+
+
+
+ 116.0
+
+
+
+ 115.8
+
+
+
+ 115.5
+
+
+
+ 114.5
+
+
+
+ 112.5
+
+
+
+ 110.8
+
+
+
+ 109.0
+
+
+
+ 106.3
+
+
+
+ 104.3
+
+
+
+ 104.0
+
+
+
+ 103.8
+
+
+
+ 103.3
+
+
+
+ 103.5
+
+
+
+ 103.8
+
+
+
+ 104.8
+
+
+
+ 105.8
+
+
+
+ 106.8
+
+
+
+ 107.8
+
+
+
+ 108.5
+
+
+
+ 109.3
+
+
+
+ 110.0
+
+
+
+ 110.5
+
+
+
+ 110.8
+
+
+
+ 111.8
+
+
+
+ 112.8
+
+
+
+ 113.3
+
+
+
+ 113.5
+
+
+
+ 113.5
+
+
+
+ 113.8
+
+
+
+ 114.8
+
+
+
+ 115.8
+
+
+
+ 118.5
+
+
+
+ 119.5
+
+
+
+ 121.3
+
+
+
+ 122.0
+
+
+
+ 122.8
+
+
+
+ 123.5
+
+
+
+ 126.3
+
+
+
+ 128.0
+
+
+
+ 129.0
+
+
+
+ 130.0
+
+
+
+ 130.8
+
+
+
+ 131.8
+
+
+
+ 132.3
+
+
+
+ 132.8
+
+
+
+ 135.8
+
+
+
+ 135.5
+
+
+
+ 132.5
+
+
+
+ 134.0
+
+
+
+ 136.8
+
+
+
+ 137.5
+
+
+
+ 137.3
+
+
+
+ 137.5
+
+
+
+ 137.3
+
+
+
+ 134.8
+
+
+
+ 132.3
+
+
+
+ 129.5
+
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/data/with_tracks.gpx b/gpx-rs/data/with_tracks.gpx
new file mode 100644
index 000000000..937b53e55
--- /dev/null
+++ b/gpx-rs/data/with_tracks.gpx
@@ -0,0 +1,257 @@
+
+
+
+ with_tracks
+
+ gpx.studio
+
+
+
+
+ track 1
+ Cycling
+
+
+ 109.0
+
+
+ 110.8
+
+
+ 110.3
+
+
+ 110.0
+
+
+ 110.3
+
+
+ 109.3
+
+
+ 107.0
+
+
+ 106.0
+
+
+ 108.5
+
+
+ 109.8
+
+
+ 110.8
+
+
+ 112.0
+
+
+ 112.8
+
+
+ 113.5
+
+
+ 114.3
+
+
+ 115.3
+
+
+ 114.8
+
+
+ 114.3
+
+
+ 114.3
+
+
+ 114.5
+
+
+ 115.0
+
+
+ 115.8
+
+
+ 115.8
+
+
+ 116.0
+
+
+ 115.8
+
+
+ 115.5
+
+
+ 114.5
+
+
+ 112.5
+
+
+ 110.8
+
+
+ 109.0
+
+
+ 106.3
+
+
+ 104.3
+
+
+ 104.0
+
+
+ 103.8
+
+
+ 103.3
+
+
+ 103.5
+
+
+ 103.8
+
+
+ 104.8
+
+
+ 105.8
+
+
+ 106.8
+
+
+ 107.8
+
+
+ 108.5
+
+
+ 109.3
+
+
+ 110.0
+
+
+ 110.5
+
+
+ 110.8
+
+
+ 111.8
+
+
+ 112.8
+
+
+ 113.3
+
+
+
+
+ track 2
+ Cycling
+
+
+ 115.5
+
+
+ 115.8
+
+
+ 118.5
+
+
+ 119.5
+
+
+ 121.3
+
+
+ 122.0
+
+
+ 122.8
+
+
+ 123.5
+
+
+ 126.3
+
+
+ 128.0
+
+
+ 129.0
+
+
+ 130.0
+
+
+ 130.8
+
+
+ 131.8
+
+
+ 132.3
+
+
+ 132.8
+
+
+ 135.8
+
+
+ 135.5
+
+
+ 132.5
+
+
+ 134.0
+
+
+ 136.8
+
+
+ 137.5
+
+
+ 137.3
+
+
+ 137.5
+
+
+ 137.3
+
+
+ 134.8
+
+
+ 132.3
+
+
+ 129.5
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/data/with_tracks_and_segments.gpx b/gpx-rs/data/with_tracks_and_segments.gpx
new file mode 100644
index 000000000..f10e720a9
--- /dev/null
+++ b/gpx-rs/data/with_tracks_and_segments.gpx
@@ -0,0 +1,346 @@
+
+
+
+ with_tracks_and_segments
+
+ gpx.studio
+
+
+
+
+ track 1
+ Running
+
+
+ 109.0
+
+
+
+ 110.8
+
+
+
+ 110.3
+
+
+
+ 110.0
+
+
+
+ 110.3
+
+
+
+ 109.3
+
+
+
+ 107.0
+
+
+
+ 106.0
+
+
+
+ 108.5
+
+
+
+ 109.8
+
+
+
+ 110.8
+
+
+
+ 112.0
+
+
+
+ 112.8
+
+
+
+ 113.5
+
+
+
+ 114.3
+
+
+
+ 115.3
+
+
+
+
+
+ 115.0
+
+
+
+ 114.8
+
+
+
+ 114.3
+
+
+
+ 114.3
+
+
+
+ 114.5
+
+
+
+ 115.0
+
+
+
+ 115.8
+
+
+
+ 115.8
+
+
+
+ 116.0
+
+
+
+ 115.8
+
+
+
+ 115.5
+
+
+
+ 114.5
+
+
+
+ 112.5
+
+
+
+ 110.8
+
+
+
+ 109.0
+
+
+
+ 106.3
+
+
+
+ 104.3
+
+
+
+ 104.0
+
+
+
+ 103.8
+
+
+
+ 103.3
+
+
+
+ 103.5
+
+
+
+ 103.8
+
+
+
+ 104.8
+
+
+
+ 105.8
+
+
+
+ 106.8
+
+
+
+ 107.8
+
+
+
+ 108.5
+
+
+
+ 109.3
+
+
+
+ 110.0
+
+
+
+ 110.5
+
+
+
+ 110.8
+
+
+
+ 111.8
+
+
+
+ 112.8
+
+
+
+ 113.3
+
+
+
+
+
+ track 2
+ Running
+
+
+ 115.5
+
+
+
+ 115.8
+
+
+
+ 118.5
+
+
+
+ 119.5
+
+
+
+ 121.3
+
+
+
+ 122.0
+
+
+
+ 122.8
+
+
+
+ 123.5
+
+
+
+ 126.3
+
+
+
+ 128.0
+
+
+
+ 129.0
+
+
+
+ 130.0
+
+
+
+ 130.8
+
+
+
+ 131.8
+
+
+
+ 132.3
+
+
+
+ 132.8
+
+
+
+ 135.8
+
+
+
+ 135.5
+
+
+
+ 132.5
+
+
+
+
+
+ 133.3
+
+
+
+ 134.0
+
+
+
+ 136.8
+
+
+
+ 137.5
+
+
+
+ 137.3
+
+
+
+ 137.5
+
+
+
+ 137.3
+
+
+
+ 134.8
+
+
+
+ 132.3
+
+
+
+ 129.5
+
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/data/with_waypoint.gpx b/gpx-rs/data/with_waypoint.gpx
new file mode 100644
index 000000000..c908b0515
--- /dev/null
+++ b/gpx-rs/data/with_waypoint.gpx
@@ -0,0 +1,267 @@
+
+
+
+ with_waypoint
+
+ gpx.studio
+
+
+
+
+ 122.0
+ Waypoint
+ Comment
+ Description
+ Bike Trail
+
+
+ with_waypoint
+ Cycling
+
+
+ 109.0
+
+
+ 110.8
+
+
+ 110.3
+
+
+ 110.0
+
+
+ 110.3
+
+
+ 109.3
+
+
+ 107.0
+
+
+ 106.0
+
+
+ 108.5
+
+
+ 109.8
+
+
+ 110.8
+
+
+ 112.0
+
+
+ 112.8
+
+
+ 113.5
+
+
+ 114.3
+
+
+ 115.3
+
+
+ 114.8
+
+
+ 114.3
+
+
+ 114.3
+
+
+ 114.5
+
+
+ 115.0
+
+
+ 115.8
+
+
+ 115.8
+
+
+ 116.0
+
+
+ 115.8
+
+
+ 115.5
+
+
+ 114.5
+
+
+ 112.5
+
+
+ 110.8
+
+
+ 109.0
+
+
+ 106.3
+
+
+ 104.3
+
+
+ 104.0
+
+
+ 103.8
+
+
+ 103.3
+
+
+ 103.5
+
+
+ 103.8
+
+
+ 104.8
+
+
+ 105.8
+
+
+ 106.8
+
+
+ 107.8
+
+
+ 108.5
+
+
+ 109.3
+
+
+ 110.0
+
+
+ 110.5
+
+
+ 110.8
+
+
+ 111.8
+
+
+ 112.8
+
+
+ 113.3
+
+
+ 113.5
+
+
+ 113.5
+
+
+ 113.8
+
+
+ 114.8
+
+
+ 115.8
+
+
+ 118.5
+
+
+ 119.5
+
+
+ 121.3
+
+
+ 122.0
+
+
+ 122.8
+
+
+ 123.5
+
+
+ 126.3
+
+
+ 128.0
+
+
+ 129.0
+
+
+ 130.0
+
+
+ 130.8
+
+
+ 131.8
+
+
+ 132.3
+
+
+ 132.8
+
+
+ 135.8
+
+
+ 135.5
+
+
+ 132.5
+
+
+ 134.0
+
+
+ 136.8
+
+
+ 137.5
+
+
+ 137.3
+
+
+ 137.5
+
+
+ 137.3
+
+
+ 134.8
+
+
+ 132.3
+
+
+ 129.5
+
+
+
+
\ No newline at end of file
diff --git a/gpx-rs/src/actions/mod.rs b/gpx-rs/src/actions/mod.rs
new file mode 100644
index 000000000..4f42021da
--- /dev/null
+++ b/gpx-rs/src/actions/mod.rs
@@ -0,0 +1,3 @@
+mod parse;
+
+pub use parse::*;
diff --git a/gpx-rs/src/actions/parse.rs b/gpx-rs/src/actions/parse.rs
new file mode 100644
index 000000000..143b5d0c0
--- /dev/null
+++ b/gpx-rs/src/actions/parse.rs
@@ -0,0 +1,231 @@
+use crate::gpx::{Author, GPXFile, Link, Track, TrackPoint, TrackSegment};
+use quick_xml::Error;
+use quick_xml::events::Event;
+use quick_xml::reader::Reader;
+
+enum GPXElement {
+ METADATA,
+ NAME,
+ COMMENT,
+ DESCRIPTION,
+ SOURCE,
+ AUTHOR(Author),
+ LINK(Link),
+ TEXT,
+ TRACK(Track),
+ SEGMENT(TrackSegment),
+ TRACKPOINT(TrackPoint),
+ ELEVATION,
+}
+
+pub fn parse(data: &[u8]) -> Result {
+ let mut reader = Reader::from_reader(data);
+ let mut buf = vec![];
+ let mut gpx = GPXFile::default();
+ let mut stack: Vec = vec![];
+ loop {
+ match reader.read_event_into(&mut buf) {
+ Ok(Event::Start(e)) => match e.name().as_ref() {
+ "metadata" => stack.push(GPXElement::METADATA),
+ "name" => stack.push(GPXElement::NAME),
+ "cmt" => stack.push(GPXElement::COMMENT),
+ "desc" => stack.push(GPXElement::DESCRIPTION),
+ "src" => stack.push(GPXElement::SOURCE),
+ "author" => stack.push(GPXElement::AUTHOR(Author::default())),
+ "link" => {
+ let mut link = Link::default();
+ for attr in e.attributes() {
+ if let Ok(attr) = attr {
+ if attr.key.as_ref() == "href" {
+ link.href = attr.value.to_string();
+ }
+ }
+ }
+ stack.push(GPXElement::LINK(link));
+ }
+ "text" => stack.push(GPXElement::TEXT),
+ "trk" => stack.push(GPXElement::TRACK(Track::default())),
+ "trkseg" => stack.push(GPXElement::SEGMENT(TrackSegment::default())),
+ "trkpt" => {
+ let mut trkpt = TrackPoint::default();
+ for attr in 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));
+ }
+ "ele" => stack.push(GPXElement::ELEVATION),
+ _ => println!("{:?}", e),
+ },
+ Ok(Event::End(e)) => match e.name().as_ref() {
+ "metadata" => {
+ stack.pop();
+ }
+ "author" => {
+ if let Some(GPXElement::AUTHOR(author)) = stack.pop() {
+ gpx.info.author = Some(author);
+ }
+ }
+ "link" => {
+ if let Some(GPXElement::LINK(link)) = stack.pop() {
+ match stack.last_mut() {
+ Some(GPXElement::AUTHOR(author)) => {
+ author.link = Some(link);
+ }
+ Some(GPXElement::TRACK(trk)) => {
+ trk.info.link = Some(link);
+ }
+ _ => (),
+ }
+ }
+ }
+ "trk" => {
+ if let Some(GPXElement::TRACK(trk)) = stack.pop() {
+ gpx.trk.push(trk);
+ }
+ }
+ "trkseg" => {
+ if let Some(GPXElement::SEGMENT(trkseg)) = stack.pop() {
+ if let Some(GPXElement::TRACK(trk)) = stack.last_mut() {
+ trk.trkseg.push(trkseg);
+ }
+ }
+ }
+ "trkpt" => {
+ if let Some(GPXElement::TRACKPOINT(trkpt)) = stack.pop() {
+ if let Some(GPXElement::SEGMENT(trkseg)) = stack.last_mut() {
+ trkseg.append(trkpt);
+ }
+ }
+ }
+ _ => (),
+ },
+ Ok(Event::Text(e)) => match stack.last_mut() {
+ Some(GPXElement::NAME) => {
+ stack.pop();
+ match stack.last_mut() {
+ Some(GPXElement::METADATA) => {
+ gpx.info.name = e.to_string();
+ }
+ Some(GPXElement::AUTHOR(author)) => {
+ author.name = Some(e.to_string());
+ }
+ Some(GPXElement::TRACK(trk)) => {
+ trk.info.name = Some(e.to_string());
+ }
+ _ => (),
+ }
+ }
+ Some(GPXElement::COMMENT) => {
+ stack.pop();
+ match stack.last_mut() {
+ Some(GPXElement::TRACK(trk)) => {
+ trk.info.cmt = Some(e.to_string());
+ }
+ _ => (),
+ }
+ }
+ Some(GPXElement::DESCRIPTION) => {
+ stack.pop();
+ match stack.last_mut() {
+ Some(GPXElement::METADATA) => {
+ gpx.info.desc = Some(e.to_string());
+ }
+ Some(GPXElement::TRACK(trk)) => {
+ trk.info.desc = Some(e.to_string());
+ }
+ _ => (),
+ }
+ }
+ Some(GPXElement::SOURCE) => {
+ stack.pop();
+ match stack.last_mut() {
+ Some(GPXElement::TRACK(trk)) => {
+ trk.info.src = Some(e.to_string());
+ }
+ _ => (),
+ }
+ }
+ Some(GPXElement::TEXT) => {
+ stack.pop();
+ if let Some(GPXElement::LINK(link)) = stack.last_mut() {
+ link.text = Some(e.to_string());
+ }
+ }
+ Some(GPXElement::ELEVATION) => {
+ stack.pop();
+ if let Some(GPXElement::TRACKPOINT(trkpt)) = stack.last_mut() {
+ trkpt.ele = e.parse().unwrap_or_default();
+ }
+ }
+ _ => (),
+ },
+ Ok(Event::Eof) => break,
+ Err(e) => return Err(e),
+ _ => (),
+ }
+ buf.clear();
+ }
+ Ok(gpx)
+}
+
+#[cfg(test)]
+mod tests {
+ use std::{fs::File, io::Read};
+
+ use super::*;
+
+ #[test]
+ fn test_parse() {
+ let mut f = File::open("data/simple.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.info.name, "simple");
+ assert!(gpx.info.desc.is_some_and(|d| d == "description"));
+ assert!(gpx.info.author.is_some());
+ let author = gpx.info.author.as_ref().unwrap();
+ assert!(author.name.as_ref().is_some_and(|n| n == "gpx.studio"));
+ assert!(author.link.is_some());
+ let link = author.link.as_ref().unwrap();
+ assert_eq!(link.href, "https://gpx.studio");
+ assert!(link.text.as_ref().is_some_and(|t| t == "link text"));
+
+ assert_eq!(gpx.trk.len(), 1);
+ let trk = &gpx.trk[0];
+ assert!(trk.info.name.as_ref().is_some_and(|n| n == "track name"));
+ assert!(trk.info.cmt.as_ref().is_some_and(|c| c == "track comment"));
+ assert!(
+ trk.info
+ .desc
+ .as_ref()
+ .is_some_and(|n| n == "track description")
+ );
+ assert!(trk.info.src.as_ref().is_some_and(|n| n == "track source"));
+ assert!(trk.info.link.is_some());
+ let link = trk.info.link.as_ref().unwrap();
+ assert_eq!(link.href, "https://gpx.studio");
+ assert!(link.text.as_ref().is_some_and(|t| t == "track link text"));
+
+ assert_eq!(gpx.trk[0].trkseg.len(), 1);
+ let trkseg = &gpx.trk[0].trkseg[0];
+ assert_eq!(trkseg.chunks.len(), 1);
+ let chunk = trkseg.chunks[0].borrow();
+ assert_eq!(chunk.trkpt.len(), 80);
+ let trkpt = &chunk.trkpt[0];
+ assert_eq!(trkpt.coordinates.lat, 50.790867);
+ assert_eq!(trkpt.coordinates.lng, 4.404968);
+ assert_eq!(trkpt.ele, 109.0);
+ }
+}
diff --git a/gpx-rs/src/controller.rs b/gpx-rs/src/controller.rs
index f04056d70..3c2783ddc 100644
--- a/gpx-rs/src/controller.rs
+++ b/gpx-rs/src/controller.rs
@@ -2,7 +2,7 @@ use std::rc::Rc;
use wasm_bindgen::prelude::*;
-use crate::{stack::Stack, types::GPXFile};
+use crate::stack::Stack;
#[wasm_bindgen]
pub struct Controller {
@@ -18,10 +18,10 @@ impl Controller {
}
}
- #[wasm_bindgen]
- pub fn create_file(&mut self, name: &str) {
- let id = self.stack.get_new_file_id();
- let file = Rc::new(GPXFile::new(id, name));
- self.stack.update(&[file]);
- }
+ // #[wasm_bindgen]
+ // pub fn create_file(&mut self, name: &str) {
+ // let id = self.stack.get_new_file_id();
+ // let file = Rc::new(GPXFile::new(id, name));
+ // self.stack.update(&[file]);
+ // }
}
diff --git a/gpx-rs/src/gpx/common.rs b/gpx-rs/src/gpx/common.rs
new file mode 100644
index 000000000..6e1619c05
--- /dev/null
+++ b/gpx-rs/src/gpx/common.rs
@@ -0,0 +1,11 @@
+#[derive(Debug, Default)]
+pub struct Link {
+ pub href: String,
+ pub text: Option,
+}
+
+#[derive(Debug, Default)]
+pub struct LngLat {
+ pub lng: f64,
+ pub lat: f64,
+}
diff --git a/gpx-rs/src/gpx/file.rs b/gpx-rs/src/gpx/file.rs
new file mode 100644
index 000000000..6107fbcad
--- /dev/null
+++ b/gpx-rs/src/gpx/file.rs
@@ -0,0 +1,26 @@
+use std::rc::Rc;
+
+use crate::gpx::{Link, Track, WaypointChunk};
+
+#[derive(Debug, Default)]
+pub struct GPXFile {
+ pub info: GPXFileInfo,
+ pub trk: Vec