Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
497ac120ec | ||
|
|
a486016d96 | ||
|
|
cc5f5653ef | ||
|
|
20222c450d | ||
|
|
69049e1345 | ||
|
|
ed6264444f | ||
|
|
86f4fc3394 | ||
|
|
565589fc94 | ||
|
|
4ef92e5abd | ||
|
|
7f8751fa38 | ||
|
|
befcba00b4 | ||
|
|
26e4b637a2 | ||
|
|
75e3bc6f93 | ||
|
|
70bb125076 | ||
|
|
e0a4fc186a | ||
|
|
6a9d30e8ea | ||
|
|
1e6a12eeda | ||
|
|
31912da76f | ||
|
|
fe8896e870 | ||
|
|
c99517572e | ||
|
|
0b7f30a7c4 | ||
|
|
fcfaf043c4 | ||
|
|
0393a330a6 | ||
|
|
2fdb58bc7d | ||
|
|
c758bda1a9 | ||
|
|
88e301e2a2 | ||
|
|
161c664e08 | ||
|
|
a0408ec798 | ||
|
|
480d5586b9 | ||
|
|
7b49018593 | ||
|
|
4b447a9b9d | ||
|
|
443feb2bfa | ||
|
|
8710101a78 | ||
|
|
2c20148e64 | ||
|
|
ffc0e84788 | ||
|
|
2d2004e447 | ||
|
|
4a7cfc113d | ||
|
|
f03ad5a0e9 | ||
|
|
7f5b83f9d8 | ||
|
|
5a8f93e225 | ||
|
|
668b0f6b23 | ||
|
|
fc1eb5a408 | ||
|
|
561c7e22b3 | ||
|
|
ce067d4ff0 | ||
|
|
7361b54255 | ||
|
|
9e2334ca83 | ||
|
|
08d1f1d5e4 | ||
|
|
f3bf4f0096 | ||
|
|
b4094d0a5b | ||
|
|
36122b4ac5 | ||
|
|
dd9aba3adb | ||
|
|
bd40fbae74 | ||
|
|
690cbc49cc | ||
|
|
36b16ddeef | ||
|
|
16b8988fa7 | ||
|
|
40f97b7c35 | ||
|
|
54b3113480 | ||
|
|
7e9140492a | ||
|
|
79c0aed54f | ||
|
|
cb5a74de00 | ||
|
|
31f25f346a | ||
|
|
b3a11125a5 | ||
|
|
71cdc03da5 | ||
|
|
694e73a677 | ||
|
|
5aaacccef9 | ||
|
|
f2bf043900 | ||
|
|
ba251fe407 | ||
|
|
421aa9dc69 | ||
|
|
b4a7f1353b | ||
|
|
30de3c6db5 | ||
|
|
8aafa26238 | ||
|
|
5768391305 | ||
|
|
1d204bacf2 | ||
|
|
4d1d5d48c0 | ||
|
|
5a6321535e | ||
|
|
e077de9f48 | ||
|
|
7586f03998 | ||
|
|
af8c22dcda | ||
|
|
3dce5dc617 | ||
|
|
84b90e1026 | ||
|
|
d507586eed | ||
|
|
57afaedf83 | ||
|
|
48063b9066 | ||
|
|
452d356599 | ||
|
|
25eda8041e | ||
|
|
ae4d5356eb | ||
|
|
3343bb906e | ||
|
|
7b17900160 | ||
|
|
d5f1fe1c7b | ||
|
|
553f73f992 | ||
|
|
c8cedf2e2c | ||
|
|
a751817847 | ||
|
|
d1ef12db8d | ||
|
|
43d73edf29 | ||
|
|
5a0b8c376c | ||
|
|
9743fd460e | ||
|
|
f70f92a176 | ||
|
|
1a4175446c | ||
|
|
ed6dfab4c1 | ||
|
|
6a6e1105c0 | ||
|
|
1677fe254b | ||
|
|
02efe708c2 | ||
|
|
7dc834f506 | ||
|
|
57c4958ff2 | ||
|
|
03e59a8cce | ||
|
|
f3d18f09a0 | ||
|
|
c1dbd984e6 | ||
|
|
e4f227221d | ||
|
|
34139974aa | ||
|
|
408b2422e6 | ||
|
|
b59cb9e200 | ||
|
|
bd5cb65d0f | ||
|
|
4cfe487af0 | ||
|
|
4da2e39e32 | ||
|
|
5ff11a32c9 | ||
|
|
01a7ec916e | ||
|
|
dd94a7d613 | ||
|
|
089b88c62d | ||
|
|
9c6e03f4a8 | ||
|
|
2a4dfe010e | ||
|
|
f42a916c25 | ||
|
|
772b810fa8 | ||
|
|
4d4d10d5c2 | ||
|
|
0e4c7dbe64 | ||
|
|
a01ca79a82 | ||
|
|
c91baf7c83 | ||
|
|
5062de8ddf | ||
|
|
9ca46b9d35 | ||
|
|
7c2e24bbc4 |
@@ -1 +1 @@
|
|||||||
ko_fi: gpxstudio
|
open_collective: gpxstudio
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
[**gpx.studio**](https://gpx.studio) is an online tool for creating and editing GPX files.
|
[**gpx.studio**](https://gpx.studio) is an online tool for creating and editing GPX files.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
This repository contains the source code of the website.
|
This repository contains the source code of the website.
|
||||||
|
|
||||||
@@ -69,9 +69,10 @@ This project has been made possible thanks to the following open source projects
|
|||||||
- [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) — fast GPX file parsing
|
- [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) — fast GPX file parsing
|
||||||
- [SortableJS](https://github.com/SortableJS/Sortable) — creating a sortable file tree
|
- [SortableJS](https://github.com/SortableJS/Sortable) — creating a sortable file tree
|
||||||
- Mapping:
|
- Mapping:
|
||||||
- [MapLibre GL JS](https://github.com/maplibre/maplibre-gl-js) — beautiful and fast interactive maps
|
- [MapLibre GL JS](https://github.com/maplibre/maplibre-gl-js) — beautiful and fast interactive map rendering
|
||||||
- [brouter](https://github.com/abrensch/brouter) — routing engine
|
- [GraphHopper](https://github.com/graphhopper/graphhopper) — powerful routing engine
|
||||||
- [OpenStreetMap](https://www.openstreetmap.org) — map data used by most of the map layers, and by the routing engine
|
- [OpenStreetMap](https://www.openstreetmap.org) — open map data used by most of the map layers, and by the routing engine
|
||||||
|
- [Mapterhorn](https://github.com/mapterhorn/mapterhorn) — high-quality open terrain data used by some map layers (including for 3D), and by the routing engine
|
||||||
- Search:
|
- Search:
|
||||||
- [DocSearch](https://github.com/algolia/docsearch) — search engine for the documentation
|
- [DocSearch](https://github.com/algolia/docsearch) — search engine for the documentation
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
target/
|
||||||
|
pkg/
|
||||||
@@ -0,0 +1,367 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.20.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3eb0f42d6c360dc3f8a821f6bf2fdea7f72bfd36b3076eb0e6d1e9e0752fff4"
|
||||||
|
dependencies = [
|
||||||
|
"find-msvc-tools",
|
||||||
|
"shlex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
|
||||||
|
dependencies = [
|
||||||
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
|
"num-traits",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "find-msvc-tools"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-core"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-task"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-util"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-task",
|
||||||
|
"pin-project-lite",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"r-efi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gpx-rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"quick-xml",
|
||||||
|
"uuid",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.65"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.103"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"futures-util",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.189"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.106"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||||
|
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"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "r-efi"
|
||||||
|
version = "6.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slab"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.118"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "1.26.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2ef6dac1e96601b4fb3acccccff2139741fcb757cb9a36089bf5be91cfb285ce"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.126"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.126"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.126"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.126"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.62.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-link",
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.60.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.59.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
[package]
|
||||||
|
name = "gpx-rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
chrono = "0.4.45"
|
||||||
|
quick-xml = "0.42.0"
|
||||||
|
uuid = {version = "1.26.1", features = ["v4", "js"]}
|
||||||
|
wasm-bindgen = "0.2"
|
||||||
@@ -0,0 +1,274 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>simple</name>
|
||||||
|
<desc>description</desc>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio">
|
||||||
|
<text>link text</text>
|
||||||
|
</link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<name>track name</name>
|
||||||
|
<cmt>track comment</cmt>
|
||||||
|
<desc>track description</desc>
|
||||||
|
<src>track source</src>
|
||||||
|
<link href="https://gpx.studio">
|
||||||
|
<text>track link text</text>
|
||||||
|
</link>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78279" lon="4.406021">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782714" lon="4.406018">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782607" lon="4.406047">
|
||||||
|
<ele>113.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782405" lon="4.406194">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,660 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_cad</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<name>with_cad</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78279" lon="4.406021">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782714" lon="4.406018">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782607" lon="4.406047">
|
||||||
|
<ele>113.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782405" lon="4.406194">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>80</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:cad>90</gpxtpx:cad>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,660 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_hr</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<name>with_hr</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78279" lon="4.406021">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782714" lon="4.406018">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782607" lon="4.406047">
|
||||||
|
<ele>113.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782405" lon="4.406194">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>150</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:hr>160</gpxtpx:hr>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,500 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_power</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<name>with_power</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78279" lon="4.406021">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782714" lon="4.406018">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782607" lon="4.406047">
|
||||||
|
<ele>113.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782405" lon="4.406194">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>200</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<power>210</power>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,665 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
xmlns:gpxpx="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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_power</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<name>with_power</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78279" lon="4.406021">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782714" lon="4.406018">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782607" lon="4.406047">
|
||||||
|
<ele>113.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782405" lon="4.406194">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>200</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxpx:PowerExtension>
|
||||||
|
<gpxpx:PowerInWatts>210</gpxpx:PowerInWatts>
|
||||||
|
</gpxpx:PowerExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_routes</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<rte>
|
||||||
|
<name>route 1</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<rtept lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
</rtept>
|
||||||
|
</rte>
|
||||||
|
<rte>
|
||||||
|
<name>route 2</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<rtept lat="50.782212" lon="4.406377">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
</rtept>
|
||||||
|
<rtept lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
</rtept>
|
||||||
|
</rte>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_segments</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<name>with_segments</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.782212" lon="4.406377">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,267 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_style</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<name>with_style</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<extensions>
|
||||||
|
<gpx_style:line>
|
||||||
|
<gpx_style:color>2d3ee9</gpx_style:color>
|
||||||
|
<gpx_style:opacity>0.5</gpx_style:opacity>
|
||||||
|
<gpx_style:width>6</gpx_style:width>
|
||||||
|
</gpx_style:line>
|
||||||
|
</extensions>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78279" lon="4.406021">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782714" lon="4.406018">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782607" lon="4.406047">
|
||||||
|
<ele>113.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782405" lon="4.406194">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,820 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_surface</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<name>with_surface</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78279" lon="4.406021">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782714" lon="4.406018">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782607" lon="4.406047">
|
||||||
|
<ele>113.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782405" lon="4.406194">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>asphalt</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:Extensions>
|
||||||
|
<surface>cobblestone</surface>
|
||||||
|
</gpxtpx:Extensions>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,660 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_temp</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<name>with_temp</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78279" lon="4.406021">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782714" lon="4.406018">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782607" lon="4.406047">
|
||||||
|
<ele>113.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782405" lon="4.406194">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>21</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
<extensions>
|
||||||
|
<gpxtpx:TrackPointExtension>
|
||||||
|
<gpxtpx:atemp>22</gpxtpx:atemp>
|
||||||
|
</gpxtpx:TrackPointExtension>
|
||||||
|
</extensions>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,340 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_time</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<name>with_time</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<time>2023-12-31T23:00:00.000Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<time>2023-12-31T23:00:03.180Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<time>2023-12-31T23:00:11.254Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<time>2023-12-31T23:00:14.795Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<time>2023-12-31T23:00:17.957Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<time>2023-12-31T23:00:21.759Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
<time>2023-12-31T23:00:29.948Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
<time>2023-12-31T23:00:36.098Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<time>2023-12-31T23:00:42.396Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
<time>2023-12-31T23:00:45.636Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<time>2023-12-31T23:00:48.827Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
<time>2023-12-31T23:00:55.249Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<time>2023-12-31T23:01:00.794Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<time>2023-12-31T23:01:03.708Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<time>2023-12-31T23:01:06.542Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
<time>2023-12-31T23:01:11.014Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<time>2023-12-31T23:01:14.108Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<time>2023-12-31T23:01:17.026Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<time>2023-12-31T23:01:19.742Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<time>2023-12-31T23:01:28.110Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
<time>2023-12-31T23:01:31.328Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<time>2023-12-31T23:01:35.306Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<time>2023-12-31T23:01:36.830Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
<time>2023-12-31T23:01:38.701Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<time>2023-12-31T23:01:40.022Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
<time>2023-12-31T23:01:41.920Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<time>2023-12-31T23:01:48.333Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
<time>2023-12-31T23:01:52.195Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<time>2023-12-31T23:01:55.766Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<time>2023-12-31T23:01:58.740Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
<time>2023-12-31T23:02:04.091Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
<time>2023-12-31T23:02:12.713Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
<time>2023-12-31T23:02:14.875Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<time>2023-12-31T23:02:16.638Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
<time>2023-12-31T23:02:18.384Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
<time>2023-12-31T23:02:25.735Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<time>2023-12-31T23:02:27.404Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
<time>2023-12-31T23:02:29.642Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
<time>2023-12-31T23:02:31.271Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
<time>2023-12-31T23:02:32.974Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
<time>2023-12-31T23:02:34.725Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<time>2023-12-31T23:02:36.057Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<time>2023-12-31T23:02:37.639Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<time>2023-12-31T23:02:39.280Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
<time>2023-12-31T23:02:41.205Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<time>2023-12-31T23:02:43.731Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
<time>2023-12-31T23:02:54.830Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<time>2023-12-31T23:02:59.232Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
<time>2023-12-31T23:03:01.951Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78279" lon="4.406021">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<time>2023-12-31T23:03:03.598Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782714" lon="4.406018">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<time>2023-12-31T23:03:05.119Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782607" lon="4.406047">
|
||||||
|
<ele>113.8</ele>
|
||||||
|
<time>2023-12-31T23:03:07.291Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782405" lon="4.406194">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<time>2023-12-31T23:03:11.741Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<time>2023-12-31T23:03:17.114Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
<time>2023-12-31T23:03:28.573Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
<time>2023-12-31T23:03:32.796Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
<time>2023-12-31T23:03:38.750Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
<time>2023-12-31T23:03:41.922Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
<time>2023-12-31T23:03:45.133Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
<time>2023-12-31T23:03:48.867Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
<time>2023-12-31T23:03:56.536Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
<time>2023-12-31T23:04:00.561Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
<time>2023-12-31T23:04:03.346Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
<time>2023-12-31T23:04:06.761Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
<time>2023-12-31T23:04:14.339Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
<time>2023-12-31T23:04:23.699Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<time>2023-12-31T23:04:27.973Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
<time>2023-12-31T23:04:32.307Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
<time>2023-12-31T23:04:44.408Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
<time>2023-12-31T23:04:48.146Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
<time>2023-12-31T23:05:00.532Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
<time>2023-12-31T23:05:11.852Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
<time>2023-12-31T23:05:23.300Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<time>2023-12-31T23:05:41.944Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<time>2023-12-31T23:05:49.538Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<time>2023-12-31T23:05:57.109Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<time>2023-12-31T23:06:03.116Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
<time>2023-12-31T23:06:14.336Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<time>2023-12-31T23:06:26.353Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
<time>2023-12-31T23:06:40.567Z</time>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,257 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_tracks</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<name>track 1</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
<trk>
|
||||||
|
<name>track 2</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.782212" lon="4.406377">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,346 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_tracks_and_segments</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<trk>
|
||||||
|
<name>track 1</name>
|
||||||
|
<type>Running</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<time>2023-12-31T23:00:00.000Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<time>2023-12-31T23:00:03.180Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<time>2023-12-31T23:00:11.254Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<time>2023-12-31T23:00:14.795Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
<time>2023-12-31T23:00:17.957Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<time>2023-12-31T23:00:21.759Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
<time>2023-12-31T23:00:29.948Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
<time>2023-12-31T23:00:36.098Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<time>2023-12-31T23:00:42.396Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
<time>2023-12-31T23:00:45.636Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<time>2023-12-31T23:00:48.827Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
<time>2023-12-31T23:00:55.249Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<time>2023-12-31T23:01:00.794Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
<time>2023-12-31T23:01:03.708Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<time>2023-12-31T23:01:06.542Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
<time>2023-12-31T23:01:11.014Z</time>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.78727108169855" lon="4.406133681127736">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
<time>2023-12-31T23:01:14.708Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
<time>2023-12-31T23:01:15.462Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<time>2023-12-31T23:01:18.380Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
<time>2023-12-31T23:01:21.096Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<time>2023-12-31T23:01:29.464Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
<time>2023-12-31T23:01:32.682Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<time>2023-12-31T23:01:36.660Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<time>2023-12-31T23:01:38.184Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
<time>2023-12-31T23:01:40.055Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<time>2023-12-31T23:01:41.376Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
<time>2023-12-31T23:01:43.274Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
<time>2023-12-31T23:01:49.687Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
<time>2023-12-31T23:01:53.549Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<time>2023-12-31T23:01:57.120Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
<time>2023-12-31T23:02:00.094Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
<time>2023-12-31T23:02:05.445Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
<time>2023-12-31T23:02:14.067Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
<time>2023-12-31T23:02:16.229Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<time>2023-12-31T23:02:17.992Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
<time>2023-12-31T23:02:19.738Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
<time>2023-12-31T23:02:27.089Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
<time>2023-12-31T23:02:28.758Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
<time>2023-12-31T23:02:30.996Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
<time>2023-12-31T23:02:32.625Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
<time>2023-12-31T23:02:34.328Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
<time>2023-12-31T23:02:36.079Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
<time>2023-12-31T23:02:37.411Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
<time>2023-12-31T23:02:38.993Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
<time>2023-12-31T23:02:40.634Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
<time>2023-12-31T23:02:42.559Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
<time>2023-12-31T23:02:45.085Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
<time>2023-12-31T23:02:56.184Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
<time>2023-12-31T23:03:00.586Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
<time>2023-12-31T23:03:03.305Z</time>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
<trk>
|
||||||
|
<name>track 2</name>
|
||||||
|
<type>Running</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.782212" lon="4.406377">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
<time>2023-12-31T23:03:17.151Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
<time>2023-12-31T23:03:18.020Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
<time>2023-12-31T23:03:29.479Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
<time>2023-12-31T23:03:33.702Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
<time>2023-12-31T23:03:39.656Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
<time>2023-12-31T23:03:42.828Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
<time>2023-12-31T23:03:46.039Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
<time>2023-12-31T23:03:49.773Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
<time>2023-12-31T23:03:57.442Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
<time>2023-12-31T23:04:01.467Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
<time>2023-12-31T23:04:04.252Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
<time>2023-12-31T23:04:07.667Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
<time>2023-12-31T23:04:15.245Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
<time>2023-12-31T23:04:24.605Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<time>2023-12-31T23:04:28.879Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
<time>2023-12-31T23:04:33.213Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
<time>2023-12-31T23:04:45.314Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
<time>2023-12-31T23:04:49.052Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
<time>2023-12-31T23:05:01.438Z</time>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.77906316558724" lon="4.412547477922485">
|
||||||
|
<ele>133.3</ele>
|
||||||
|
<time>2023-12-31T23:05:03.324Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
<time>2023-12-31T23:05:12.804Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
<time>2023-12-31T23:05:24.252Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<time>2023-12-31T23:05:42.896Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<time>2023-12-31T23:05:50.490Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
<time>2023-12-31T23:05:58.061Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
<time>2023-12-31T23:06:04.068Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
<time>2023-12-31T23:06:15.288Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
<time>2023-12-31T23:06:27.305Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
<time>2023-12-31T23:06:41.519Z</time>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,276 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
|
||||||
|
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">
|
||||||
|
<metadata>
|
||||||
|
<name>with_waypoint</name>
|
||||||
|
<author>
|
||||||
|
<name>gpx.studio</name>
|
||||||
|
<link href="https://gpx.studio"></link>
|
||||||
|
</author>
|
||||||
|
</metadata>
|
||||||
|
<wpt lat="50.7836710064975" lon="4.410764082658738">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
<name>waypoint name</name>
|
||||||
|
<cmt>waypoint comment</cmt>
|
||||||
|
<desc>waypoint description</desc>
|
||||||
|
<link href="https://gpx.studio">
|
||||||
|
<text>waypoint link text</text>
|
||||||
|
</link>
|
||||||
|
<sym>Bike Trail</sym>
|
||||||
|
<type>Bike Trail</type>
|
||||||
|
</wpt>
|
||||||
|
<trk>
|
||||||
|
<name>with_waypoint</name>
|
||||||
|
<type>Cycling</type>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="50.790867" lon="4.404968">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790714" lon="4.405036">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790336" lon="4.405259">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790165" lon="4.405331">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.790008" lon="4.405359">
|
||||||
|
<ele>110.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789818" lon="4.405359">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789409" lon="4.40534">
|
||||||
|
<ele>107.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.789105" lon="4.405411">
|
||||||
|
<ele>106.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788799" lon="4.405527">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.788645" lon="4.405606">
|
||||||
|
<ele>109.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.7885" lon="4.405711">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78822" lon="4.405959">
|
||||||
|
<ele>112.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787956" lon="4.406092">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787814" lon="4.406143">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787674" lon="4.406177">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787451" lon="4.406199">
|
||||||
|
<ele>115.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787297" lon="4.406177">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78716" lon="4.406098">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.787045" lon="4.405984">
|
||||||
|
<ele>114.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786683" lon="4.405653">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786538" lon="4.405543">
|
||||||
|
<ele>115.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78635" lon="4.405441">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786275" lon="4.40542">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786182" lon="4.405435">
|
||||||
|
<ele>116.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786121" lon="4.405475">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.786042" lon="4.405558">
|
||||||
|
<ele>115.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785821" lon="4.405925">
|
||||||
|
<ele>114.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785672" lon="4.406119">
|
||||||
|
<ele>112.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785516" lon="4.406256">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785384" lon="4.406364">
|
||||||
|
<ele>109.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.785126" lon="4.406475">
|
||||||
|
<ele>106.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784697" lon="4.406537">
|
||||||
|
<ele>104.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784591" lon="4.40657">
|
||||||
|
<ele>104.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784507" lon="4.406612">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784435" lon="4.40669">
|
||||||
|
<ele>103.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784209" lon="4.407148">
|
||||||
|
<ele>103.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784162" lon="4.407257">
|
||||||
|
<ele>103.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784077" lon="4.407372">
|
||||||
|
<ele>104.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.784006" lon="4.407435">
|
||||||
|
<ele>105.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783924" lon="4.407471">
|
||||||
|
<ele>106.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783837" lon="4.407486">
|
||||||
|
<ele>107.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783771" lon="4.407472">
|
||||||
|
<ele>108.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783697" lon="4.407428">
|
||||||
|
<ele>109.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783626" lon="4.407363">
|
||||||
|
<ele>110.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783548" lon="4.407274">
|
||||||
|
<ele>110.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783458" lon="4.407134">
|
||||||
|
<ele>110.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.783123" lon="4.406435">
|
||||||
|
<ele>111.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782982" lon="4.406168">
|
||||||
|
<ele>112.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782871" lon="4.406044">
|
||||||
|
<ele>113.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78279" lon="4.406021">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782714" lon="4.406018">
|
||||||
|
<ele>113.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782607" lon="4.406047">
|
||||||
|
<ele>113.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782405" lon="4.406194">
|
||||||
|
<ele>114.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.782175" lon="4.406413">
|
||||||
|
<ele>115.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781749" lon="4.407018">
|
||||||
|
<ele>118.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781654" lon="4.407316">
|
||||||
|
<ele>119.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781563" lon="4.407764">
|
||||||
|
<ele>121.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781487" lon="4.407984">
|
||||||
|
<ele>122.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781422" lon="4.408216">
|
||||||
|
<ele>122.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781395" lon="4.408508">
|
||||||
|
<ele>123.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781399" lon="4.409114">
|
||||||
|
<ele>126.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781367" lon="4.409428">
|
||||||
|
<ele>128.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.781286" lon="4.409607">
|
||||||
|
<ele>129.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.78116" lon="4.409789">
|
||||||
|
<ele>130.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780804" lon="4.409993">
|
||||||
|
<ele>130.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780389" lon="4.410334">
|
||||||
|
<ele>131.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780232" lon="4.410563">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.780094" lon="4.410827">
|
||||||
|
<ele>132.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779723" lon="4.411582">
|
||||||
|
<ele>135.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779591" lon="4.411791">
|
||||||
|
<ele>135.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.779125" lon="4.412435">
|
||||||
|
<ele>132.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778676" lon="4.412979">
|
||||||
|
<ele>134.0</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.778194" lon="4.413466">
|
||||||
|
<ele>136.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777427" lon="4.414302">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.777165" lon="4.414736">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776927" lon="4.415201">
|
||||||
|
<ele>137.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776778" lon="4.415613">
|
||||||
|
<ele>137.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776553" lon="4.416425">
|
||||||
|
<ele>134.8</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776326" lon="4.417304">
|
||||||
|
<ele>132.3</ele>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="50.776129" lon="4.418383">
|
||||||
|
<ele>129.5</ele>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
mod parse;
|
||||||
|
|
||||||
|
pub use parse::*;
|
||||||
@@ -0,0 +1,637 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::gpx::{
|
||||||
|
Author, GPXFile, Link, LngLat, Track, TrackSegment, Trackpoint, TrackpointChunk, Waypoint,
|
||||||
|
WaypointChunk,
|
||||||
|
};
|
||||||
|
use chrono::DateTime;
|
||||||
|
use quick_xml::Error;
|
||||||
|
use quick_xml::events::Event;
|
||||||
|
use quick_xml::events::attributes::Attributes;
|
||||||
|
use quick_xml::reader::Reader;
|
||||||
|
|
||||||
|
enum GPXElement {
|
||||||
|
METADATA,
|
||||||
|
NAME,
|
||||||
|
COMMENT,
|
||||||
|
DESCRIPTION,
|
||||||
|
SOURCE,
|
||||||
|
AUTHOR(Author),
|
||||||
|
LINK(Link),
|
||||||
|
TEXT,
|
||||||
|
TRACK(Track),
|
||||||
|
SEGMENT(TrackSegment),
|
||||||
|
TRACKPOINT(Trackpoint),
|
||||||
|
WAYPOINT(Waypoint),
|
||||||
|
ELEVATION,
|
||||||
|
TIME,
|
||||||
|
TEMPERATURE,
|
||||||
|
HEARTRATE,
|
||||||
|
CADENCE,
|
||||||
|
POWER,
|
||||||
|
SYMBOL,
|
||||||
|
TYPE,
|
||||||
|
COLOR,
|
||||||
|
OPACITY,
|
||||||
|
WIDTH,
|
||||||
|
}
|
||||||
|
|
||||||
|
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> {
|
||||||
|
let mut reader = Reader::from_reader(data);
|
||||||
|
let mut buf = vec![];
|
||||||
|
let mut gpx = GPXFile::default();
|
||||||
|
let mut stack: Vec<GPXElement> = vec![];
|
||||||
|
let mut trkpt_chunk = TrackpointChunk::default();
|
||||||
|
let mut wpt_chunk = WaypointChunk::default();
|
||||||
|
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();
|
||||||
|
trkpt.coordinates = parse_coordinates(e.attributes());
|
||||||
|
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),
|
||||||
|
"time" => stack.push(GPXElement::TIME),
|
||||||
|
e if e.ends_with("atemp") => stack.push(GPXElement::TEMPERATURE),
|
||||||
|
e if e.ends_with("hr") => stack.push(GPXElement::HEARTRATE),
|
||||||
|
e if e.ends_with("cad") => stack.push(GPXElement::CADENCE),
|
||||||
|
"power" => stack.push(GPXElement::POWER),
|
||||||
|
e if e.ends_with("PowerInWatts") => stack.push(GPXElement::POWER),
|
||||||
|
"sym" => stack.push(GPXElement::SYMBOL),
|
||||||
|
"type" => stack.push(GPXElement::TYPE),
|
||||||
|
e if e.ends_with("color") => stack.push(GPXElement::COLOR),
|
||||||
|
e if e.ends_with("opacity") => stack.push(GPXElement::OPACITY),
|
||||||
|
e if e.ends_with("width") => stack.push(GPXElement::WIDTH),
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
|
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" => {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
Some(GPXElement::WAYPOINT(wpt)) => {
|
||||||
|
wpt.link = Some(link);
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"trk" => {
|
||||||
|
if let Some(GPXElement::TRACK(trk)) = stack.pop() {
|
||||||
|
gpx.trk.push(trk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"trkseg" => {
|
||||||
|
if let Some(GPXElement::SEGMENT(mut trkseg)) = stack.pop() {
|
||||||
|
if let Some(GPXElement::TRACK(trk)) = stack.last_mut() {
|
||||||
|
if !trkpt_chunk.trkpt.is_empty() {
|
||||||
|
trkseg.push(trkpt_chunk);
|
||||||
|
trkpt_chunk = TrackpointChunk::default();
|
||||||
|
}
|
||||||
|
trk.trkseg.push(trkseg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"trkpt" => {
|
||||||
|
if let Some(GPXElement::TRACKPOINT(trkpt)) = stack.pop() {
|
||||||
|
if let Some(GPXElement::SEGMENT(trkseg)) = stack.last_mut() {
|
||||||
|
trkpt_chunk.trkpt.push(trkpt);
|
||||||
|
if trkpt_chunk.is_full() {
|
||||||
|
trkseg.push(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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
|
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::WAYPOINT(wpt)) => {
|
||||||
|
wpt.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::WAYPOINT(wpt)) => {
|
||||||
|
wpt.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::WAYPOINT(wpt)) => {
|
||||||
|
wpt.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();
|
||||||
|
match stack.last_mut() {
|
||||||
|
Some(GPXElement::TRACKPOINT(trkpt)) => {
|
||||||
|
trkpt.ele = e.parse().unwrap_or_default();
|
||||||
|
}
|
||||||
|
Some(GPXElement::WAYPOINT(wpt)) => {
|
||||||
|
wpt.ele = e.parse().unwrap_or_default();
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(GPXElement::TIME) => {
|
||||||
|
stack.pop();
|
||||||
|
if let Some(GPXElement::TRACKPOINT(trkpt)) = stack.last_mut() {
|
||||||
|
if let Ok(time) = DateTime::parse_from_rfc3339(e.as_ref()) {
|
||||||
|
trkpt.time = Some(time.timestamp_millis());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(GPXElement::TEMPERATURE) => {
|
||||||
|
stack.pop();
|
||||||
|
if let Some(GPXElement::TRACKPOINT(trkpt)) = stack.last_mut() {
|
||||||
|
trkpt.atemp = e.parse().ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(GPXElement::HEARTRATE) => {
|
||||||
|
stack.pop();
|
||||||
|
if let Some(GPXElement::TRACKPOINT(trkpt)) = stack.last_mut() {
|
||||||
|
trkpt.hr = e.parse().ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(GPXElement::CADENCE) => {
|
||||||
|
stack.pop();
|
||||||
|
if let Some(GPXElement::TRACKPOINT(trkpt)) = stack.last_mut() {
|
||||||
|
trkpt.cad = e.parse().ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(GPXElement::POWER) => {
|
||||||
|
stack.pop();
|
||||||
|
if let Some(GPXElement::TRACKPOINT(trkpt)) = stack.last_mut() {
|
||||||
|
trkpt.power = e.parse().ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(GPXElement::SYMBOL) => {
|
||||||
|
stack.pop();
|
||||||
|
match stack.last_mut() {
|
||||||
|
Some(GPXElement::WAYPOINT(wpt)) => {
|
||||||
|
wpt.sym = Some(e.to_string());
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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::COLOR) => {
|
||||||
|
stack.pop();
|
||||||
|
match stack.last_mut() {
|
||||||
|
Some(GPXElement::TRACK(trk)) => {
|
||||||
|
let mut color = "#".to_string();
|
||||||
|
color.push_str(&e);
|
||||||
|
trk.info.color = Some(color);
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(GPXElement::OPACITY) => {
|
||||||
|
stack.pop();
|
||||||
|
match stack.last_mut() {
|
||||||
|
Some(GPXElement::TRACK(trk)) => {
|
||||||
|
trk.info.opacity = e.parse().ok();
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(GPXElement::WIDTH) => {
|
||||||
|
stack.pop();
|
||||||
|
match stack.last_mut() {
|
||||||
|
Some(GPXElement::TRACK(trk)) => {
|
||||||
|
trk.info.width = e.parse().ok();
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
|
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_simple() {
|
||||||
|
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();
|
||||||
|
|
||||||
|
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(|d| d == "track description")
|
||||||
|
);
|
||||||
|
assert!(trk.info.src.as_ref().is_some_and(|s| s == "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!(trk.info.type_.as_ref().is_some_and(|c| c == "Cycling"));
|
||||||
|
|
||||||
|
assert_eq!(trk.trkseg.len(), 1);
|
||||||
|
let trkseg = &trk.trkseg[0];
|
||||||
|
assert_eq!(trkseg.len(), 80);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert_eq!(trkpt.coordinates.lat, 50.790867);
|
||||||
|
assert_eq!(trkpt.coordinates.lng, 4.404968);
|
||||||
|
assert_eq!(trkpt.ele, 109.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_tracks() {
|
||||||
|
let mut f = File::open("data/with_tracks.gpx").unwrap();
|
||||||
|
let mut data = String::new();
|
||||||
|
let _ = f.read_to_string(&mut data);
|
||||||
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(gpx.trk.len(), 2);
|
||||||
|
let trk = &gpx.trk[0];
|
||||||
|
assert!(trk.info.name.as_ref().is_some_and(|n| n == "track 1"));
|
||||||
|
assert!(trk.info.type_.as_ref().is_some_and(|c| c == "Cycling"));
|
||||||
|
|
||||||
|
assert_eq!(trk.trkseg.len(), 1);
|
||||||
|
let trkseg = &trk.trkseg[0];
|
||||||
|
assert_eq!(trkseg.len(), 49);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert_eq!(trkpt.coordinates.lat, 50.790867);
|
||||||
|
assert_eq!(trkpt.coordinates.lng, 4.404968);
|
||||||
|
assert_eq!(trkpt.ele, 109.0);
|
||||||
|
|
||||||
|
let trk = &gpx.trk[1];
|
||||||
|
assert!(trk.info.name.as_ref().is_some_and(|n| n == "track 2"));
|
||||||
|
assert!(trk.info.type_.as_ref().is_some_and(|c| c == "Cycling"));
|
||||||
|
|
||||||
|
assert_eq!(trk.trkseg.len(), 1);
|
||||||
|
let trkseg = &trk.trkseg[0];
|
||||||
|
assert_eq!(trkseg.len(), 28);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert_eq!(trkpt.coordinates.lat, 50.782212);
|
||||||
|
assert_eq!(trkpt.coordinates.lng, 4.406377);
|
||||||
|
assert_eq!(trkpt.ele, 115.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_segments() {
|
||||||
|
let mut f = File::open("data/with_segments.gpx").unwrap();
|
||||||
|
let mut data = String::new();
|
||||||
|
let _ = f.read_to_string(&mut data);
|
||||||
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(gpx.trk.len(), 1);
|
||||||
|
let trk = &gpx.trk[0];
|
||||||
|
|
||||||
|
assert_eq!(trk.trkseg.len(), 2);
|
||||||
|
let trkseg = &trk.trkseg[0];
|
||||||
|
assert_eq!(trkseg.len(), 49);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert_eq!(trkpt.coordinates.lat, 50.790867);
|
||||||
|
assert_eq!(trkpt.coordinates.lng, 4.404968);
|
||||||
|
assert_eq!(trkpt.ele, 109.0);
|
||||||
|
|
||||||
|
let trkseg = &trk.trkseg[1];
|
||||||
|
assert_eq!(trkseg.len(), 28);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert_eq!(trkpt.coordinates.lat, 50.782212);
|
||||||
|
assert_eq!(trkpt.coordinates.lng, 4.406377);
|
||||||
|
assert_eq!(trkpt.ele, 115.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_tracks_and_segments() {
|
||||||
|
let mut f = File::open("data/with_tracks_and_segments.gpx").unwrap();
|
||||||
|
let mut data = String::new();
|
||||||
|
let _ = f.read_to_string(&mut data);
|
||||||
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(gpx.trk.len(), 2);
|
||||||
|
let trk = &gpx.trk[0];
|
||||||
|
|
||||||
|
assert_eq!(trk.trkseg.len(), 2);
|
||||||
|
let trkseg = &trk.trkseg[0];
|
||||||
|
assert_eq!(trkseg.len(), 16);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert_eq!(trkpt.coordinates.lat, 50.790867);
|
||||||
|
assert_eq!(trkpt.coordinates.lng, 4.404968);
|
||||||
|
assert_eq!(trkpt.ele, 109.0);
|
||||||
|
|
||||||
|
let trkseg = &trk.trkseg[1];
|
||||||
|
assert_eq!(trkseg.len(), 34);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert_eq!(trkpt.coordinates.lat, 50.78727108169855);
|
||||||
|
assert_eq!(trkpt.coordinates.lng, 4.406133681127736);
|
||||||
|
assert_eq!(trkpt.ele, 115.0);
|
||||||
|
|
||||||
|
let trk = &gpx.trk[1];
|
||||||
|
|
||||||
|
assert_eq!(trk.trkseg.len(), 2);
|
||||||
|
let trkseg = &trk.trkseg[0];
|
||||||
|
assert_eq!(trkseg.len(), 19);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert_eq!(trkpt.coordinates.lat, 50.782212);
|
||||||
|
assert_eq!(trkpt.coordinates.lng, 4.406377);
|
||||||
|
assert_eq!(trkpt.ele, 115.5);
|
||||||
|
|
||||||
|
let trkseg = &trk.trkseg[1];
|
||||||
|
assert_eq!(trkseg.len(), 10);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert_eq!(trkpt.coordinates.lat, 50.77906316558724);
|
||||||
|
assert_eq!(trkpt.coordinates.lng, 4.412547477922485);
|
||||||
|
assert_eq!(trkpt.ele, 133.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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();
|
||||||
|
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_trackpoint_time() {
|
||||||
|
let mut f = File::open("data/with_time.gpx").unwrap();
|
||||||
|
let mut data = String::new();
|
||||||
|
let _ = f.read_to_string(&mut data);
|
||||||
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(gpx.trk.len(), 1);
|
||||||
|
let trk = &gpx.trk[0];
|
||||||
|
assert_eq!(trk.trkseg.len(), 1);
|
||||||
|
let trkseg = &trk.trkseg[0];
|
||||||
|
assert!(trkseg.len() > 0);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert!(trkpt.time.is_some_and(|t| t == 1704063600000));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_trackpoint_hr() {
|
||||||
|
let mut f = File::open("data/with_hr.gpx").unwrap();
|
||||||
|
let mut data = String::new();
|
||||||
|
let _ = f.read_to_string(&mut data);
|
||||||
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(gpx.trk.len(), 1);
|
||||||
|
let trk = &gpx.trk[0];
|
||||||
|
assert_eq!(trk.trkseg.len(), 1);
|
||||||
|
let trkseg = &trk.trkseg[0];
|
||||||
|
assert!(trkseg.len() > 0);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert!(trkpt.hr.is_some_and(|h| h == 150));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_trackpoint_cad() {
|
||||||
|
let mut f = File::open("data/with_cad.gpx").unwrap();
|
||||||
|
let mut data = String::new();
|
||||||
|
let _ = f.read_to_string(&mut data);
|
||||||
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(gpx.trk.len(), 1);
|
||||||
|
let trk = &gpx.trk[0];
|
||||||
|
assert_eq!(trk.trkseg.len(), 1);
|
||||||
|
let trkseg = &trk.trkseg[0];
|
||||||
|
assert!(trkseg.len() > 0);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert!(trkpt.cad.is_some_and(|c| c == 80));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_trackpoint_power_1() {
|
||||||
|
let mut f = File::open("data/with_power_1.gpx").unwrap();
|
||||||
|
let mut data = String::new();
|
||||||
|
let _ = f.read_to_string(&mut data);
|
||||||
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(gpx.trk.len(), 1);
|
||||||
|
let trk = &gpx.trk[0];
|
||||||
|
assert_eq!(trk.trkseg.len(), 1);
|
||||||
|
let trkseg = &trk.trkseg[0];
|
||||||
|
assert!(trkseg.len() > 0);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert!(trkpt.power.is_some_and(|p| p == 200));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_trackpoint_power_2() {
|
||||||
|
let mut f = File::open("data/with_power_2.gpx").unwrap();
|
||||||
|
let mut data = String::new();
|
||||||
|
let _ = f.read_to_string(&mut data);
|
||||||
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(gpx.trk.len(), 1);
|
||||||
|
let trk = &gpx.trk[0];
|
||||||
|
assert_eq!(trk.trkseg.len(), 1);
|
||||||
|
let trkseg = &trk.trkseg[0];
|
||||||
|
assert!(trkseg.len() > 0);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert!(trkpt.power.is_some_and(|p| p == 200));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_trackpoint_atemp() {
|
||||||
|
let mut f = File::open("data/with_temp.gpx").unwrap();
|
||||||
|
let mut data = String::new();
|
||||||
|
let _ = f.read_to_string(&mut data);
|
||||||
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(gpx.trk.len(), 1);
|
||||||
|
let trk = &gpx.trk[0];
|
||||||
|
assert_eq!(trk.trkseg.len(), 1);
|
||||||
|
let trkseg = &trk.trkseg[0];
|
||||||
|
assert!(trkseg.len() > 0);
|
||||||
|
let trkpt = &trkseg[0];
|
||||||
|
assert!(trkpt.atemp.is_some_and(|t| t == 21));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_track_style() {
|
||||||
|
let mut f = File::open("data/with_style.gpx").unwrap();
|
||||||
|
let mut data = String::new();
|
||||||
|
let _ = f.read_to_string(&mut data);
|
||||||
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(gpx.trk.len(), 1);
|
||||||
|
let trk = &gpx.trk[0];
|
||||||
|
assert_eq!(trk.trkseg.len(), 1);
|
||||||
|
assert!(trk.info.color.as_ref().is_some_and(|c| c == "#2d3ee9"));
|
||||||
|
assert!(trk.info.opacity.is_some_and(|o| o == 0.5));
|
||||||
|
assert!(trk.info.width.is_some_and(|w| w == 6.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
mod simplify;
|
||||||
|
mod smooth;
|
||||||
|
|
||||||
|
pub use simplify::*;
|
||||||
|
pub use smooth::*;
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
use crate::gpx::{TrackSegment, TrackSegmentIndex};
|
||||||
|
|
||||||
|
pub fn ramer_douglas_peucker<F, T>(
|
||||||
|
trkseg: &TrackSegment,
|
||||||
|
distance: &F,
|
||||||
|
epsilon: T,
|
||||||
|
) -> Vec<TrackSegmentIndex>
|
||||||
|
where
|
||||||
|
F: Fn(TrackSegmentIndex, TrackSegmentIndex, TrackSegmentIndex) -> T,
|
||||||
|
T: Default + PartialOrd + Copy,
|
||||||
|
{
|
||||||
|
match trkseg.len() {
|
||||||
|
0 => vec![],
|
||||||
|
1 => vec![trkseg.first_index().unwrap()],
|
||||||
|
2 => vec![trkseg.last_index().unwrap()],
|
||||||
|
_ => {
|
||||||
|
let first = trkseg.first_index().unwrap();
|
||||||
|
let last = trkseg.last_index().unwrap();
|
||||||
|
|
||||||
|
let mut indices = vec![first];
|
||||||
|
ramer_douglas_peucker_helper(trkseg, first, last, distance, epsilon, &mut indices);
|
||||||
|
indices.push(last);
|
||||||
|
indices
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ramer_douglas_peucker_helper<F, T>(
|
||||||
|
trkseg: &TrackSegment,
|
||||||
|
start: TrackSegmentIndex,
|
||||||
|
end: TrackSegmentIndex,
|
||||||
|
distance: &F,
|
||||||
|
epsilon: T,
|
||||||
|
indices: &mut Vec<TrackSegmentIndex>,
|
||||||
|
) where
|
||||||
|
F: Fn(TrackSegmentIndex, TrackSegmentIndex, TrackSegmentIndex) -> T,
|
||||||
|
T: Default + PartialOrd + Copy,
|
||||||
|
{
|
||||||
|
let mut max_idx = None;
|
||||||
|
let mut max_dist = T::default();
|
||||||
|
|
||||||
|
let mut cur = trkseg.next_index(Some(start));
|
||||||
|
|
||||||
|
while let Some(idx) = cur {
|
||||||
|
if idx == end {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let dist = distance(start, end, idx);
|
||||||
|
if dist > max_dist {
|
||||||
|
max_idx = Some(idx);
|
||||||
|
max_dist = dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = trkseg.next_index(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(idx) = max_idx {
|
||||||
|
if max_dist > epsilon {
|
||||||
|
ramer_douglas_peucker_helper(trkseg, start, idx, distance, epsilon, indices);
|
||||||
|
indices.push(idx);
|
||||||
|
ramer_douglas_peucker_helper(trkseg, idx, end, distance, epsilon, indices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#[macro_export]
|
||||||
|
macro_rules! for_each_window {
|
||||||
|
(
|
||||||
|
$trkseg:expr,
|
||||||
|
$left:expr,
|
||||||
|
$right:expr,
|
||||||
|
$window:expr,
|
||||||
|
|$a:ident, $b:ident| $distance:expr,
|
||||||
|
|$i:ident, $l:ident, $r:ident| $body:block,
|
||||||
|
) => {{
|
||||||
|
let mut start = $left.unwrap_or_default();
|
||||||
|
let mut cur = $left;
|
||||||
|
while let Some(idx) = cur {
|
||||||
|
// advance left if needed
|
||||||
|
while start != idx && {
|
||||||
|
let $a = start;
|
||||||
|
let $b = idx;
|
||||||
|
$distance
|
||||||
|
} > $window {
|
||||||
|
if let Some(next) = $trkseg.next_index(Some(start)) {
|
||||||
|
if next == idx {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
start = next;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// advance right if needed
|
||||||
|
let mut end = idx;
|
||||||
|
while let Some(next) = $trkseg.next_index(Some(end)) {
|
||||||
|
if {
|
||||||
|
let $a = idx;
|
||||||
|
let $b = end;
|
||||||
|
$distance
|
||||||
|
} > $window {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
end = next;
|
||||||
|
}
|
||||||
|
// apply body
|
||||||
|
let $i = idx;
|
||||||
|
let $l = start;
|
||||||
|
let $r = end;
|
||||||
|
$body
|
||||||
|
// go next
|
||||||
|
cur = $trkseg.next_index(cur);
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use uuid::Uuid;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
actions::parse,
|
||||||
|
gpx::GPXFile,
|
||||||
|
stack::{Stack, StackEntry},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Control flow
|
||||||
|
// - get lock to cancel any other updates
|
||||||
|
// - update files
|
||||||
|
// - update separate statistics
|
||||||
|
// - update selection
|
||||||
|
// - update selection statistics
|
||||||
|
// - notify UI (changed files, updated selection, new stats)
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub struct Controller {
|
||||||
|
stack: Stack,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl Controller {
|
||||||
|
#[wasm_bindgen(constructor)]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
stack: Stack::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn create_file(&mut self, name: &str) {
|
||||||
|
let mut file = GPXFile::default();
|
||||||
|
file.info.name = name.to_string();
|
||||||
|
self.stack.create_and_push_next(|entry: &mut StackEntry| {
|
||||||
|
entry.insert(file.id, Rc::new(file));
|
||||||
|
true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn load_file(&mut self, data: &[u8]) {
|
||||||
|
if let Ok(file) = parse(data) {
|
||||||
|
self.stack.create_and_push_next(|entry: &mut StackEntry| {
|
||||||
|
entry.insert(file.id, Rc::new(file));
|
||||||
|
true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn delete_file(&mut self, id: &[u8]) {
|
||||||
|
if let Ok(id) = Uuid::from_slice(id) {
|
||||||
|
self.stack
|
||||||
|
.create_and_push_next(|entry: &mut StackEntry| entry.remove(&id).is_some());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
use crate::gpx::{Trackpoint, Waypoint};
|
||||||
|
|
||||||
|
static MAX_TRKPT_CHUNK_SIZE: usize = 4096;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct TrackpointChunk {
|
||||||
|
pub trkpt: Vec<Trackpoint>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TrackpointChunk {
|
||||||
|
pub fn is_full(&self) -> bool {
|
||||||
|
self.trkpt.len() == MAX_TRKPT_CHUNK_SIZE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static MAX_WPT_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_WPT_CHUNK_SIZE
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Link {
|
||||||
|
pub href: String,
|
||||||
|
pub text: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
|
pub struct LngLat {
|
||||||
|
pub lng: f64,
|
||||||
|
pub lat: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct LngLatBounds {
|
||||||
|
pub sw: LngLat,
|
||||||
|
pub ne: LngLat,
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use crate::gpx::{Link, Track, WaypointChunk};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GPXFile {
|
||||||
|
pub id: Uuid,
|
||||||
|
pub info: GPXFileInfo,
|
||||||
|
pub trk: Vec<Track>,
|
||||||
|
pub wpt: Vec<Rc<WaypointChunk>>,
|
||||||
|
// TODO routes
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GPXFile {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
id: Uuid::new_v4(),
|
||||||
|
info: Default::default(),
|
||||||
|
trk: Default::default(),
|
||||||
|
wpt: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct GPXFileInfo {
|
||||||
|
pub name: String,
|
||||||
|
pub desc: Option<String>,
|
||||||
|
pub author: Option<Author>,
|
||||||
|
pub link: Option<Link>,
|
||||||
|
pub time: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Author {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub email: Option<String>,
|
||||||
|
pub link: Option<Link>,
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
mod chunk;
|
||||||
|
mod common;
|
||||||
|
mod file;
|
||||||
|
mod segment;
|
||||||
|
mod track;
|
||||||
|
mod trackpoint;
|
||||||
|
mod waypoint;
|
||||||
|
|
||||||
|
pub use chunk::*;
|
||||||
|
pub use common::*;
|
||||||
|
pub use file::*;
|
||||||
|
pub use segment::*;
|
||||||
|
pub use track::*;
|
||||||
|
pub use trackpoint::*;
|
||||||
|
pub use waypoint::*;
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
use std::{ops::Index, rc::Rc};
|
||||||
|
|
||||||
|
use crate::gpx::{Trackpoint, TrackpointChunk};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct TrackSegment {
|
||||||
|
chunks: Vec<Rc<TrackpointChunk>>,
|
||||||
|
cumul_length: Vec<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TrackSegment {
|
||||||
|
pub fn push(&mut self, chunk: TrackpointChunk) {
|
||||||
|
if chunk.trkpt.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.cumul_length
|
||||||
|
.push(self.cumul_length.last().copied().unwrap_or_default() + chunk.trkpt.len());
|
||||||
|
self.chunks.push(Rc::new(chunk));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.cumul_length.last().copied().unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> TrackSegmentIterator<'_> {
|
||||||
|
TrackSegmentIterator::new(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn first_index(&self) -> Option<TrackSegmentIndex> {
|
||||||
|
self.next_index(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn last_index(&self) -> Option<TrackSegmentIndex> {
|
||||||
|
self.prev_index(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_index(&self, cur: Option<TrackSegmentIndex>) -> Option<TrackSegmentIndex> {
|
||||||
|
let mut next = cur.map_or_default(|idx| TrackSegmentIndex {
|
||||||
|
chunk: idx.chunk,
|
||||||
|
pos: idx.pos + 1,
|
||||||
|
});
|
||||||
|
loop {
|
||||||
|
if next.chunk >= self.chunks.len() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if next.pos == self.chunks[next.chunk].trkpt.len() {
|
||||||
|
next.chunk += 1;
|
||||||
|
next.pos = 0;
|
||||||
|
} else {
|
||||||
|
return Some(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev_index(&self, cur: Option<TrackSegmentIndex>) -> Option<TrackSegmentIndex> {
|
||||||
|
let mut prev = cur.unwrap_or(TrackSegmentIndex {
|
||||||
|
chunk: self.chunks.len(),
|
||||||
|
pos: 0,
|
||||||
|
});
|
||||||
|
loop {
|
||||||
|
if prev.pos == 0 {
|
||||||
|
if prev.chunk == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
prev.chunk -= 1;
|
||||||
|
prev.pos = self.chunks[prev.chunk].trkpt.len();
|
||||||
|
} else {
|
||||||
|
prev.pos -= 1;
|
||||||
|
return Some(prev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_flat_index(&self, idx: TrackSegmentIndex) -> usize {
|
||||||
|
idx.pos
|
||||||
|
+ if idx.chunk > 0 {
|
||||||
|
self.cumul_length[idx.chunk - 1]
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn locate(&self, idx: usize) -> Option<TrackSegmentIndex> {
|
||||||
|
let chunk = self.cumul_length.partition_point(|l| idx >= *l);
|
||||||
|
if chunk >= self.chunks.len() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let pos = if chunk > 0 {
|
||||||
|
idx - self.cumul_length[chunk - 1]
|
||||||
|
} else {
|
||||||
|
idx
|
||||||
|
};
|
||||||
|
if pos >= self.chunks[chunk].trkpt.len() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(TrackSegmentIndex { chunk, pos })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Index<TrackSegmentIndex> for TrackSegment {
|
||||||
|
type Output = Trackpoint;
|
||||||
|
|
||||||
|
fn index(&self, idx: TrackSegmentIndex) -> &Self::Output {
|
||||||
|
&self.chunks[idx.chunk].trkpt[idx.pos]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Index<usize> for TrackSegment {
|
||||||
|
type Output = Trackpoint;
|
||||||
|
|
||||||
|
fn index(&self, idx: usize) -> &Self::Output {
|
||||||
|
&self[self.locate(idx).unwrap()]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord)]
|
||||||
|
pub struct TrackSegmentIndex {
|
||||||
|
pub chunk: usize,
|
||||||
|
pub pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct TrackSegmentIterator<'a> {
|
||||||
|
trkseg: &'a TrackSegment,
|
||||||
|
idx: Option<TrackSegmentIndex>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TrackSegmentIterator<'a> {
|
||||||
|
pub fn new(trkseg: &'a TrackSegment) -> Self {
|
||||||
|
Self {
|
||||||
|
trkseg,
|
||||||
|
idx: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for TrackSegmentIterator<'a> {
|
||||||
|
type Item = &'a Trackpoint;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.idx = self.trkseg.next_index(self.idx);
|
||||||
|
self.idx.map(|idx| &self.trkseg[idx])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||||
|
let idx = self
|
||||||
|
.idx
|
||||||
|
.map_or_default(|idx| self.trkseg.to_flat_index(idx))
|
||||||
|
+ n;
|
||||||
|
self.idx = self.trkseg.locate(idx);
|
||||||
|
self.idx.map(|idx| &self.trkseg[idx])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::gpx::TrackpointChunk;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn create_track_segment(nb_chunks: usize) -> TrackSegment {
|
||||||
|
let mut trkseg = TrackSegment::default();
|
||||||
|
let mut count = 0;
|
||||||
|
for n in 1..=nb_chunks {
|
||||||
|
let mut chunk = TrackpointChunk::default();
|
||||||
|
for _ in 0..n {
|
||||||
|
let mut trkpt = Trackpoint::default();
|
||||||
|
trkpt.ele = count as f64;
|
||||||
|
chunk.trkpt.push(trkpt);
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
trkseg.push(chunk);
|
||||||
|
}
|
||||||
|
trkseg
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_len() {
|
||||||
|
let nb_chunks = 10;
|
||||||
|
let trkseg = create_track_segment(nb_chunks);
|
||||||
|
assert_eq!(trkseg.len(), nb_chunks * (nb_chunks + 1) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_locate() {
|
||||||
|
let nb_chunks = 10;
|
||||||
|
let trkseg = create_track_segment(nb_chunks);
|
||||||
|
for i in 0..trkseg.len() {
|
||||||
|
let idx = trkseg.locate(i);
|
||||||
|
assert!(idx.is_some());
|
||||||
|
assert_eq!(trkseg[idx.unwrap()].ele, i as f64);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(trkseg.locate(trkseg.len()).is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_index() {
|
||||||
|
let nb_chunks = 10;
|
||||||
|
let trkseg = create_track_segment(nb_chunks);
|
||||||
|
for i in 0..trkseg.len() {
|
||||||
|
assert_eq!(trkseg[i].ele, i as f64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn test_index_out_of_bounds_1() {
|
||||||
|
let nb_chunks = 10;
|
||||||
|
let trkseg = create_track_segment(nb_chunks);
|
||||||
|
trkseg[trkseg.len()].ele;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn test_index_out_of_bounds_2() {
|
||||||
|
let nb_chunks = 10;
|
||||||
|
let trkseg = create_track_segment(nb_chunks);
|
||||||
|
trkseg[TrackSegmentIndex {
|
||||||
|
chunk: trkseg.chunks.len(),
|
||||||
|
pos: 0,
|
||||||
|
}]
|
||||||
|
.ele;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_iter() {
|
||||||
|
let nb_chunks = 10;
|
||||||
|
let trkseg = create_track_segment(nb_chunks);
|
||||||
|
for (i, trkpt) in trkseg.iter().enumerate() {
|
||||||
|
assert!(std::ptr::eq(&trkseg[i], trkpt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_iter_nth() {
|
||||||
|
let nb_chunks = 10;
|
||||||
|
let trkseg = create_track_segment(nb_chunks);
|
||||||
|
let tenth = trkseg.iter().nth(10);
|
||||||
|
assert!(tenth.is_some());
|
||||||
|
assert!(std::ptr::eq(&trkseg[10], tenth.unwrap()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_iter_skip() {
|
||||||
|
let nb_chunks = 10;
|
||||||
|
let trkseg = create_track_segment(nb_chunks);
|
||||||
|
for (i, trkpt) in trkseg.iter().enumerate().skip(5) {
|
||||||
|
assert!(std::ptr::eq(&trkseg[i], trkpt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
use crate::gpx::{Link, TrackSegment};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Track {
|
||||||
|
pub info: TrackInfo,
|
||||||
|
pub trkseg: Vec<TrackSegment>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct TrackInfo {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub cmt: Option<String>,
|
||||||
|
pub desc: Option<String>,
|
||||||
|
pub src: Option<String>,
|
||||||
|
pub link: Option<Link>,
|
||||||
|
pub type_: Option<String>,
|
||||||
|
pub color: Option<String>,
|
||||||
|
pub opacity: Option<f64>,
|
||||||
|
pub width: Option<f64>,
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
use crate::gpx::LngLat;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Trackpoint {
|
||||||
|
pub coordinates: LngLat,
|
||||||
|
pub ele: f64,
|
||||||
|
pub time: Option<i64>,
|
||||||
|
pub atemp: Option<i16>,
|
||||||
|
pub hr: Option<u16>,
|
||||||
|
pub cad: Option<u16>,
|
||||||
|
pub power: Option<u16>,
|
||||||
|
// TODO OSM data? or store intervals at a higher level?
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trackpoint {
|
||||||
|
pub fn time_diff(&self, other: &Trackpoint) -> Option<i64> {
|
||||||
|
self.time.zip(other.time).map(|(t1, t2)| t1 - t2)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
use crate::gpx::{Link, LngLat};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Waypoint {
|
||||||
|
pub coordinates: LngLat,
|
||||||
|
pub ele: f64,
|
||||||
|
pub time: Option<i64>,
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub cmt: Option<String>,
|
||||||
|
pub desc: Option<String>,
|
||||||
|
pub link: Option<Link>,
|
||||||
|
pub sym: Option<String>,
|
||||||
|
pub type_: Option<String>,
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
mod actions;
|
||||||
|
mod controller;
|
||||||
|
mod gpx;
|
||||||
|
mod stack;
|
||||||
|
mod statistics;
|
||||||
|
mod utils;
|
||||||
|
mod algorithms;
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
use std::{collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use crate::gpx::GPXFile;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Stack {
|
||||||
|
entries: Vec<StackEntry>,
|
||||||
|
index: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stack {
|
||||||
|
pub fn current(&self) -> Option<&StackEntry> {
|
||||||
|
match self.index {
|
||||||
|
Some(i) => Some(&self.entries[i]),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_and_push_next<F>(&mut self, f: F)
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut StackEntry) -> bool,
|
||||||
|
{
|
||||||
|
let mut next = self.current().map_or_default(|c| c.clone());
|
||||||
|
if f(&mut next) {
|
||||||
|
self.push(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn update(&mut self, files: &[Rc<GPXFile>], ids: &[GPXFileId]) {
|
||||||
|
// let mut next = match self.current() {
|
||||||
|
// Some(current) => current.clone(),
|
||||||
|
// None => StackEntry::default(),
|
||||||
|
// };
|
||||||
|
// for (file, id) in files.iter().zip(ids) {
|
||||||
|
// next.insert(*id, file.clone());
|
||||||
|
// }
|
||||||
|
// self.push(next);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub fn delete(&mut self, files: &[GPXFileId]) {
|
||||||
|
// if let Some(current) = self.current() {
|
||||||
|
// let mut next = current.clone();
|
||||||
|
// for file in files {
|
||||||
|
// next.remove(file);
|
||||||
|
// }
|
||||||
|
// self.push(next);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
pub fn can_undo(&self) -> bool {
|
||||||
|
self.index.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn can_redo(&self) -> bool {
|
||||||
|
match self.index {
|
||||||
|
Some(i) => i + 1 < self.entries.len(),
|
||||||
|
None => !self.entries.is_empty(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn undo(&mut self) {
|
||||||
|
if let Some(i) = self.index {
|
||||||
|
if i == 0 {
|
||||||
|
self.index = None;
|
||||||
|
} else {
|
||||||
|
self.index = Some(i - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn redo(&mut self) {
|
||||||
|
match self.index {
|
||||||
|
Some(i) => {
|
||||||
|
if i + 1 < self.entries.len() {
|
||||||
|
self.index = Some(i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
if !self.entries.is_empty() {
|
||||||
|
self.index = Some(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push(&mut self, entry: StackEntry) {
|
||||||
|
if let Some(i) = self.index {
|
||||||
|
if i + 1 < self.entries.len() {
|
||||||
|
self.entries.truncate(i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.entries.push(entry);
|
||||||
|
self.index = Some(self.entries.len() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type StackEntry = HashMap<Uuid, Rc<GPXFile>>;
|
||||||
@@ -0,0 +1,292 @@
|
|||||||
|
use crate::{
|
||||||
|
algorithms::ramer_douglas_peucker,
|
||||||
|
for_each_window,
|
||||||
|
gpx::{LngLat, LngLatBounds, TrackSegment, Trackpoint},
|
||||||
|
utils::{distance, slope, speed},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct GPXStatistics {
|
||||||
|
pub total_distance: f64,
|
||||||
|
pub moving_distance: Option<f64>,
|
||||||
|
pub moving_time: Option<i64>,
|
||||||
|
pub elevation_gain: f64,
|
||||||
|
pub elevation_loss: f64,
|
||||||
|
pub start_time: Option<i64>,
|
||||||
|
pub end_time: Option<i64>,
|
||||||
|
pub bounds: LngLatBounds,
|
||||||
|
pub local: Vec<TrackpointStatistics>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GPXStatistics {
|
||||||
|
pub fn total_time(&self) -> Option<i64> {
|
||||||
|
self.start_time.zip(self.end_time).map(|(t1, t2)| t2 - t1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn total_speed(&self) -> Option<f64> {
|
||||||
|
self.total_time().map(|t| speed(self.total_distance, t))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn moving_speed(&self) -> Option<f64> {
|
||||||
|
self.moving_distance
|
||||||
|
.zip(self.moving_time)
|
||||||
|
.map(|(d, t)| speed(d, t))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compute(trkseg: &TrackSegment) -> Self {
|
||||||
|
let mut stats = Self::default();
|
||||||
|
if trkseg.len() == 0 {
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut prev = &trkseg[0];
|
||||||
|
for cur in trkseg.iter() {
|
||||||
|
stats.accumulate(prev, cur);
|
||||||
|
prev = cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.compute_smoothed_speed(trkseg);
|
||||||
|
stats.compute_smoothed_elevation_gain(trkseg);
|
||||||
|
|
||||||
|
stats
|
||||||
|
}
|
||||||
|
|
||||||
|
fn accumulate(&mut self, prev: &Trackpoint, cur: &Trackpoint) {
|
||||||
|
self.accumulate_distance_and_time(prev, cur);
|
||||||
|
self.update_time_bounds(cur.time);
|
||||||
|
self.update_bounds(&cur.coordinates);
|
||||||
|
self.local
|
||||||
|
.push(TrackpointStatistics::from_partial_stats(&self));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn accumulate_distance_and_time(&mut self, prev: &Trackpoint, cur: &Trackpoint) {
|
||||||
|
let dist = distance(prev.coordinates, cur.coordinates);
|
||||||
|
let time = cur.time_diff(prev);
|
||||||
|
|
||||||
|
self.total_distance += dist;
|
||||||
|
|
||||||
|
if let Some(time) = time {
|
||||||
|
let speed = speed(dist, time);
|
||||||
|
if speed >= 0.5 && speed <= 1500.0 {
|
||||||
|
self.moving_distance = self.moving_distance.map_or(Some(dist), |d| Some(d + dist));
|
||||||
|
self.moving_time = self.moving_time.map_or(Some(time), |t| Some(t + time));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_time_bounds(&mut self, time: Option<i64>) {
|
||||||
|
if let Some(time) = time {
|
||||||
|
if self.start_time.is_none() {
|
||||||
|
self.start_time = Some(time);
|
||||||
|
}
|
||||||
|
self.end_time = Some(time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_bounds(&mut self, coordinates: &LngLat) {
|
||||||
|
self.bounds.sw.lng = self.bounds.sw.lng.min(coordinates.lng);
|
||||||
|
self.bounds.sw.lat = self.bounds.sw.lat.min(coordinates.lat);
|
||||||
|
self.bounds.ne.lng = self.bounds.ne.lng.min(coordinates.lng);
|
||||||
|
self.bounds.ne.lat = self.bounds.ne.lat.min(coordinates.lat);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_smoothed_speed(&mut self, trkseg: &TrackSegment) {
|
||||||
|
for_each_window!(
|
||||||
|
trkseg,
|
||||||
|
trkseg.first_index(),
|
||||||
|
trkseg.last_index(),
|
||||||
|
Some(10000),
|
||||||
|
|i, j| trkseg[i].time_diff(&trkseg[j]),
|
||||||
|
|i, left, right| {
|
||||||
|
let i = trkseg.to_flat_index(i);
|
||||||
|
let left = trkseg.to_flat_index(left);
|
||||||
|
let right = trkseg.to_flat_index(right);
|
||||||
|
self.local[i].speed = trkseg[right].time_diff(&trkseg[left]).map(|t| {
|
||||||
|
speed(
|
||||||
|
self.local[right].total_distance - self.local[left].total_distance,
|
||||||
|
t,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_smoothed_elevation_gain(&mut self, trkseg: &TrackSegment) {
|
||||||
|
let simplified = ramer_douglas_peucker(
|
||||||
|
trkseg,
|
||||||
|
&|i, j, k| {
|
||||||
|
let x1 = self.local[trkseg.to_flat_index(i)].total_distance * 1000.0;
|
||||||
|
let x2 = self.local[trkseg.to_flat_index(j)].total_distance * 1000.0;
|
||||||
|
let x3 = self.local[trkseg.to_flat_index(k)].total_distance * 1000.0;
|
||||||
|
let y1 = trkseg[i].ele;
|
||||||
|
let y2 = trkseg[j].ele;
|
||||||
|
let y3 = trkseg[k].ele;
|
||||||
|
|
||||||
|
let dist = ((y2 - y1).powi(2) + (x2 - x1).powi(2)).sqrt();
|
||||||
|
if dist == 0.0 {
|
||||||
|
((x3 - x1).powi(2) + (y3 - y1).powi(2)).sqrt()
|
||||||
|
} else {
|
||||||
|
((y2 - y1) * x3 - (x2 - x1) * y3 + x2 * y1 - y2 * x1).abs() / dist
|
||||||
|
}
|
||||||
|
},
|
||||||
|
20.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
for i in 0..(simplified.len() - 1) {
|
||||||
|
let start = simplified[i];
|
||||||
|
let end = simplified[i + 1];
|
||||||
|
let last = i + 1 == simplified.len() - 1;
|
||||||
|
|
||||||
|
let mut cumul_ele = 0.0;
|
||||||
|
let mut current_left = start;
|
||||||
|
let mut current_right = Some(start);
|
||||||
|
let mut prev_smoothed_ele = trkseg[start].ele;
|
||||||
|
|
||||||
|
for_each_window!(
|
||||||
|
trkseg,
|
||||||
|
Some(start),
|
||||||
|
Some(end),
|
||||||
|
0.1,
|
||||||
|
|i, j| {
|
||||||
|
let i = trkseg.to_flat_index(i);
|
||||||
|
let j = trkseg.to_flat_index(j);
|
||||||
|
self.local[j].total_distance - self.local[i].total_distance
|
||||||
|
},
|
||||||
|
|i, left, right| {
|
||||||
|
while current_left != left {
|
||||||
|
cumul_ele -= trkseg[current_left].ele;
|
||||||
|
current_left = trkseg.next_index(Some(current_left)).unwrap();
|
||||||
|
}
|
||||||
|
while let Some(current) = current_right {
|
||||||
|
if current > right {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cumul_ele += trkseg[current].ele;
|
||||||
|
current_right = trkseg.next_index(current_right);
|
||||||
|
}
|
||||||
|
|
||||||
|
let flat_i = trkseg.to_flat_index(i);
|
||||||
|
let flat_left = trkseg.to_flat_index(left);
|
||||||
|
let flat_right = trkseg.to_flat_index(right);
|
||||||
|
|
||||||
|
let smoothed_ele: f64 = if i == start || i == end {
|
||||||
|
trkseg[i].ele
|
||||||
|
} else {
|
||||||
|
cumul_ele / (flat_right - flat_left + 1) as f64
|
||||||
|
};
|
||||||
|
|
||||||
|
let delta = smoothed_ele - prev_smoothed_ele;
|
||||||
|
if delta > 0.0 {
|
||||||
|
self.elevation_gain += delta;
|
||||||
|
} else if delta < 0.0 {
|
||||||
|
self.elevation_loss -= delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
if i < end || last {
|
||||||
|
self.local[flat_i].elevation_gain = self.elevation_gain;
|
||||||
|
self.local[flat_i].elevation_loss = self.elevation_loss;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_smoothed_ele = smoothed_ele;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let flat_start = trkseg.to_flat_index(start);
|
||||||
|
let flat_end = trkseg.to_flat_index(end);
|
||||||
|
|
||||||
|
let segment_dist =
|
||||||
|
self.local[flat_end].total_distance - self.local[flat_start].total_distance;
|
||||||
|
let segment_ele = trkseg[end].ele - trkseg[start].ele;
|
||||||
|
let segment_slope = slope(segment_ele, segment_dist);
|
||||||
|
for k in flat_start..(flat_end + last as usize) {
|
||||||
|
self.local[k].slope_segment = SlopeSegment {
|
||||||
|
slope: segment_slope,
|
||||||
|
distance: segment_dist,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each_window!(
|
||||||
|
trkseg,
|
||||||
|
trkseg.first_index(),
|
||||||
|
trkseg.last_index(),
|
||||||
|
0.05,
|
||||||
|
|i, j| {
|
||||||
|
let i = trkseg.to_flat_index(i);
|
||||||
|
let j = trkseg.to_flat_index(j);
|
||||||
|
self.local[j].total_distance - self.local[i].total_distance
|
||||||
|
},
|
||||||
|
|i, left, right| {
|
||||||
|
let flat_i = trkseg.to_flat_index(i);
|
||||||
|
let flat_left = trkseg.to_flat_index(left);
|
||||||
|
let flat_right = trkseg.to_flat_index(right);
|
||||||
|
let dist =
|
||||||
|
self.local[flat_right].total_distance - self.local[flat_left].total_distance;
|
||||||
|
let ele = trkseg[right].ele - trkseg[left].ele;
|
||||||
|
self.local[flat_i].slope = slope(ele, dist);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct SlopeSegment {
|
||||||
|
pub slope: f64,
|
||||||
|
pub distance: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct TrackpointStatistics {
|
||||||
|
pub total_distance: f64,
|
||||||
|
pub moving_distance: Option<f64>,
|
||||||
|
pub total_time: Option<i64>,
|
||||||
|
pub moving_time: Option<i64>,
|
||||||
|
pub speed: Option<f64>,
|
||||||
|
pub elevation_gain: f64,
|
||||||
|
pub elevation_loss: f64,
|
||||||
|
pub slope: f64,
|
||||||
|
pub slope_segment: SlopeSegment,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TrackpointStatistics {
|
||||||
|
fn from_partial_stats(stats: &GPXStatistics) -> Self {
|
||||||
|
Self {
|
||||||
|
total_distance: stats.total_distance,
|
||||||
|
moving_distance: stats.moving_distance,
|
||||||
|
total_time: stats.start_time.zip(stats.end_time).map(|(t1, t2)| t2 - t1),
|
||||||
|
moving_time: stats.moving_time,
|
||||||
|
speed: None,
|
||||||
|
elevation_gain: stats.elevation_gain,
|
||||||
|
elevation_loss: stats.elevation_loss,
|
||||||
|
slope: Default::default(),
|
||||||
|
slope_segment: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::{fs::File, io::Read};
|
||||||
|
|
||||||
|
use crate::actions::parse;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_compute_smoothed_speed() {
|
||||||
|
let mut f = File::open("data/with_time.gpx").unwrap();
|
||||||
|
let mut data = String::new();
|
||||||
|
let _ = f.read_to_string(&mut data);
|
||||||
|
let gpx = parse(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
let trkseg = &gpx.trk[0].trkseg[0];
|
||||||
|
let stats = GPXStatistics::compute(trkseg);
|
||||||
|
assert_eq!(stats.local.len(), trkseg.len());
|
||||||
|
for trkpt_stats in stats.local.iter() {
|
||||||
|
assert!(trkpt_stats.speed.is_some());
|
||||||
|
let speed = trkpt_stats.speed.unwrap();
|
||||||
|
assert_ne!(speed, f64::NAN);
|
||||||
|
assert!((speed - 20.0).abs() < 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
|
use crate::gpx::LngLat;
|
||||||
|
|
||||||
|
static TO_RADIANS: f64 = PI / 180.0;
|
||||||
|
static EARTH_RADIUS: f64 = 6371.0088;
|
||||||
|
|
||||||
|
/// Computes the distance in kilometers between two coordinates using the Haversine formula
|
||||||
|
pub fn distance(p1: LngLat, p2: LngLat) -> f64 {
|
||||||
|
let lat1 = p1.lat * TO_RADIANS;
|
||||||
|
let lat2 = p2.lat * TO_RADIANS;
|
||||||
|
let delta_lat = lat2 - lat1;
|
||||||
|
let delta_lng = (p2.lng - p1.lng) * TO_RADIANS;
|
||||||
|
|
||||||
|
let a =
|
||||||
|
(delta_lat / 2.0).sin().powi(2) + lat1.cos() * lat2.cos() * (delta_lng / 2.0).sin().powi(2);
|
||||||
|
let c = 2.0 * a.min(1.0).sqrt().asin();
|
||||||
|
EARTH_RADIUS * c
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes the speed for a given distance in kilometers and a time in milliseconds
|
||||||
|
pub fn speed(distance: f64, time: i64) -> f64 {
|
||||||
|
distance / (time as f64 / 3600_000.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn slope(ele: f64, distance: f64) -> f64 {
|
||||||
|
if distance == 0.0 {
|
||||||
|
100.0
|
||||||
|
} else {
|
||||||
|
0.1 * ele / distance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static METERS_PER_LATITUDE_DEGREE: f64 = 111320.0;
|
||||||
|
|
||||||
|
fn get_meters_per_longitude_degree(latitude: f64) -> f64 {
|
||||||
|
((latitude * PI) / 180.0).cos() * METERS_PER_LATITUDE_DEGREE
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculates the point on the line segment defined by p1 and p2
|
||||||
|
// that is closest to the third point, p3.
|
||||||
|
// Uses simple planar geometry (ignores earth curvature).
|
||||||
|
fn projected(p1: LngLat, p2: LngLat, coord3: LngLat) -> LngLat {
|
||||||
|
// Convert to meters using approximate scaling
|
||||||
|
let meters_per_longitude_degree = get_meters_per_longitude_degree(p1.lat);
|
||||||
|
|
||||||
|
let x1 = p1.lng * meters_per_longitude_degree;
|
||||||
|
let y1 = p1.lat * METERS_PER_LATITUDE_DEGREE;
|
||||||
|
let x2 = p2.lng * meters_per_longitude_degree;
|
||||||
|
let y2 = p2.lat * METERS_PER_LATITUDE_DEGREE;
|
||||||
|
let x3 = coord3.lng * meters_per_longitude_degree;
|
||||||
|
let y3 = coord3.lat * METERS_PER_LATITUDE_DEGREE;
|
||||||
|
|
||||||
|
let dx = x2 - x1;
|
||||||
|
let dy = y2 - y1;
|
||||||
|
let segment_length_squared = dx * dx + dy * dy;
|
||||||
|
|
||||||
|
if segment_length_squared == 0.0 {
|
||||||
|
// p1 and p2 are the same point
|
||||||
|
p1
|
||||||
|
} else {
|
||||||
|
// Project p3 onto the line defined by p1-p2
|
||||||
|
let t =
|
||||||
|
0.0_f64.max(1.0_f64.min(((x3 - x1) * dx + (y3 - y1) * dy) / segment_length_squared));
|
||||||
|
|
||||||
|
// Find the closest point on the segment
|
||||||
|
let proj_x = x1 + t * dx;
|
||||||
|
let proj_y = y1 + t * dy;
|
||||||
|
|
||||||
|
// Convert back to degrees
|
||||||
|
LngLat {
|
||||||
|
lng: proj_x / meters_per_longitude_degree,
|
||||||
|
lat: proj_y / METERS_PER_LATITUDE_DEGREE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculates the perpendicular distance in meters
|
||||||
|
/// between a line segment (defined by p1 and p2) and a third point, p3.
|
||||||
|
/// Uses simple planar geometry (ignores earth curvature).
|
||||||
|
fn crossarc(p1: LngLat, p2: LngLat, p3: LngLat) -> f64 {
|
||||||
|
// Convert to meters using approximate scaling
|
||||||
|
let meters_per_longitude_degree = get_meters_per_longitude_degree(p1.lat);
|
||||||
|
|
||||||
|
let x1 = p1.lng * meters_per_longitude_degree;
|
||||||
|
let y1 = p1.lat * METERS_PER_LATITUDE_DEGREE;
|
||||||
|
let x2 = p2.lng * meters_per_longitude_degree;
|
||||||
|
let y2 = p2.lat * METERS_PER_LATITUDE_DEGREE;
|
||||||
|
let x3 = p3.lng * meters_per_longitude_degree;
|
||||||
|
let y3 = p3.lat * METERS_PER_LATITUDE_DEGREE;
|
||||||
|
|
||||||
|
let dx = x2 - x1;
|
||||||
|
let dy = y2 - y1;
|
||||||
|
let segment_length_squared = dx * dx + dy * dy;
|
||||||
|
|
||||||
|
if segment_length_squared == 0.0 {
|
||||||
|
// p1 and p2 are the same point
|
||||||
|
((x3 - x1) * (x3 - x1) + (y3 - y1) * (y3 - y1)).sqrt()
|
||||||
|
} else {
|
||||||
|
// Project p3 onto the line defined by p1 - p2
|
||||||
|
let t =
|
||||||
|
0.0_f64.max(1.0_f64.min(((x3 - x1) * dx + (y3 - y1) * dy) / segment_length_squared));
|
||||||
|
|
||||||
|
// Find the closest point on the segment
|
||||||
|
let proj_x = x1 + t * dx;
|
||||||
|
let proj_y = y1 + t * dy;
|
||||||
|
|
||||||
|
// Return distance from p3 to the projected point
|
||||||
|
((x3 - proj_x) * (x3 - proj_x) + (y3 - proj_y) * (y3 - proj_y)).sqrt()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1398,10 +1398,7 @@ export class TrackPoint {
|
|||||||
: undefined;
|
: undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
setExtensions(extensions: Record<string, string>) {
|
setExtension(key: string, value: string) {
|
||||||
if (Object.keys(extensions).length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!this.extensions) {
|
if (!this.extensions) {
|
||||||
this.extensions = {};
|
this.extensions = {};
|
||||||
}
|
}
|
||||||
@@ -1411,8 +1408,12 @@ export class TrackPoint {
|
|||||||
if (!this.extensions['gpxtpx:TrackPointExtension']['gpxtpx:Extensions']) {
|
if (!this.extensions['gpxtpx:TrackPointExtension']['gpxtpx:Extensions']) {
|
||||||
this.extensions['gpxtpx:TrackPointExtension']['gpxtpx:Extensions'] = {};
|
this.extensions['gpxtpx:TrackPointExtension']['gpxtpx:Extensions'] = {};
|
||||||
}
|
}
|
||||||
|
this.extensions['gpxtpx:TrackPointExtension']['gpxtpx:Extensions'][key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
setExtensions(extensions: Record<string, string>) {
|
||||||
Object.entries(extensions).forEach(([key, value]) => {
|
Object.entries(extensions).forEach(([key, value]) => {
|
||||||
this.extensions['gpxtpx:TrackPointExtension']['gpxtpx:Extensions'][key] = value;
|
this.setExtension(key, value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://shadcn-svelte.com/schema.json",
|
"$schema": "https://shadcn-svelte.com/schema.json",
|
||||||
"style": "default",
|
"tailwind": {
|
||||||
"tailwind": {
|
"css": "src/app.css",
|
||||||
"css": "src/app.css",
|
"baseColor": "neutral"
|
||||||
"baseColor": "slate"
|
},
|
||||||
},
|
"aliases": {
|
||||||
"aliases": {
|
"components": "$lib/components",
|
||||||
"components": "$lib/components",
|
"utils": "$lib/utils",
|
||||||
"utils": "$lib/utils",
|
"ui": "$lib/components/ui",
|
||||||
"ui": "$lib/components/ui",
|
"hooks": "$lib/hooks",
|
||||||
"hooks": "$lib/hooks",
|
"lib": "$lib"
|
||||||
"lib": "$lib"
|
},
|
||||||
},
|
"typescript": true,
|
||||||
"typescript": true,
|
"registry": "https://shadcn-svelte.com/registry",
|
||||||
"registry": "https://shadcn-svelte.com/registry"
|
"style": "nova",
|
||||||
|
"iconLibrary": "lucide",
|
||||||
|
"menuColor": "default",
|
||||||
|
"menuAccent": "subtle"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,9 @@
|
|||||||
"format": "prettier --write . --config ../.prettierrc --ignore-path ../.prettierignore --ignore-path ./.gitignore"
|
"format": "prettier --write . --config ../.prettierrc --ignore-path ../.prettierignore --ignore-path ./.gitignore"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@lucide/svelte": "^0.544.0",
|
"@fontsource-variable/inter": "^5.2.8",
|
||||||
|
"@internationalized/date": "^3.12.0",
|
||||||
|
"@lucide/svelte": "^1.7.0",
|
||||||
"@sveltejs/adapter-static": "^3.0.8",
|
"@sveltejs/adapter-static": "^3.0.8",
|
||||||
"@sveltejs/enhanced-img": "^0.6.0",
|
"@sveltejs/enhanced-img": "^0.6.0",
|
||||||
"@sveltejs/kit": "^2.21.2",
|
"@sveltejs/kit": "^2.21.2",
|
||||||
@@ -30,7 +32,8 @@
|
|||||||
"@types/sortablejs": "^1.15.8",
|
"@types/sortablejs": "^1.15.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.33.1",
|
"@typescript-eslint/eslint-plugin": "^8.33.1",
|
||||||
"@typescript-eslint/parser": "^8.33.1",
|
"@typescript-eslint/parser": "^8.33.1",
|
||||||
"bits-ui": "^2.14.4",
|
"bits-ui": "^2.17.2",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
"eslint": "^9.28.0",
|
"eslint": "^9.28.0",
|
||||||
"eslint-config-prettier": "^10.1.5",
|
"eslint-config-prettier": "^10.1.5",
|
||||||
"eslint-plugin-svelte": "^3.9.1",
|
"eslint-plugin-svelte": "^3.9.1",
|
||||||
@@ -43,39 +46,39 @@
|
|||||||
"postcss": "^8.4.47",
|
"postcss": "^8.4.47",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"prettier-plugin-svelte": "^3.4.0",
|
"prettier-plugin-svelte": "^3.4.0",
|
||||||
|
"shadcn-svelte": "^1.2.7",
|
||||||
"svelte": "^5.33.18",
|
"svelte": "^5.33.18",
|
||||||
"svelte-check": "^4.0.0",
|
"svelte-check": "^4.0.0",
|
||||||
"svelte-dnd-action": "^0.9.65",
|
"svelte-dnd-action": "^0.9.65",
|
||||||
"svelte-sonner": "^1.0.5",
|
"svelte-sonner": "^1.1.0",
|
||||||
"tailwind-variants": "^3.1.1",
|
"tailwind-merge": "^3.5.0",
|
||||||
|
"tailwind-variants": "^3.2.2",
|
||||||
"tailwindcss": "^4.1.8",
|
"tailwindcss": "^4.1.8",
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"tsx": "^4.19.1",
|
"tsx": "^4.19.1",
|
||||||
"tw-animate-css": "^1.3.4",
|
"tw-animate-css": "^1.4.0",
|
||||||
"typescript": "^5.8.3",
|
"typescript": "^5.8.3",
|
||||||
"vaul-svelte": "^1.0.0-next.7",
|
"vaul-svelte": "^1.0.0-next.7",
|
||||||
"vite": "^6.3.5",
|
"vite": "^6.3.5",
|
||||||
"vite-plugin-node-polyfills": "^0.23.0"
|
"vite-plugin-wasm": "^3.6.0"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docsearch/js": "^3.9.0",
|
"@docsearch/js": "^3.9.0",
|
||||||
"@internationalized/date": "^3.8.2",
|
|
||||||
"@mapbox/sphericalmercator": "^2.0.1",
|
"@mapbox/sphericalmercator": "^2.0.1",
|
||||||
"@mapbox/tilebelt": "^2.0.2",
|
"@mapbox/tilebelt": "^2.0.2",
|
||||||
"@maplibre/maplibre-gl-geocoder": "^1.9.4",
|
"@maplibre/maplibre-gl-geocoder": "^1.9.4",
|
||||||
"chart.js": "^4.5.1",
|
"chart.js": "^4.5.1",
|
||||||
"chartjs-plugin-zoom": "^2.2.0",
|
"chartjs-plugin-zoom": "^2.2.0",
|
||||||
"clsx": "^2.1.1",
|
|
||||||
"dexie": "^4.0.11",
|
"dexie": "^4.0.11",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"gpx": "file:../gpx",
|
"gpx": "file:../gpx",
|
||||||
|
"gpx-rs": "file:../gpx-rs/pkg",
|
||||||
"immer": "^10.1.1",
|
"immer": "^10.1.1",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"mapillary-js": "^4.1.2",
|
"mapillary-js": "^4.1.2",
|
||||||
"maplibre-gl": "^5.16.0",
|
"maplibre-gl": "^5.21.1",
|
||||||
"sanitize-html": "^2.17.0",
|
"sanitize-html": "^2.17.0",
|
||||||
"sortablejs": "^1.15.6",
|
"sortablejs": "^1.15.6"
|
||||||
"tailwind-merge": "^3.3.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,76 +1,93 @@
|
|||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
@import 'tw-animate-css';
|
@import 'tw-animate-css';
|
||||||
|
@import "shadcn-svelte/tailwind.css";
|
||||||
|
@import "@fontsource-variable/inter";
|
||||||
|
|
||||||
@custom-variant dark (&:is(.dark *));
|
@custom-variant dark (&:is(.dark *));
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--background: hsl(0 0% 100%) /* <- Wrap in HSL */;
|
--background: oklch(1 0 0);
|
||||||
--foreground: hsl(240 10% 3.9%);
|
--foreground: oklch(0.145 0 0);
|
||||||
--muted: hsl(240 4.8% 95.9%);
|
--muted: oklch(0.97 0 0);
|
||||||
--muted-foreground: hsl(240 3.8% 46.1%);
|
--muted-foreground: oklch(0.556 0 0);
|
||||||
--popover: hsl(0 0% 100%);
|
--popover: oklch(1 0 0);
|
||||||
--popover-foreground: hsl(240 10% 3.9%);
|
--popover-foreground: oklch(0.145 0 0);
|
||||||
--card: hsl(0 0% 100%);
|
--card: oklch(1 0 0);
|
||||||
--card-foreground: hsl(240 10% 3.9%);
|
--card-foreground: oklch(0.145 0 0);
|
||||||
--border: hsl(240 5.9% 90%);
|
--border: oklch(0.922 0 0);
|
||||||
--input: hsl(240 5.9% 90%);
|
--input: oklch(0.922 0 0);
|
||||||
--primary: hsl(240 5.9% 10%);
|
--primary: oklch(0.205 0 0);
|
||||||
--primary-foreground: hsl(0 0% 98%);
|
--primary-foreground: oklch(0.985 0 0);
|
||||||
--secondary: hsl(240 4.8% 95.9%);
|
--secondary: oklch(0.97 0 0);
|
||||||
--secondary-foreground: hsl(240 5.9% 10%);
|
--secondary-foreground: oklch(0.205 0 0);
|
||||||
--accent: hsl(240 4.8% 95.9%);
|
--accent: oklch(0.97 0 0);
|
||||||
--accent-foreground: hsl(240 5.9% 10%);
|
--accent-foreground: oklch(0.205 0 0);
|
||||||
--destructive: hsl(0 72.2% 50.6%);
|
--destructive: oklch(0.577 0.245 27.325);
|
||||||
--destructive-foreground: hsl(0 0% 98%);
|
--destructive-foreground: hsl(0 0% 98%);
|
||||||
--ring: hsl(240 10% 3.9%);
|
--ring: oklch(0.708 0 0);
|
||||||
--sidebar: hsl(0 0% 98%);
|
--sidebar: oklch(0.985 0 0);
|
||||||
--sidebar-foreground: hsl(240 5.3% 26.1%);
|
--sidebar-foreground: oklch(0.145 0 0);
|
||||||
--sidebar-primary: hsl(240 5.9% 10%);
|
--sidebar-primary: oklch(0.205 0 0);
|
||||||
--sidebar-primary-foreground: hsl(0 0% 98%);
|
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-accent: hsl(240 4.8% 95.9%);
|
--sidebar-accent: oklch(0.97 0 0);
|
||||||
--sidebar-accent-foreground: hsl(240 5.9% 10%);
|
--sidebar-accent-foreground: oklch(0.205 0 0);
|
||||||
--sidebar-border: hsl(220 13% 91%);
|
--sidebar-border: oklch(0.922 0 0);
|
||||||
--sidebar-ring: hsl(217.2 91.2% 59.8%);
|
--sidebar-ring: oklch(0.708 0 0);
|
||||||
|
|
||||||
--support: rgb(220 15 130);
|
--support: rgb(220 15 130);
|
||||||
--link: rgb(0 110 180);
|
--link: rgb(0 110 180);
|
||||||
--selection: hsl(240 4.8% 93%);
|
--selection: hsl(240 4.8% 93%);
|
||||||
|
|
||||||
--radius: 0.5rem;
|
--radius: 0.5rem;
|
||||||
|
|
||||||
|
--chart-1: oklch(0.87 0 0);
|
||||||
|
|
||||||
|
--chart-2: oklch(0.556 0 0);
|
||||||
|
|
||||||
|
--chart-3: oklch(0.439 0 0);
|
||||||
|
|
||||||
|
--chart-4: oklch(0.371 0 0);
|
||||||
|
|
||||||
|
--chart-5: oklch(0.269 0 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
--background: hsl(240 10% 3.9%);
|
--background: oklch(0.145 0 0);
|
||||||
--foreground: hsl(0 0% 98%);
|
--foreground: oklch(0.985 0 0);
|
||||||
--muted: hsl(240 3.7% 15.9%);
|
--muted: oklch(0.269 0 0);
|
||||||
--muted-foreground: hsl(240 5% 64.9%);
|
--muted-foreground: oklch(0.708 0 0);
|
||||||
--popover: hsl(240 10% 3.9%);
|
--popover: oklch(0.205 0 0);
|
||||||
--popover-foreground: hsl(0 0% 98%);
|
--popover-foreground: oklch(0.985 0 0);
|
||||||
--card: hsl(240 10% 3.9%);
|
--card: oklch(0.205 0 0);
|
||||||
--card-foreground: hsl(0 0% 98%);
|
--card-foreground: oklch(0.985 0 0);
|
||||||
--border: hsl(240 3.7% 15.9%);
|
--border: oklch(1 0 0 / 10%);
|
||||||
--input: hsl(240 3.7% 15.9%);
|
--input: oklch(1 0 0 / 15%);
|
||||||
--primary: hsl(0 0% 98%);
|
--primary: oklch(0.922 0 0);
|
||||||
--primary-foreground: hsl(240 5.9% 10%);
|
--primary-foreground: oklch(0.205 0 0);
|
||||||
--secondary: hsl(240 3.7% 15.9%);
|
--secondary: oklch(0.269 0 0);
|
||||||
--secondary-foreground: hsl(0 0% 98%);
|
--secondary-foreground: oklch(0.985 0 0);
|
||||||
--accent: hsl(240 3.7% 15.9%);
|
--accent: oklch(0.269 0 0);
|
||||||
--accent-foreground: hsl(0 0% 98%);
|
--accent-foreground: oklch(0.985 0 0);
|
||||||
--destructive: hsl(0 62.8% 30.6%);
|
--destructive: oklch(0.704 0.191 22.216);
|
||||||
--destructive-foreground: hsl(0 0% 98%);
|
--destructive-foreground: hsl(0 0% 98%);
|
||||||
--ring: hsl(240 4.9% 83.9%);
|
--ring: oklch(0.556 0 0);
|
||||||
--sidebar: hsl(240 5.9% 10%);
|
--sidebar: oklch(0.205 0 0);
|
||||||
--sidebar-foreground: hsl(240 4.8% 95.9%);
|
--sidebar-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-primary: hsl(224.3 76.3% 48%);
|
--sidebar-primary: oklch(0.488 0.243 264.376);
|
||||||
--sidebar-primary-foreground: hsl(0 0% 100%);
|
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-accent: hsl(240 3.7% 15.9%);
|
--sidebar-accent: oklch(0.269 0 0);
|
||||||
--sidebar-accent-foreground: hsl(240 4.8% 95.9%);
|
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-border: hsl(240 3.7% 15.9%);
|
--sidebar-border: oklch(1 0 0 / 10%);
|
||||||
--sidebar-ring: hsl(217.2 91.2% 59.8%);
|
--sidebar-ring: oklch(0.556 0 0);
|
||||||
|
|
||||||
--support: rgb(255 110 190);
|
--support: rgb(255 110 190);
|
||||||
--link: rgb(80 190 255);
|
--link: rgb(80 190 255);
|
||||||
--selection: hsl(240 3.7% 22%);
|
--selection: hsl(240 3.7% 22%);
|
||||||
|
--chart-1: oklch(0.87 0 0);
|
||||||
|
--chart-2: oklch(0.556 0 0);
|
||||||
|
--chart-3: oklch(0.439 0 0);
|
||||||
|
--chart-4: oklch(0.371 0 0);
|
||||||
|
--chart-5: oklch(0.269 0 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@theme inline {
|
@theme inline {
|
||||||
@@ -113,14 +130,35 @@
|
|||||||
--color-link: var(--link);
|
--color-link: var(--link);
|
||||||
|
|
||||||
--breakpoint-xs: 540px;
|
--breakpoint-xs: 540px;
|
||||||
|
|
||||||
|
--font-sans: 'Inter Variable', sans-serif;
|
||||||
|
|
||||||
|
--color-chart-5: var(--chart-5);
|
||||||
|
|
||||||
|
--color-chart-4: var(--chart-4);
|
||||||
|
|
||||||
|
--color-chart-3: var(--chart-3);
|
||||||
|
|
||||||
|
--color-chart-2: var(--chart-2);
|
||||||
|
|
||||||
|
--color-chart-1: var(--chart-1);
|
||||||
|
|
||||||
|
--radius-2xl: calc(var(--radius) * 1.8);
|
||||||
|
|
||||||
|
--radius-3xl: calc(var(--radius) * 2.2);
|
||||||
|
|
||||||
|
--radius-4xl: calc(var(--radius) * 2.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
* {
|
* {
|
||||||
@apply border-border;
|
@apply border-border outline-ring/50;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@apply bg-background text-foreground;
|
@apply bg-background text-foreground;
|
||||||
}
|
}
|
||||||
|
html {
|
||||||
|
@apply font-sans;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 313 KiB |
|
After Width: | Height: | Size: 729 KiB |
|
After Width: | Height: | Size: 308 KiB |
|
Before Width: | Height: | Size: 768 KiB After Width: | Height: | Size: 525 KiB |
|
Before Width: | Height: | Size: 596 KiB After Width: | Height: | Size: 710 KiB |
|
Before Width: | Height: | Size: 4.3 MiB |
|
Before Width: | Height: | Size: 5.4 MiB |
|
After Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 3.6 MiB |
|
Before Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 6.9 MiB |
|
Before Width: | Height: | Size: 448 KiB |
@@ -31,9 +31,32 @@ import bikerouterGravel from './custom/bikerouter-gravel.json';
|
|||||||
export const maptilerKeyPlaceHolder = 'MAPTILER_KEY';
|
export const maptilerKeyPlaceHolder = 'MAPTILER_KEY';
|
||||||
|
|
||||||
export const basemaps: { [key: string]: string | StyleSpecification } = {
|
export const basemaps: { [key: string]: string | StyleSpecification } = {
|
||||||
maptilerTopo: `https://api.maptiler.com/maps/topo-v4/style.json?key=${maptilerKeyPlaceHolder}`,
|
libertyTopo: 'https://styles.gpx.studio/liberty-topo.json',
|
||||||
maptilerOutdoors: `https://api.maptiler.com/maps/outdoor-v4/style.json?key=${maptilerKeyPlaceHolder}`,
|
libertySatellite: 'https://styles.gpx.studio/liberty-satellite.json',
|
||||||
maptilerSatellite: `https://api.maptiler.com/maps/hybrid-v4/style.json?key=${maptilerKeyPlaceHolder}`,
|
osm: 'https://styles.gpx.studio/osm.json',
|
||||||
|
osmTopo: 'https://styles.gpx.studio/osm-topo.json',
|
||||||
|
esriSatellite: {
|
||||||
|
version: 8,
|
||||||
|
sources: {
|
||||||
|
esriSatellite: {
|
||||||
|
type: 'raster',
|
||||||
|
tiles: [
|
||||||
|
'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/WMTS/tile/1.0.0/World_Imagery/default/default028mm/{z}/{y}/{x}.jpg',
|
||||||
|
],
|
||||||
|
tileSize: 256,
|
||||||
|
maxzoom: 19,
|
||||||
|
attribution:
|
||||||
|
'© <a href="https://www.esri.com/" target="_blank">Esri</a>, Vantor, Earthstar Geographics, and the GIS User Community',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
layers: [
|
||||||
|
{
|
||||||
|
id: 'esriSatellite',
|
||||||
|
type: 'raster',
|
||||||
|
source: 'esriSatellite',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
openStreetMap: {
|
openStreetMap: {
|
||||||
version: 8,
|
version: 8,
|
||||||
sources: {
|
sources: {
|
||||||
@@ -776,9 +799,11 @@ export type LayerTreeType = { [key: string]: LayerTreeType | boolean };
|
|||||||
export const basemapTree: LayerTreeType = {
|
export const basemapTree: LayerTreeType = {
|
||||||
basemaps: {
|
basemaps: {
|
||||||
world: {
|
world: {
|
||||||
maptilerTopo: true,
|
libertyTopo: true,
|
||||||
maptilerOutdoors: true,
|
libertySatellite: true,
|
||||||
maptilerSatellite: true,
|
osm: true,
|
||||||
|
osmTopo: true,
|
||||||
|
esriSatellite: true,
|
||||||
openStreetMap: true,
|
openStreetMap: true,
|
||||||
openTopoMap: true,
|
openTopoMap: true,
|
||||||
openHikingMap: true,
|
openHikingMap: true,
|
||||||
@@ -911,7 +936,7 @@ export const overpassTree: LayerTreeType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Default basemap used
|
// Default basemap used
|
||||||
export const defaultBasemap = 'maptilerTopo';
|
export const defaultBasemap = 'libertyTopo';
|
||||||
|
|
||||||
// Default overlays used (none)
|
// Default overlays used (none)
|
||||||
export const defaultOverlays: LayerTreeType = {
|
export const defaultOverlays: LayerTreeType = {
|
||||||
@@ -1000,9 +1025,11 @@ export const defaultOverpassQueries: LayerTreeType = {
|
|||||||
export const defaultBasemapTree: LayerTreeType = {
|
export const defaultBasemapTree: LayerTreeType = {
|
||||||
basemaps: {
|
basemaps: {
|
||||||
world: {
|
world: {
|
||||||
maptilerTopo: true,
|
libertyTopo: true,
|
||||||
maptilerOutdoors: true,
|
libertySatellite: true,
|
||||||
maptilerSatellite: true,
|
osm: true,
|
||||||
|
osmTopo: true,
|
||||||
|
esriSatellite: false,
|
||||||
openStreetMap: true,
|
openStreetMap: true,
|
||||||
openTopoMap: true,
|
openTopoMap: true,
|
||||||
openHikingMap: true,
|
openHikingMap: true,
|
||||||
@@ -1422,7 +1449,7 @@ export const overpassQueryData: Record<string, OverpassQueryData> = {
|
|||||||
color: 'DarkBlue',
|
color: 'DarkBlue',
|
||||||
},
|
},
|
||||||
tags: {
|
tags: {
|
||||||
railway: 'station',
|
railway: ['station', 'halt'],
|
||||||
},
|
},
|
||||||
symbol: 'Ground Transportation',
|
symbol: 'Ground Transportation',
|
||||||
},
|
},
|
||||||
@@ -1460,14 +1487,11 @@ export const overpassQueryData: Record<string, OverpassQueryData> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const terrainSources: { [key: string]: RasterDEMSourceSpecification } = {
|
export const terrainSources: { [key: string]: RasterDEMSourceSpecification } = {
|
||||||
'maptiler-dem': {
|
|
||||||
type: 'raster-dem',
|
|
||||||
url: `https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key=${maptilerKeyPlaceHolder}`,
|
|
||||||
},
|
|
||||||
mapterhorn: {
|
mapterhorn: {
|
||||||
type: 'raster-dem',
|
type: 'raster-dem',
|
||||||
url: 'https://tiles.mapterhorn.com/tilejson.json',
|
url: 'https://tiles.gpx.studio/mapterhorn.json',
|
||||||
|
encoding: 'terrarium',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultTerrainSource = 'maptiler-dem';
|
export const defaultTerrainSource = 'mapterhorn';
|
||||||
|
|||||||
@@ -64,3 +64,9 @@
|
|||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<div id="docsearch" class={props.class ?? ''}></div>
|
<div id="docsearch" class={props.class ?? ''}></div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#docsearch :global(button) {
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<Tooltip.Root>
|
<Tooltip.Root>
|
||||||
<Tooltip.Trigger>
|
<Tooltip.Trigger>
|
||||||
{#snippet child({ props })}
|
{#snippet child({ props })}
|
||||||
<Button {...props} {variant} class={className} {onclick}>
|
<Button {...props} {variant} class="bg-inherit {className}" {onclick}>
|
||||||
{@render children()}
|
{@render children()}
|
||||||
</Button>
|
</Button>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
|||||||
@@ -1,116 +1,118 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import LanguageSelect from '$lib/components/LanguageSelect.svelte';
|
import LanguageSelect from '$lib/components/LanguageSelect.svelte';
|
||||||
|
import ModeSwitch from '$lib/components/ModeSwitch.svelte';
|
||||||
import Logo from '$lib/components/Logo.svelte';
|
import Logo from '$lib/components/Logo.svelte';
|
||||||
import { AtSign, BookOpenText, Heart, House, Map } from '@lucide/svelte';
|
import { AtSign, BookOpenText, Heart, House, Map } from '@lucide/svelte';
|
||||||
import { i18n } from '$lib/i18n.svelte';
|
import { i18n } from '$lib/i18n.svelte';
|
||||||
import { getURLForLanguage } from '$lib/utils';
|
import { getURLForLanguage } from '$lib/utils';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<footer class="w-full">
|
<footer class="w-full px-12 py-10 border-t flex flex-col items-center">
|
||||||
<div class="mx-6 border-t">
|
<div class="w-full max-w-5xl flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
|
||||||
<div class="mx-12 py-10 flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
|
<div class="grow flex flex-col items-start">
|
||||||
<div class="grow flex flex-col items-start">
|
<Logo class="h-8" width="153" />
|
||||||
<Logo class="h-8" width="153" />
|
<Button
|
||||||
|
variant="link"
|
||||||
|
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||||
|
href="https://github.com/gpxstudio/gpx.studio/blob/main/LICENSE"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
MIT © 2026 gpx.studio
|
||||||
|
</Button>
|
||||||
|
<div class="mt-3 flex flex-row gap-1.5">
|
||||||
|
<LanguageSelect />
|
||||||
|
<ModeSwitch />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="grow max-w-2xl flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
|
||||||
|
<div class="flex flex-col items-start gap-1">
|
||||||
|
<span class="font-semibold">{i18n._('homepage.website')}</span>
|
||||||
<Button
|
<Button
|
||||||
variant="link"
|
variant="link"
|
||||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||||
href="https://github.com/gpxstudio/gpx.studio/blob/main/LICENSE"
|
href={getURLForLanguage(i18n.lang, '/')}
|
||||||
|
>
|
||||||
|
<House size="16" />
|
||||||
|
{i18n._('homepage.home')}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
data-sveltekit-reload
|
||||||
|
variant="link"
|
||||||
|
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||||
|
href={getURLForLanguage(i18n.lang, '/app')}
|
||||||
|
>
|
||||||
|
<Map size="16" />
|
||||||
|
{i18n._('homepage.app')}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="link"
|
||||||
|
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||||
|
href={getURLForLanguage(i18n.lang, '/help')}
|
||||||
|
>
|
||||||
|
<BookOpenText size="16" />
|
||||||
|
{i18n._('menu.help')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col items-start gap-1" id="contact">
|
||||||
|
<span class="font-semibold">{i18n._('homepage.contact')}</span>
|
||||||
|
<Button
|
||||||
|
variant="link"
|
||||||
|
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||||
|
href="https://www.reddit.com/r/gpxstudio/"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
MIT © 2026 gpx.studio
|
<Logo company="reddit" class="h-4 fill-muted-foreground" />
|
||||||
|
{i18n._('homepage.reddit')}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="link"
|
||||||
|
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||||
|
href="https://facebook.com/gpx.studio"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<Logo company="facebook" class="h-4 fill-muted-foreground" />
|
||||||
|
{i18n._('homepage.facebook')}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="link"
|
||||||
|
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||||
|
href="mailto:hello@gpx.studio"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<AtSign size="16" />
|
||||||
|
{i18n._('homepage.email')}
|
||||||
</Button>
|
</Button>
|
||||||
<LanguageSelect class="w-40 mt-3" />
|
|
||||||
</div>
|
</div>
|
||||||
<div class="grow max-w-2xl flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
|
<div class="flex flex-col items-start gap-1">
|
||||||
<div class="flex flex-col items-start gap-1">
|
<span class="font-semibold">{i18n._('homepage.contribute')}</span>
|
||||||
<span class="font-semibold">{i18n._('homepage.website')}</span>
|
<Button
|
||||||
<Button
|
variant="link"
|
||||||
variant="link"
|
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
href="https://opencollective.com/gpxstudio"
|
||||||
href={getURLForLanguage(i18n.lang, '/')}
|
target="_blank"
|
||||||
>
|
>
|
||||||
<House size="16" />
|
<Heart size="16" />
|
||||||
{i18n._('homepage.home')}
|
{i18n._('menu.donate')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
data-sveltekit-reload
|
variant="link"
|
||||||
variant="link"
|
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
href="https://crowdin.com/project/gpxstudio"
|
||||||
href={getURLForLanguage(i18n.lang, '/app')}
|
target="_blank"
|
||||||
>
|
>
|
||||||
<Map size="16" />
|
<Logo company="crowdin" class="h-4 fill-muted-foreground" />
|
||||||
{i18n._('homepage.app')}
|
{i18n._('homepage.crowdin')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="link"
|
variant="link"
|
||||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||||
href={getURLForLanguage(i18n.lang, '/help')}
|
href="https://github.com/gpxstudio/gpx.studio"
|
||||||
>
|
target="_blank"
|
||||||
<BookOpenText size="16" />
|
>
|
||||||
{i18n._('menu.help')}
|
<Logo company="github" class="h-4 fill-muted-foreground" />
|
||||||
</Button>
|
{i18n._('homepage.github')}
|
||||||
</div>
|
</Button>
|
||||||
<div class="flex flex-col items-start gap-1" id="contact">
|
|
||||||
<span class="font-semibold">{i18n._('homepage.contact')}</span>
|
|
||||||
<Button
|
|
||||||
variant="link"
|
|
||||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
|
||||||
href="https://www.reddit.com/r/gpxstudio/"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<Logo company="reddit" class="h-4 fill-muted-foreground" />
|
|
||||||
{i18n._('homepage.reddit')}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="link"
|
|
||||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
|
||||||
href="https://facebook.com/gpx.studio"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<Logo company="facebook" class="h-4 fill-muted-foreground" />
|
|
||||||
{i18n._('homepage.facebook')}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="link"
|
|
||||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
|
||||||
href="mailto:hello@gpx.studio"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<AtSign size="16" />
|
|
||||||
{i18n._('homepage.email')}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col items-start gap-1">
|
|
||||||
<span class="font-semibold">{i18n._('homepage.contribute')}</span>
|
|
||||||
<Button
|
|
||||||
variant="link"
|
|
||||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
|
||||||
href="https://ko-fi.com/gpxstudio"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<Heart size="16" />
|
|
||||||
{i18n._('menu.donate')}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="link"
|
|
||||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
|
||||||
href="https://crowdin.com/project/gpxstudio"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<Logo company="crowdin" class="h-4 fill-muted-foreground" />
|
|
||||||
{i18n._('homepage.crowdin')}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="link"
|
|
||||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
|
||||||
href="https://github.com/gpxstudio/gpx.studio"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<Logo company="github" class="h-4 fill-muted-foreground" />
|
|
||||||
{i18n._('homepage.github')}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,16 +12,17 @@
|
|||||||
|
|
||||||
const { velocityUnits } = settings;
|
const { velocityUnits } = settings;
|
||||||
|
|
||||||
|
let panelHeight: number = $state(0);
|
||||||
|
let panelWidth: number = $state(0);
|
||||||
|
|
||||||
let {
|
let {
|
||||||
gpxStatistics,
|
gpxStatistics,
|
||||||
slicedGPXStatistics,
|
slicedGPXStatistics,
|
||||||
orientation,
|
orientation,
|
||||||
panelSize,
|
|
||||||
}: {
|
}: {
|
||||||
gpxStatistics: Readable<GPXStatisticsGroup>;
|
gpxStatistics: Readable<GPXStatisticsGroup>;
|
||||||
slicedGPXStatistics: Readable<[GPXGlobalStatistics, number, number] | undefined>;
|
slicedGPXStatistics: Readable<[GPXGlobalStatistics, number, number] | undefined>;
|
||||||
orientation: 'horizontal' | 'vertical';
|
orientation: 'horizontal' | 'vertical';
|
||||||
panelSize: number;
|
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
let statistics = $derived(
|
let statistics = $derived(
|
||||||
@@ -32,58 +33,60 @@
|
|||||||
<Card.Root
|
<Card.Root
|
||||||
class="h-full {orientation === 'vertical'
|
class="h-full {orientation === 'vertical'
|
||||||
? 'min-w-40 sm:min-w-44'
|
? 'min-w-40 sm:min-w-44'
|
||||||
: 'w-full h-10'} border-none shadow-none p-0 text-sm sm:text-base"
|
: 'w-full h-fit my-1'} ring-0 p-0 text-sm sm:text-base bg-transparent"
|
||||||
>
|
>
|
||||||
<Card.Content
|
<Card.Content class="h-full p-0">
|
||||||
class="h-full flex {orientation === 'vertical'
|
<div
|
||||||
? 'flex-col justify-center'
|
bind:clientHeight={panelHeight}
|
||||||
: 'flex-row w-full justify-evenly'} gap-4 p-0"
|
bind:clientWidth={panelWidth}
|
||||||
>
|
class="flex {orientation === 'vertical'
|
||||||
<Tooltip label={i18n._('quantities.distance')}>
|
? 'flex-col h-full justify-center'
|
||||||
<span class="flex flex-row items-center">
|
: 'flex-row w-full justify-evenly'} gap-4"
|
||||||
<Ruler size="16" class="mr-1" />
|
>
|
||||||
<WithUnits value={statistics.distance.total} type="distance" />
|
<Tooltip label={i18n._('quantities.distance')}>
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip label={i18n._('quantities.elevation_gain_loss')}>
|
|
||||||
<span class="flex flex-row items-center">
|
|
||||||
<MoveUpRight size="16" class="mr-1" />
|
|
||||||
<WithUnits value={statistics.elevation.gain} type="elevation" />
|
|
||||||
<MoveDownRight size="16" class="mx-1" />
|
|
||||||
<WithUnits value={statistics.elevation.loss} type="elevation" />
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
{#if panelSize > 120 || orientation === 'horizontal'}
|
|
||||||
<Tooltip
|
|
||||||
class={orientation === 'horizontal' ? 'hidden xs:block' : ''}
|
|
||||||
label="{$velocityUnits === 'speed'
|
|
||||||
? i18n._('quantities.speed')
|
|
||||||
: i18n._('quantities.pace')} ({i18n._('quantities.moving')} / {i18n._(
|
|
||||||
'quantities.total'
|
|
||||||
)})"
|
|
||||||
>
|
|
||||||
<span class="flex flex-row items-center">
|
<span class="flex flex-row items-center">
|
||||||
<Zap size="16" class="mr-1" />
|
<Ruler size="16" class="mr-1" />
|
||||||
<WithUnits value={statistics.speed.moving} type="speed" showUnits={false} />
|
<WithUnits value={statistics.distance.total} type="distance" />
|
||||||
<span class="mx-1">/</span>
|
|
||||||
<WithUnits value={statistics.speed.total} type="speed" />
|
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{/if}
|
<Tooltip label={i18n._('quantities.elevation_gain_loss')}>
|
||||||
{#if panelSize > 160 || orientation === 'horizontal'}
|
|
||||||
<Tooltip
|
|
||||||
class={orientation === 'horizontal' ? 'hidden md:block' : ''}
|
|
||||||
label="{i18n._('quantities.time')} ({i18n._('quantities.moving')} / {i18n._(
|
|
||||||
'quantities.total'
|
|
||||||
)})"
|
|
||||||
>
|
|
||||||
<span class="flex flex-row items-center">
|
<span class="flex flex-row items-center">
|
||||||
<Timer size="16" class="mr-1" />
|
<MoveUpRight size="16" class="mr-1" />
|
||||||
<WithUnits value={statistics.time.moving} type="time" />
|
<WithUnits value={statistics.elevation.gain} type="elevation" />
|
||||||
<span class="mx-1">/</span>
|
<MoveDownRight size="16" class="mx-1" />
|
||||||
<WithUnits value={statistics.time.total} type="time" />
|
<WithUnits value={statistics.elevation.loss} type="elevation" />
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{/if}
|
{#if panelHeight > 120 || (orientation === 'horizontal' && panelWidth > 450)}
|
||||||
|
<Tooltip
|
||||||
|
label="{$velocityUnits === 'speed'
|
||||||
|
? i18n._('quantities.speed')
|
||||||
|
: i18n._('quantities.pace')} ({i18n._('quantities.moving')} / {i18n._(
|
||||||
|
'quantities.total'
|
||||||
|
)})"
|
||||||
|
>
|
||||||
|
<span class="flex flex-row items-center">
|
||||||
|
<Zap size="16" class="mr-1" />
|
||||||
|
<WithUnits value={statistics.speed.moving} type="speed" showUnits={false} />
|
||||||
|
<span class="mx-1">/</span>
|
||||||
|
<WithUnits value={statistics.speed.total} type="speed" />
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
{/if}
|
||||||
|
{#if panelHeight > 150 || (orientation === 'horizontal' && panelWidth > 620)}
|
||||||
|
<Tooltip
|
||||||
|
label="{i18n._('quantities.time')} ({i18n._('quantities.moving')} / {i18n._(
|
||||||
|
'quantities.total'
|
||||||
|
)})"
|
||||||
|
>
|
||||||
|
<span class="flex flex-row items-center">
|
||||||
|
<Timer size="16" class="mr-1" />
|
||||||
|
<WithUnits value={statistics.time.moving} type="time" />
|
||||||
|
<span class="mx-1">/</span>
|
||||||
|
<WithUnits value={statistics.time.total} type="time" />
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
</Card.Root>
|
</Card.Root>
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="text-sm bg-secondary rounded border flex flex-row items-center p-2 {className}">
|
<div class="text-[13px] bg-secondary rounded border flex flex-row items-center p-2 {className}">
|
||||||
<CircleQuestionMark size="16" class="w-4 mr-2 shrink-0 grow-0" />
|
<CircleQuestionMark size="16" class="w-4 mr-2 shrink-0 grow-0" />
|
||||||
<div>
|
<div>
|
||||||
{@render children()}
|
{@render children()}
|
||||||
{#if link}
|
{#if link}
|
||||||
<a href={link} target="_blank" class="text-sm text-link hover:underline">
|
<a href={link} target="_blank" class="text-[13px] text-link hover:underline">
|
||||||
{i18n._('menu.more')}
|
{i18n._('menu.more')}
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -5,16 +5,10 @@
|
|||||||
import { getURLForLanguage } from '$lib/utils';
|
import { getURLForLanguage } from '$lib/utils';
|
||||||
import { Languages } from '@lucide/svelte';
|
import { Languages } from '@lucide/svelte';
|
||||||
import { i18n } from '$lib/i18n.svelte';
|
import { i18n } from '$lib/i18n.svelte';
|
||||||
|
|
||||||
let {
|
|
||||||
class: className = '',
|
|
||||||
}: {
|
|
||||||
class?: string;
|
|
||||||
} = $props();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Select.Root type="single" value={i18n.lang}>
|
<Select.Root type="single" value={i18n.lang}>
|
||||||
<Select.Trigger class="min-w-[180px] {className}" aria-label={i18n._('menu.language')}>
|
<Select.Trigger class="w-[180px] px-2" aria-label={i18n._('menu.language')}>
|
||||||
<Languages size="16" />
|
<Languages size="16" />
|
||||||
<span class="mr-auto">
|
<span class="mr-auto">
|
||||||
{languages[i18n.lang]}
|
{languages[i18n.lang]}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
...others
|
...others
|
||||||
}: {
|
}: {
|
||||||
iconOnly?: boolean;
|
iconOnly?: boolean;
|
||||||
company?: 'gpx.studio' | 'maptiler' | 'github' | 'crowdin' | 'facebook' | 'reddit';
|
company?: 'gpx.studio' | 'github' | 'crowdin' | 'facebook' | 'reddit';
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
@@ -19,12 +19,6 @@
|
|||||||
alt="Logo of gpx.studio."
|
alt="Logo of gpx.studio."
|
||||||
{...others}
|
{...others}
|
||||||
/>
|
/>
|
||||||
{:else if company === 'maptiler'}
|
|
||||||
<img
|
|
||||||
src="{base}/maptiler-logo{mode.current === 'dark' ? '-dark' : ''}.svg"
|
|
||||||
alt="Logo of Maptiler."
|
|
||||||
{...others}
|
|
||||||
/>
|
|
||||||
{:else if company === 'github'}
|
{:else if company === 'github'}
|
||||||
<svg
|
<svg
|
||||||
role="img"
|
role="img"
|
||||||
|
|||||||
@@ -43,6 +43,8 @@
|
|||||||
BookOpenText,
|
BookOpenText,
|
||||||
ChartArea,
|
ChartArea,
|
||||||
Maximize,
|
Maximize,
|
||||||
|
Maximize2,
|
||||||
|
Minimize2,
|
||||||
} from '@lucide/svelte';
|
} from '@lucide/svelte';
|
||||||
import { map } from '$lib/components/map/map';
|
import { map } from '$lib/components/map/map';
|
||||||
import { editMetadata } from '$lib/components/file-list/metadata/utils.svelte';
|
import { editMetadata } from '$lib/components/file-list/metadata/utils.svelte';
|
||||||
@@ -70,7 +72,7 @@
|
|||||||
import { copied, selection } from '$lib/logic/selection';
|
import { copied, selection } from '$lib/logic/selection';
|
||||||
import { allHidden } from '$lib/logic/hidden';
|
import { allHidden } from '$lib/logic/hidden';
|
||||||
import { boundsManager } from '$lib/logic/bounds';
|
import { boundsManager } from '$lib/logic/bounds';
|
||||||
import { tick } from 'svelte';
|
import { tick, onMount } from 'svelte';
|
||||||
import { allowedPastes } from '$lib/components/file-list/sortable-file-list';
|
import { allowedPastes } from '$lib/components/file-list/sortable-file-list';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -105,6 +107,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let layerSettingsOpen = $state(false);
|
let layerSettingsOpen = $state(false);
|
||||||
|
let fullscreen = $state(false);
|
||||||
|
|
||||||
|
function toggleFullscreen() {
|
||||||
|
if (!document.fullscreenElement) {
|
||||||
|
document.documentElement.requestFullscreen?.();
|
||||||
|
} else {
|
||||||
|
document.exitFullscreen?.();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
const handler = () => {
|
||||||
|
fullscreen = document.fullscreenElement !== null;
|
||||||
|
};
|
||||||
|
document.addEventListener('fullscreenchange', handler);
|
||||||
|
return () => document.removeEventListener('fullscreenchange', handler);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="absolute md:top-2 left-0 right-0 z-20 flex flex-row justify-center pointer-events-none">
|
<div class="absolute md:top-2 left-0 right-0 z-20 flex flex-row justify-center pointer-events-none">
|
||||||
@@ -375,8 +394,18 @@
|
|||||||
<Menubar.Item inset onclick={() => map.toggle3D()}>
|
<Menubar.Item inset onclick={() => map.toggle3D()}>
|
||||||
<Box size="16" />
|
<Box size="16" />
|
||||||
{i18n._('menu.toggle_3d')}
|
{i18n._('menu.toggle_3d')}
|
||||||
<Shortcut key="{i18n._('menu.ctrl')} {i18n._('menu.drag')}" />
|
<Shortcut key={i18n._('menu.right_click_drag')} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
|
<Menubar.Separator />
|
||||||
|
<Menubar.CheckboxItem checked={fullscreen} onCheckedChange={toggleFullscreen}>
|
||||||
|
{#if fullscreen}
|
||||||
|
<Minimize2 size="16" />
|
||||||
|
{:else}
|
||||||
|
<Maximize2 size="16" />
|
||||||
|
{/if}
|
||||||
|
{i18n._('menu.fullscreen')}
|
||||||
|
<Shortcut key="F11" />
|
||||||
|
</Menubar.CheckboxItem>
|
||||||
</Menubar.Content>
|
</Menubar.Content>
|
||||||
</Menubar.Menu>
|
</Menubar.Menu>
|
||||||
<Menubar.Menu>
|
<Menubar.Menu>
|
||||||
@@ -389,7 +418,7 @@
|
|||||||
<Menubar.Content class="border-none">
|
<Menubar.Content class="border-none">
|
||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
<Ruler size="16" class="mr-2" />{i18n._('menu.distance_units')}
|
<Ruler size="16" />{i18n._('menu.distance_units')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
<Menubar.RadioGroup bind:value={$distanceUnits}>
|
<Menubar.RadioGroup bind:value={$distanceUnits}>
|
||||||
@@ -407,7 +436,7 @@
|
|||||||
</Menubar.Sub>
|
</Menubar.Sub>
|
||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
<Zap size="16" class="mr-2" />{i18n._('menu.velocity_units')}
|
<Zap size="16" />{i18n._('menu.velocity_units')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
<Menubar.RadioGroup bind:value={$velocityUnits}>
|
<Menubar.RadioGroup bind:value={$velocityUnits}>
|
||||||
@@ -422,7 +451,7 @@
|
|||||||
</Menubar.Sub>
|
</Menubar.Sub>
|
||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
<Thermometer size="16" class="mr-2" />{i18n._('menu.temperature_units')}
|
<Thermometer size="16" />{i18n._('menu.temperature_units')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
<Menubar.RadioGroup bind:value={$temperatureUnits}>
|
<Menubar.RadioGroup bind:value={$temperatureUnits}>
|
||||||
@@ -438,7 +467,7 @@
|
|||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
<Languages size="16" class="mr-2" />
|
<Languages size="16" />
|
||||||
{i18n._('menu.language')}
|
{i18n._('menu.language')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
@@ -454,9 +483,9 @@
|
|||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
{#if mode.current === 'light' || !mode.current}
|
{#if mode.current === 'light' || !mode.current}
|
||||||
<Sun size="16" class="mr-2" />
|
<Sun size="16" />
|
||||||
{:else}
|
{:else}
|
||||||
<Moon size="16" class="mr-2" />
|
<Moon size="16" />
|
||||||
{/if}
|
{/if}
|
||||||
{i18n._('menu.mode')}
|
{i18n._('menu.mode')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
@@ -479,7 +508,7 @@
|
|||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
<PersonStanding size="16" class="mr-2" />
|
<PersonStanding size="16" />
|
||||||
{i18n._('menu.street_view_source')}
|
{i18n._('menu.street_view_source')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
@@ -500,12 +529,12 @@
|
|||||||
</Menubar.Content>
|
</Menubar.Content>
|
||||||
</Menubar.Menu>
|
</Menubar.Menu>
|
||||||
</Menubar.Root>
|
</Menubar.Root>
|
||||||
<div class="h-fit flex flex-row items-center ml-1 gap-1">
|
<div class="h-fit flex flex-row items-center">
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
href="./help"
|
href="./help"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="cursor-default h-fit rounded-sm px-3 py-0.5"
|
class="cursor-default h-fit rounded-md px-3 py-0.5"
|
||||||
aria-label={i18n._('menu.help')}
|
aria-label={i18n._('menu.help')}
|
||||||
>
|
>
|
||||||
<BookOpenText size="18" class="md:hidden" />
|
<BookOpenText size="18" class="md:hidden" />
|
||||||
@@ -515,9 +544,9 @@
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
href="https://ko-fi.com/gpxstudio"
|
href="https://opencollective.com/gpxstudio"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="cursor-default h-fit rounded-sm font-bold text-support hover:text-support px-3 py-0.5"
|
class="cursor-default h-fit rounded-md font-bold text-support hover:text-support px-3 py-0.5"
|
||||||
aria-label={i18n._('menu.donate')}
|
aria-label={i18n._('menu.donate')}
|
||||||
>
|
>
|
||||||
<HeartHandshake size="18" class="md:hidden" />
|
<HeartHandshake size="18" class="md:hidden" />
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="outline"
|
||||||
size="icon"
|
size="icon"
|
||||||
class={className}
|
class={className}
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Logo from '$lib/components/Logo.svelte';
|
import Logo from '$lib/components/Logo.svelte';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import AlgoliaDocSearch from '$lib/components/AlgoliaDocSearch.svelte';
|
|
||||||
import ModeSwitch from '$lib/components/ModeSwitch.svelte';
|
|
||||||
import { BookOpenText, House, Map } from '@lucide/svelte';
|
import { BookOpenText, House, Map } from '@lucide/svelte';
|
||||||
import { i18n } from '$lib/i18n.svelte';
|
import { i18n } from '$lib/i18n.svelte';
|
||||||
import { getURLForLanguage } from '$lib/utils';
|
import { getURLForLanguage } from '$lib/utils';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<nav class="w-full sticky top-0 bg-background z-50">
|
<nav class="sticky top-0 w-full px-12 py-2 bg-background z-50 flex flex-col items-center border-b">
|
||||||
<div class="mx-6 py-2 flex flex-row items-center border-b gap-4 sm:gap-8">
|
<div class="w-full max-w-5xl flex flex-row items-center gap-4 sm:gap-8">
|
||||||
<a href={getURLForLanguage(i18n.lang, '/')} class="shrink-0 translate-y-0.5">
|
<a
|
||||||
<Logo class="h-8 sm:hidden" iconOnly={true} width="26" />
|
href={getURLForLanguage(i18n.lang, '/')}
|
||||||
<Logo class="h-8 hidden sm:block" width="153" />
|
class="shrink-0 translate-y-0.25 justify-self-start"
|
||||||
|
>
|
||||||
|
<Logo class="h-8 xs:hidden" iconOnly={true} width="26" />
|
||||||
|
<Logo class="h-8 hidden xs:block" width="153" />
|
||||||
</a>
|
</a>
|
||||||
<Button
|
<Button
|
||||||
variant="link"
|
variant="link"
|
||||||
class="text-base px-0 has-[>svg]:px-0"
|
class="text-base px-0 has-[>svg]:px-0 ml-auto"
|
||||||
href={getURLForLanguage(i18n.lang, '/')}
|
href={getURLForLanguage(i18n.lang, '/')}
|
||||||
>
|
>
|
||||||
<House size="18" />
|
<House size="18" />
|
||||||
@@ -39,7 +40,5 @@
|
|||||||
<BookOpenText size="18" />
|
<BookOpenText size="18" />
|
||||||
{i18n._('menu.help')}
|
{i18n._('menu.help')}
|
||||||
</Button>
|
</Button>
|
||||||
<AlgoliaDocSearch class="ml-auto" />
|
|
||||||
<ModeSwitch class="hidden xs:inline-flex" />
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
class="w-full flex flex-row gap-1 {side === 'right'
|
class="w-full flex flex-row gap-1 border-none {side === 'right'
|
||||||
? 'justify-between'
|
? 'justify-between'
|
||||||
: 'justify-start pl-1'} h-fit {nohover
|
: 'justify-start pl-1'} h-fit {nohover
|
||||||
? 'hover:bg-background'
|
? 'hover:bg-background'
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
class="w-full flex flex-row gap-1 {side === 'right'
|
class="w-full flex flex-row gap-1 border-none {side === 'right'
|
||||||
? 'justify-between'
|
? 'justify-between'
|
||||||
: 'justify-start pl-1'} h-fit {nohover ? 'hover:bg-background' : ''}"
|
: 'justify-start pl-1'} h-fit {nohover ? 'hover:bg-background' : ''}"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
@apply text-foreground;
|
@apply text-foreground;
|
||||||
@apply text-3xl;
|
@apply text-3xl;
|
||||||
@apply font-semibold;
|
@apply font-semibold;
|
||||||
@apply mb-3 pt-6;
|
@apply mb-3;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown h2) {
|
:global(.markdown h2) {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<div class="rounded-md overflow-hidden overflow-clip shadow-xl mx-auto">
|
<div class="rounded-md overflow-hidden overflow-clip shadow-xl mx-auto">
|
||||||
{#if src === 'getting-started/interface'}
|
{#if src === 'getting-started/interface'}
|
||||||
<enhanced:img
|
<enhanced:img
|
||||||
src="/src/lib/assets/img/docs/getting-started/interface.png"
|
src="/src/lib/assets/img/docs/getting-started/interface.webp"
|
||||||
{alt}
|
{alt}
|
||||||
class="w-full max-w-3xl"
|
class="w-full max-w-3xl"
|
||||||
/>
|
/>
|
||||||
@@ -20,13 +20,13 @@
|
|||||||
<enhanced:img
|
<enhanced:img
|
||||||
src="/src/lib/assets/img/docs/tools/routing.png"
|
src="/src/lib/assets/img/docs/tools/routing.png"
|
||||||
{alt}
|
{alt}
|
||||||
class="w-full max-w-3xl"
|
class="w-full max-w-lg"
|
||||||
/>
|
/>
|
||||||
{:else if src === 'tools/split'}
|
{:else if src === 'tools/split'}
|
||||||
<enhanced:img
|
<enhanced:img
|
||||||
src="/src/lib/assets/img/docs/tools/split.png"
|
src="/src/lib/assets/img/docs/tools/split.png"
|
||||||
{alt}
|
{alt}
|
||||||
class="w-full max-w-3xl"
|
class="w-full max-w-lg"
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import maptilerTopoMap from '$lib/assets/img/home/maptiler-topo.png?enhanced';
|
import topoMap from '$lib/assets/img/docs/maps/topo.png?enhanced';
|
||||||
import waymarkedMap from '$lib/assets/img/home/waymarked.png?enhanced';
|
import waymarkedMap from '$lib/assets/img/docs/maps/waymarked.png?enhanced';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="relative h-80 aspect-square rounded-2xl shadow-xl overflow-clip">
|
<div class="relative h-80 aspect-square rounded-2xl shadow-xl overflow-clip">
|
||||||
<enhanced:img src={maptilerTopoMap} alt="MapTiler Topo map screenshot." class="absolute" />
|
<enhanced:img src={topoMap} alt="Topo map screenshot." class="absolute" />
|
||||||
<enhanced:img
|
<enhanced:img
|
||||||
src={waymarkedMap}
|
src={waymarkedMap}
|
||||||
alt="Waymarked Trails map screenshot."
|
alt="Waymarked Trails map screenshot."
|
||||||
|
|||||||
@@ -68,33 +68,31 @@
|
|||||||
<canvas bind:this={overlay} class="w-full h-full absolute pointer-events-none"></canvas>
|
<canvas bind:this={overlay} class="w-full h-full absolute pointer-events-none"></canvas>
|
||||||
<canvas bind:this={canvas} class="w-full h-full absolute"></canvas>
|
<canvas bind:this={canvas} class="w-full h-full absolute"></canvas>
|
||||||
{#if showControls}
|
{#if showControls}
|
||||||
<div class="absolute bottom-10 right-1.5">
|
<div class="absolute bottom-9 right-2.5">
|
||||||
<Popover.Root>
|
<Popover.Root>
|
||||||
<Popover.Trigger>
|
<Popover.Trigger>
|
||||||
<ButtonWithTooltip
|
<ButtonWithTooltip
|
||||||
label={i18n._('chart.settings')}
|
label={i18n._('chart.settings')}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
side="left"
|
side="left"
|
||||||
class="w-7 h-7 p-0 flex justify-center opacity-70 hover:opacity-100 transition-opacity duration-300 hover:bg-background"
|
class="w-7 h-7 p-0 flex justify-center opacity-70 hover:opacity-100 transition-opacity duration-300 bg-background"
|
||||||
>
|
>
|
||||||
<ChartNoAxesColumn size="18" />
|
<ChartNoAxesColumn size="18" />
|
||||||
</ButtonWithTooltip>
|
</ButtonWithTooltip>
|
||||||
</Popover.Trigger>
|
</Popover.Trigger>
|
||||||
<Popover.Content
|
<Popover.Content
|
||||||
class="w-fit p-0 flex flex-col"
|
class="w-fit p-0 flex flex-col gap-0 overflow-hidden"
|
||||||
side="top"
|
side="top"
|
||||||
align="end"
|
align="end"
|
||||||
sideOffset={-32}
|
sideOffset={-32}
|
||||||
>
|
>
|
||||||
<ToggleGroup.Root
|
<ToggleGroup.Root
|
||||||
class="flex flex-col items-start gap-0 p-1 w-full border-none"
|
class="flex flex-col w-full border-none"
|
||||||
type="single"
|
type="single"
|
||||||
|
size="sm"
|
||||||
bind:value={$elevationFill}
|
bind:value={$elevationFill}
|
||||||
>
|
>
|
||||||
<ToggleGroup.Item
|
<ToggleGroup.Item value="slope" class="w-full flex flex-row justify-start">
|
||||||
class="p-0 pr-1.5 h-6 w-full gap-1.5 rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
|
||||||
value="slope"
|
|
||||||
>
|
|
||||||
<div class="w-6 flex justify-center items-center">
|
<div class="w-6 flex justify-center items-center">
|
||||||
{#if $elevationFill === 'slope'}
|
{#if $elevationFill === 'slope'}
|
||||||
<Circle class="size-1.5 fill-current text-current" />
|
<Circle class="size-1.5 fill-current text-current" />
|
||||||
@@ -104,9 +102,8 @@
|
|||||||
{i18n._('quantities.slope')}
|
{i18n._('quantities.slope')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
<ToggleGroup.Item
|
<ToggleGroup.Item
|
||||||
class="p-0 pr-1.5 h-6 w-full gap-1.5 rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
|
||||||
value="surface"
|
value="surface"
|
||||||
variant="outline"
|
class="w-full flex flex-row justify-start"
|
||||||
>
|
>
|
||||||
<div class="w-6 flex justify-center items-center">
|
<div class="w-6 flex justify-center items-center">
|
||||||
{#if $elevationFill === 'surface'}
|
{#if $elevationFill === 'surface'}
|
||||||
@@ -117,9 +114,8 @@
|
|||||||
{i18n._('quantities.surface')}
|
{i18n._('quantities.surface')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
<ToggleGroup.Item
|
<ToggleGroup.Item
|
||||||
class="p-0 pr-1.5 h-6 w-full gap-1.5 rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
|
||||||
value="highway"
|
value="highway"
|
||||||
variant="outline"
|
class="w-full flex flex-row justify-start"
|
||||||
>
|
>
|
||||||
<div class="w-6 flex justify-center items-center">
|
<div class="w-6 flex justify-center items-center">
|
||||||
{#if $elevationFill === 'highway'}
|
{#if $elevationFill === 'highway'}
|
||||||
@@ -132,14 +128,12 @@
|
|||||||
</ToggleGroup.Root>
|
</ToggleGroup.Root>
|
||||||
<Separator />
|
<Separator />
|
||||||
<ToggleGroup.Root
|
<ToggleGroup.Root
|
||||||
class="flex flex-col items-start gap-0 p-1"
|
class="flex flex-col gap-0"
|
||||||
type="multiple"
|
type="multiple"
|
||||||
|
size="sm"
|
||||||
bind:value={$additionalDatasets}
|
bind:value={$additionalDatasets}
|
||||||
>
|
>
|
||||||
<ToggleGroup.Item
|
<ToggleGroup.Item value="speed" class="w-full flex flex-row justify-start">
|
||||||
class="p-0 pr-1.5 h-6 w-full gap-1.5 rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
|
||||||
value="speed"
|
|
||||||
>
|
|
||||||
<div class="w-6 flex justify-center items-center">
|
<div class="w-6 flex justify-center items-center">
|
||||||
{#if $additionalDatasets.includes('speed')}
|
{#if $additionalDatasets.includes('speed')}
|
||||||
<Check size="14" />
|
<Check size="14" />
|
||||||
@@ -150,10 +144,7 @@
|
|||||||
? i18n._('quantities.speed')
|
? i18n._('quantities.speed')
|
||||||
: i18n._('quantities.pace')}
|
: i18n._('quantities.pace')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
<ToggleGroup.Item
|
<ToggleGroup.Item value="hr" class="w-full flex flex-row justify-start">
|
||||||
class="p-0 pr-1.5 h-6 w-full gap-1.5 rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
|
||||||
value="hr"
|
|
||||||
>
|
|
||||||
<div class="w-6 flex justify-center items-center">
|
<div class="w-6 flex justify-center items-center">
|
||||||
{#if $additionalDatasets.includes('hr')}
|
{#if $additionalDatasets.includes('hr')}
|
||||||
<Check size="14" />
|
<Check size="14" />
|
||||||
@@ -162,10 +153,7 @@
|
|||||||
<HeartPulse size="15" />
|
<HeartPulse size="15" />
|
||||||
{i18n._('quantities.heartrate')}
|
{i18n._('quantities.heartrate')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
<ToggleGroup.Item
|
<ToggleGroup.Item value="cad" class="w-full flex flex-row justify-start">
|
||||||
class="p-0 pr-1.5 h-6 w-full gap-1.5 rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
|
||||||
value="cad"
|
|
||||||
>
|
|
||||||
<div class="w-6 flex justify-center items-center">
|
<div class="w-6 flex justify-center items-center">
|
||||||
{#if $additionalDatasets.includes('cad')}
|
{#if $additionalDatasets.includes('cad')}
|
||||||
<Check size="14" />
|
<Check size="14" />
|
||||||
@@ -174,10 +162,7 @@
|
|||||||
<Orbit size="15" />
|
<Orbit size="15" />
|
||||||
{i18n._('quantities.cadence')}
|
{i18n._('quantities.cadence')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
<ToggleGroup.Item
|
<ToggleGroup.Item value="atemp" class="w-full flex flex-row justify-start">
|
||||||
class="p-0 pr-1.5 h-6 w-full gap-1.5 rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
|
||||||
value="atemp"
|
|
||||||
>
|
|
||||||
<div class="w-6 flex justify-center items-center">
|
<div class="w-6 flex justify-center items-center">
|
||||||
{#if $additionalDatasets.includes('atemp')}
|
{#if $additionalDatasets.includes('atemp')}
|
||||||
<Check size="14" />
|
<Check size="14" />
|
||||||
@@ -186,10 +171,7 @@
|
|||||||
<Thermometer size="15" />
|
<Thermometer size="15" />
|
||||||
{i18n._('quantities.temperature')}
|
{i18n._('quantities.temperature')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
<ToggleGroup.Item
|
<ToggleGroup.Item value="power" class="w-full flex flex-row justify-start">
|
||||||
class="p-0 pr-1.5 h-6 w-full gap-1.5 rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
|
||||||
value="power"
|
|
||||||
>
|
|
||||||
<div class="w-6 flex justify-center items-center">
|
<div class="w-6 flex justify-center items-center">
|
||||||
{#if $additionalDatasets.includes('power')}
|
{#if $additionalDatasets.includes('power')}
|
||||||
<Check size="14" />
|
<Check size="14" />
|
||||||
|
|||||||
@@ -45,26 +45,6 @@
|
|||||||
settings.initialize();
|
settings.initialize();
|
||||||
|
|
||||||
function applyOptions() {
|
function applyOptions() {
|
||||||
let downloads: Promise<GPXFile | null>[] = getFilesFromEmbeddingOptions(options).map(
|
|
||||||
(url) => {
|
|
||||||
return fetch(url)
|
|
||||||
.then((response) => response.blob())
|
|
||||||
.then((blob) => new File([blob], url.split('/').pop() ?? url))
|
|
||||||
.then(loadFile);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
Promise.all(downloads).then((answers) => {
|
|
||||||
const files = answers.filter((file) => file !== null) as GPXFile[];
|
|
||||||
let ids: string[] = [];
|
|
||||||
files.forEach((file, index) => {
|
|
||||||
let id = `gpx-${index}-embed`;
|
|
||||||
file._data.id = id;
|
|
||||||
ids.push(id);
|
|
||||||
});
|
|
||||||
fileStateCollection.setEmbeddedFiles(files);
|
|
||||||
$fileOrder = ids;
|
|
||||||
selection.selectAll();
|
|
||||||
});
|
|
||||||
if (allowedEmbeddingBasemaps.includes(options.basemap)) {
|
if (allowedEmbeddingBasemaps.includes(options.basemap)) {
|
||||||
$currentBasemap = options.basemap;
|
$currentBasemap = options.basemap;
|
||||||
}
|
}
|
||||||
@@ -90,6 +70,27 @@
|
|||||||
].filter((dataset) => dataset !== null)
|
].filter((dataset) => dataset !== null)
|
||||||
);
|
);
|
||||||
elevationFill.set(options.elevation.fill == 'none' ? undefined : options.elevation.fill);
|
elevationFill.set(options.elevation.fill == 'none' ? undefined : options.elevation.fill);
|
||||||
|
|
||||||
|
let downloads: Promise<GPXFile | null>[] = getFilesFromEmbeddingOptions(options).map(
|
||||||
|
(url) => {
|
||||||
|
return fetch(url)
|
||||||
|
.then((response) => response.blob())
|
||||||
|
.then((blob) => new File([blob], url.split('/').pop() ?? url))
|
||||||
|
.then(loadFile);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
Promise.all(downloads).then((answers) => {
|
||||||
|
const files = answers.filter((file) => file !== null) as GPXFile[];
|
||||||
|
let ids: string[] = [];
|
||||||
|
files.forEach((file, index) => {
|
||||||
|
let id = `gpx-${index}-embed`;
|
||||||
|
file._data.id = id;
|
||||||
|
ids.push(id);
|
||||||
|
});
|
||||||
|
fileStateCollection.setEmbeddedFiles(files);
|
||||||
|
$fileOrder = ids;
|
||||||
|
selection.selectAll();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
@@ -117,13 +118,12 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="{options.elevation.show ? '' : 'h-10'} flex flex-row gap-2 px-2 sm:px-4"
|
class="{options.elevation.show ? '' : 'h-10'} flex flex-row gap-2 p-2 sm:px-4"
|
||||||
style={options.elevation.show ? `height: ${options.elevation.height}px` : ''}
|
style={options.elevation.show ? `height: ${options.elevation.height}px` : ''}
|
||||||
>
|
>
|
||||||
<GPXStatistics
|
<GPXStatistics
|
||||||
{gpxStatistics}
|
{gpxStatistics}
|
||||||
{slicedGPXStatistics}
|
{slicedGPXStatistics}
|
||||||
panelSize={options.elevation.height}
|
|
||||||
orientation={options.elevation.show ? 'vertical' : 'horizontal'}
|
orientation={options.elevation.show ? 'vertical' : 'horizontal'}
|
||||||
/>
|
/>
|
||||||
{#if options.elevation.show}
|
{#if options.elevation.show}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export const defaultEmbeddingOptions = {
|
|||||||
key: '',
|
key: '',
|
||||||
files: [],
|
files: [],
|
||||||
ids: [],
|
ids: [],
|
||||||
basemap: 'maptilerTopo',
|
basemap: 'libertyTopo',
|
||||||
elevation: {
|
elevation: {
|
||||||
show: true,
|
show: true,
|
||||||
height: 170,
|
height: 170,
|
||||||
@@ -90,6 +90,9 @@ export function getCleanedEmbeddingOptions(
|
|||||||
delete cleanedOptions[key];
|
delete cleanedOptions[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cleanedOptions['key'] && cleanedOptions['key'] === PUBLIC_MAPTILER_KEY) {
|
||||||
|
delete cleanedOptions['key'];
|
||||||
|
}
|
||||||
return cleanedOptions;
|
return cleanedOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +126,7 @@ export function convertOldEmbeddingOptions(options: URLSearchParams): any {
|
|||||||
if (options.has('source')) {
|
if (options.has('source')) {
|
||||||
let basemap = options.get('source')!;
|
let basemap = options.get('source')!;
|
||||||
if (basemap === 'satellite') {
|
if (basemap === 'satellite') {
|
||||||
newOptions.basemap = 'maptilerSatellite';
|
newOptions.basemap = 'libertySatellite';
|
||||||
} else if (basemap === 'otm') {
|
} else if (basemap === 'otm') {
|
||||||
newOptions.basemap = 'openTopoMap';
|
newOptions.basemap = 'openTopoMap';
|
||||||
} else if (basemap === 'ohm') {
|
} else if (basemap === 'ohm') {
|
||||||
|
|||||||
@@ -100,7 +100,11 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full flex flex-row flex-wrap gap-2">
|
<div class="w-full flex flex-row flex-wrap gap-2">
|
||||||
<Button class="bg-support grow" href="https://ko-fi.com/gpxstudio" target="_blank">
|
<Button
|
||||||
|
class="bg-support grow"
|
||||||
|
href="https://opencollective.com/gpxstudio"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
{i18n._('menu.support_button')}
|
{i18n._('menu.support_button')}
|
||||||
<span>🙏</span>
|
<span>🙏</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -114,10 +114,10 @@
|
|||||||
<ContextMenu.Trigger class="grow truncate">
|
<ContextMenu.Trigger class="grow truncate">
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
class="relative w-full p-0 overflow-hidden focus-visible:ring-0 focus-visible:ring-offset-0 {orientation ===
|
class="relative w-full p-0 overflow-hidden border-none focus-visible:ring-0 focus-visible:ring-offset-0 flex flex-row {orientation ===
|
||||||
'vertical'
|
'vertical'
|
||||||
? 'h-fit'
|
? 'h-7'
|
||||||
: 'h-9 px-1.5 shadow-md'} pointer-events-auto"
|
: 'h-9 px-1.5'} pointer-events-auto"
|
||||||
>
|
>
|
||||||
{#if item instanceof ListFileItem || item instanceof ListTrackItem}
|
{#if item instanceof ListFileItem || item instanceof ListTrackItem}
|
||||||
<MetadataDialog bind:open={openEditMetadata} {node} {item} />
|
<MetadataDialog bind:open={openEditMetadata} {node} {item} />
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
{#if item.level === ListLevel.FILE || item.level === ListLevel.TRACK}
|
{#if item.level === ListLevel.FILE || item.level === ListLevel.TRACK}
|
||||||
<div
|
<div
|
||||||
class="absolute {orientation === 'vertical'
|
class="absolute {orientation === 'vertical'
|
||||||
? 'top-0 bottom-0 right-1 w-1'
|
? 'top-0 bottom-0 right-0 w-1'
|
||||||
: 'top-0 h-1 left-0 right-0'}"
|
: 'top-0 h-1 left-0 right-0'}"
|
||||||
style="background:linear-gradient(to {orientation === 'vertical'
|
style="background:linear-gradient(to {orientation === 'vertical'
|
||||||
? 'bottom'
|
? 'bottom'
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
></div>
|
></div>
|
||||||
{/if}
|
{/if}
|
||||||
<span
|
<span
|
||||||
class="w-full text-left truncate py-1 flex flex-row items-center {hidden
|
class="grow text-left truncate ml-1 flex flex-row items-center {hidden
|
||||||
? 'text-muted-foreground'
|
? 'text-muted-foreground'
|
||||||
: ''} {$cut && $copied?.some((i) => i.getFullId() === item.getFullId())
|
: ''} {$cut && $copied?.some((i) => i.getFullId() === item.getFullId())
|
||||||
? 'text-muted-foreground'
|
? 'text-muted-foreground'
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
|
||||||
class="justify-start {className}"
|
class="justify-start {className}"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
|
|||||||
@@ -39,7 +39,6 @@
|
|||||||
/>
|
/>
|
||||||
{#if trackpoint.fileId === undefined}
|
{#if trackpoint.fileId === undefined}
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="justify-start"
|
class="justify-start"
|
||||||
href={`https://www.openstreetmap.org/edit?#map=${(($map?.getZoom() ?? 17) + 1).toFixed(0)}/${trackpoint.item.getLatitude().toFixed(5)}/${trackpoint.item.getLongitude().toFixed(5)}`}
|
href={`https://www.openstreetmap.org/edit?#map=${(($map?.getZoom() ?? 17) + 1).toFixed(0)}/${trackpoint.item.getLatitude().toFixed(5)}/${trackpoint.item.getLongitude().toFixed(5)}`}
|
||||||
|
|||||||
@@ -88,7 +88,6 @@
|
|||||||
<CopyCoordinates coordinates={waypoint.item.attributes} />
|
<CopyCoordinates coordinates={waypoint.item.attributes} />
|
||||||
{#if $currentTool === Tool.WAYPOINT && selected}
|
{#if $currentTool === Tool.WAYPOINT && selected}
|
||||||
<Button
|
<Button
|
||||||
class="p-1 has-[>svg]:px-2 h-8"
|
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
if (waypoint.fileId) {
|
if (waypoint.fileId) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { get } from 'svelte/store';
|
|||||||
import { map } from '$lib/components/map/map';
|
import { map } from '$lib/components/map/map';
|
||||||
import { allHidden } from '$lib/logic/hidden';
|
import { allHidden } from '$lib/logic/hidden';
|
||||||
import type { GeoJSONSource } from 'maplibre-gl';
|
import type { GeoJSONSource } from 'maplibre-gl';
|
||||||
import { ANCHOR_LAYER_KEY } from '../style';
|
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
|
||||||
|
|
||||||
const { distanceMarkers, distanceUnits } = settings;
|
const { distanceMarkers, distanceUnits } = settings;
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ export class DistanceMarkers {
|
|||||||
layout: {
|
layout: {
|
||||||
'text-field': ['get', 'distance'],
|
'text-field': ['get', 'distance'],
|
||||||
'text-size': 14,
|
'text-size': 14,
|
||||||
'text-font': ['Open Sans Bold'],
|
'text-font': ['Noto Sans Bold'],
|
||||||
},
|
},
|
||||||
paint: {
|
paint: {
|
||||||
'text-color': 'black',
|
'text-color': 'black',
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import { fileActions } from '$lib/logic/file-actions';
|
|||||||
import { splitAs } from '$lib/components/toolbar/tools/scissors/scissors';
|
import { splitAs } from '$lib/components/toolbar/tools/scissors/scissors';
|
||||||
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
|
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
|
||||||
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
|
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
|
||||||
import { gpxColors } from './gpx-layers';
|
import { gpxColors } from '$lib/components/map/gpx-layer/gpx-layers';
|
||||||
|
|
||||||
const colors = [
|
const colors = [
|
||||||
'#ff0000',
|
'#ff0000',
|
||||||
@@ -255,13 +255,12 @@ export class GPXLayer {
|
|||||||
'text-keep-upright': false,
|
'text-keep-upright': false,
|
||||||
'text-max-angle': 361,
|
'text-max-angle': 361,
|
||||||
'text-allow-overlap': true,
|
'text-allow-overlap': true,
|
||||||
'text-font': ['Open Sans Bold'],
|
'text-font': ['Noto Sans Bold'],
|
||||||
'symbol-placement': 'line',
|
'symbol-placement': 'line',
|
||||||
'symbol-spacing': 20,
|
'symbol-spacing': 20,
|
||||||
},
|
},
|
||||||
paint: {
|
paint: {
|
||||||
'text-color': 'white',
|
'text-color': 'white',
|
||||||
'text-opacity': 0.7,
|
|
||||||
'text-halo-width': 0.2,
|
'text-halo-width': 0.2,
|
||||||
'text-halo-color': 'white',
|
'text-halo-color': 'white',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export class StartEndMarkers {
|
|||||||
unsubscribes: (() => void)[] = [];
|
unsubscribes: (() => void)[] = [];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
map.onLoad(() => this.update());
|
map.onLoad((map_) => map_.on('style.load', this.updateBinded));
|
||||||
this.unsubscribes.push(gpxStatistics.subscribe(this.updateBinded));
|
this.unsubscribes.push(gpxStatistics.subscribe(this.updateBinded));
|
||||||
this.unsubscribes.push(slicedGPXStatistics.subscribe(this.updateBinded));
|
this.unsubscribes.push(slicedGPXStatistics.subscribe(this.updateBinded));
|
||||||
this.unsubscribes.push(hoveredPoint.subscribe(this.updateBinded));
|
this.unsubscribes.push(hoveredPoint.subscribe(this.updateBinded));
|
||||||
|
|||||||
@@ -232,120 +232,127 @@
|
|||||||
|
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
{#if $customBasemapOrder.length > 0}
|
{#if $customBasemapOrder.length > 0}
|
||||||
<div class="flex flex-row items-center gap-1 font-semibold mb-2">
|
<div class="px-3 py-2">
|
||||||
<Map size="16" />
|
<div class="flex flex-row items-center gap-1 font-semibold mb-2">
|
||||||
{i18n._('layers.label.basemaps')}
|
<Map size="16" />
|
||||||
<div class="grow">
|
{i18n._('layers.label.basemaps')}
|
||||||
<Separator />
|
</div>
|
||||||
|
<div
|
||||||
|
class="ml-1.5 flex flex-col gap-1"
|
||||||
|
use:dndzone={{
|
||||||
|
items: customBasemapItems,
|
||||||
|
type: 'basemap',
|
||||||
|
dropTargetStyle: {},
|
||||||
|
transformDraggedElement: (element) => {
|
||||||
|
if (element) {
|
||||||
|
element.style.opacity = '0.5';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onconsider={(e) => {
|
||||||
|
customBasemapItems = e.detail.items;
|
||||||
|
}}
|
||||||
|
onfinalize={(e) => {
|
||||||
|
customBasemapItems = e.detail.items;
|
||||||
|
$customBasemapOrder = customBasemapItems.map((item) => item.id);
|
||||||
|
$selectedBasemapTree.basemaps['custom'] = customBasemapItems.reduce(
|
||||||
|
(acc, item) => {
|
||||||
|
acc[item.id] = true;
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{#each customBasemapItems as item (item.id)}
|
||||||
|
<div class="flex flex-row items-center gap-1">
|
||||||
|
<Move size="12" />
|
||||||
|
<span class="grow">{item.name}</span>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon-sm"
|
||||||
|
onclick={() => (selectedLayerId = item.id)}
|
||||||
|
class="p-1 h-7"
|
||||||
|
>
|
||||||
|
<Pencil size="16" />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon-sm"
|
||||||
|
onclick={() => deleteLayer(item.id)}
|
||||||
|
class="p-1 h-7"
|
||||||
|
>
|
||||||
|
<Trash2 size="16" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Separator />
|
||||||
{/if}
|
{/if}
|
||||||
<div
|
|
||||||
class="ml-1.5 flex flex-col gap-1 {$customBasemapOrder.length > 0 ? 'mb-2' : ''}"
|
|
||||||
use:dndzone={{
|
|
||||||
items: customBasemapItems,
|
|
||||||
type: 'basemap',
|
|
||||||
dropTargetStyle: {},
|
|
||||||
transformDraggedElement: (element) => {
|
|
||||||
if (element) {
|
|
||||||
element.style.opacity = '0.5';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
onconsider={(e) => {
|
|
||||||
customBasemapItems = e.detail.items;
|
|
||||||
}}
|
|
||||||
onfinalize={(e) => {
|
|
||||||
customBasemapItems = e.detail.items;
|
|
||||||
$customBasemapOrder = customBasemapItems.map((item) => item.id);
|
|
||||||
$selectedBasemapTree.basemaps['custom'] = customBasemapItems.reduce((acc, item) => {
|
|
||||||
acc[item.id] = true;
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{#each customBasemapItems as item (item.id)}
|
|
||||||
<div class="flex flex-row items-center gap-2">
|
|
||||||
<Move size="12" />
|
|
||||||
<span class="grow">{item.name}</span>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="icon-sm"
|
|
||||||
onclick={() => (selectedLayerId = item.id)}
|
|
||||||
class="p-1 h-7"
|
|
||||||
>
|
|
||||||
<Pencil size="16" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="icon-sm"
|
|
||||||
onclick={() => deleteLayer(item.id)}
|
|
||||||
class="p-1 h-7"
|
|
||||||
>
|
|
||||||
<Trash2 size="16" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{#if $customOverlayOrder.length > 0}
|
{#if $customOverlayOrder.length > 0}
|
||||||
<div class="flex flex-row items-center gap-1 font-semibold mb-2">
|
<div class="px-3 py-2">
|
||||||
<Layers2 size="16" />
|
<div class="flex flex-row items-center gap-1 font-semibold mb-2">
|
||||||
{i18n._('layers.label.overlays')}
|
<Layers2 size="16" />
|
||||||
<div class="grow">
|
{i18n._('layers.label.overlays')}
|
||||||
<Separator />
|
<div class="grow"></div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ml-1.5 flex flex-col gap-1"
|
||||||
|
use:dndzone={{
|
||||||
|
items: customOverlayItems,
|
||||||
|
type: 'overlay',
|
||||||
|
dropTargetStyle: {},
|
||||||
|
transformDraggedElement: (element) => {
|
||||||
|
if (element) {
|
||||||
|
element.style.opacity = '0.5';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onconsider={(e) => {
|
||||||
|
customOverlayItems = e.detail.items;
|
||||||
|
}}
|
||||||
|
onfinalize={(e) => {
|
||||||
|
customOverlayItems = e.detail.items;
|
||||||
|
$customOverlayOrder = customOverlayItems.map((item) => item.id);
|
||||||
|
$selectedOverlayTree.overlays['custom'] = customOverlayItems.reduce(
|
||||||
|
(acc, item) => {
|
||||||
|
acc[item.id] = true;
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{#each customOverlayItems as item (item.id)}
|
||||||
|
<div class="flex flex-row items-center gap-1">
|
||||||
|
<Move size="12" />
|
||||||
|
<span class="grow">{item.name}</span>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon-sm"
|
||||||
|
onclick={() => (selectedLayerId = item.id)}
|
||||||
|
class="p-1 h-7"
|
||||||
|
>
|
||||||
|
<Pencil size="16" />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon-sm"
|
||||||
|
onclick={() => deleteLayer(item.id)}
|
||||||
|
class="p-1 h-7"
|
||||||
|
>
|
||||||
|
<Trash2 size="16" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Separator />
|
||||||
{/if}
|
{/if}
|
||||||
<div
|
<Card.Root class="py-0 gap-0 shadow-none ring-0">
|
||||||
class="ml-1.5 flex flex-col gap-1 {$customOverlayOrder.length > 0 ? 'mb-2' : ''}"
|
|
||||||
use:dndzone={{
|
|
||||||
items: customOverlayItems,
|
|
||||||
type: 'overlay',
|
|
||||||
dropTargetStyle: {},
|
|
||||||
transformDraggedElement: (element) => {
|
|
||||||
if (element) {
|
|
||||||
element.style.opacity = '0.5';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
onconsider={(e) => {
|
|
||||||
customOverlayItems = e.detail.items;
|
|
||||||
}}
|
|
||||||
onfinalize={(e) => {
|
|
||||||
customOverlayItems = e.detail.items;
|
|
||||||
$customOverlayOrder = customOverlayItems.map((item) => item.id);
|
|
||||||
$selectedOverlayTree.overlays['custom'] = customOverlayItems.reduce((acc, item) => {
|
|
||||||
acc[item.id] = true;
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{#each customOverlayItems as item (item.id)}
|
|
||||||
<div class="flex flex-row items-center gap-2">
|
|
||||||
<Move size="12" />
|
|
||||||
<span class="grow">{item.name}</span>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="icon-sm"
|
|
||||||
onclick={() => (selectedLayerId = item.id)}
|
|
||||||
class="p-1 h-7"
|
|
||||||
>
|
|
||||||
<Pencil size="16" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="icon-sm"
|
|
||||||
onclick={() => deleteLayer(item.id)}
|
|
||||||
class="p-1 h-7"
|
|
||||||
>
|
|
||||||
<Trash2 size="16" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
<Card.Root class="py-0 gap-0 shadow-none">
|
|
||||||
<Card.Header class="p-3">
|
<Card.Header class="p-3">
|
||||||
<Card.Title class="text-base">
|
<Card.Title class="text-sm font-semibold">
|
||||||
{#if selectedLayerId}
|
{#if selectedLayerId}
|
||||||
{i18n._('layers.custom_layers.edit')}
|
{i18n._('layers.custom_layers.edit')}
|
||||||
{:else}
|
{:else}
|
||||||
@@ -353,7 +360,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</Card.Title>
|
</Card.Title>
|
||||||
</Card.Header>
|
</Card.Header>
|
||||||
<Card.Content class="p-3 pt-0">
|
<Card.Content class="px-3 py-2">
|
||||||
<fieldset class="flex flex-col gap-2">
|
<fieldset class="flex flex-col gap-2">
|
||||||
<Label for="name">{i18n._('menu.metadata.name')}</Label>
|
<Label for="name">{i18n._('menu.metadata.name')}</Label>
|
||||||
<Input bind:value={name} id="name" class="h-8" />
|
<Input bind:value={name} id="name" class="h-8" />
|
||||||
@@ -410,7 +417,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</RadioGroup.Root>
|
</RadioGroup.Root>
|
||||||
{#if selectedLayerId}
|
{#if selectedLayerId}
|
||||||
<div class="mt-2 flex flex-row gap-2">
|
<div class="mt-2 flex flex-row gap-1">
|
||||||
<Button variant="outline" onclick={createLayer} class="grow">
|
<Button variant="outline" onclick={createLayer} class="grow">
|
||||||
<Save size="16" />
|
<Save size="16" />
|
||||||
{i18n._('layers.custom_layers.update')}
|
{i18n._('layers.custom_layers.update')}
|
||||||
|
|||||||
@@ -121,7 +121,7 @@
|
|||||||
<Accordion.Root class="flex flex-col" bind:value={accordionValue} type="single">
|
<Accordion.Root class="flex flex-col" bind:value={accordionValue} type="single">
|
||||||
<Accordion.Item value="layer-selection" class="flex flex-col">
|
<Accordion.Item value="layer-selection" class="flex flex-col">
|
||||||
<Accordion.Trigger>{i18n._('layers.selection')}</Accordion.Trigger>
|
<Accordion.Trigger>{i18n._('layers.selection')}</Accordion.Trigger>
|
||||||
<Accordion.Content class="grow flex flex-col border rounded">
|
<Accordion.Content class="grow flex flex-col border rounded-md mb-1.5">
|
||||||
<div class="py-2 pl-3 pr-2">
|
<div class="py-2 pl-3 pr-2">
|
||||||
<LayerTree
|
<LayerTree
|
||||||
layerTree={basemapTree}
|
layerTree={basemapTree}
|
||||||
@@ -152,7 +152,9 @@
|
|||||||
</Accordion.Item>
|
</Accordion.Item>
|
||||||
<Accordion.Item value="overlay-opacity">
|
<Accordion.Item value="overlay-opacity">
|
||||||
<Accordion.Trigger>{i18n._('layers.opacity')}</Accordion.Trigger>
|
<Accordion.Trigger>{i18n._('layers.opacity')}</Accordion.Trigger>
|
||||||
<Accordion.Content class="flex flex-col gap-3 overflow-visible">
|
<Accordion.Content
|
||||||
|
class="flex flex-col gap-3 overflow-visible border rounded-md px-3 py-2 mb-1.5"
|
||||||
|
>
|
||||||
<div class="flex flex-row gap-6 items-center">
|
<div class="flex flex-row gap-6 items-center">
|
||||||
<Label>
|
<Label>
|
||||||
{i18n._('layers.custom_layers.overlay')}
|
{i18n._('layers.custom_layers.overlay')}
|
||||||
@@ -231,10 +233,10 @@
|
|||||||
<Accordion.Item value="custom-layers">
|
<Accordion.Item value="custom-layers">
|
||||||
<Accordion.Trigger>{i18n._('layers.custom_layers.title')}</Accordion.Trigger
|
<Accordion.Trigger>{i18n._('layers.custom_layers.title')}</Accordion.Trigger
|
||||||
>
|
>
|
||||||
<Accordion.Content>
|
<Accordion.Content
|
||||||
<ScrollArea>
|
class="flex flex-col overflow-visible border rounded-md p-0 mb-1.5"
|
||||||
<CustomLayers />
|
>
|
||||||
</ScrollArea>
|
<CustomLayers />
|
||||||
</Accordion.Content>
|
</Accordion.Content>
|
||||||
</Accordion.Item>
|
</Accordion.Item>
|
||||||
<Accordion.Item value="terrain-source">
|
<Accordion.Item value="terrain-source">
|
||||||
|
|||||||
@@ -88,6 +88,14 @@
|
|||||||
<span class="font-mono">{key}</span>
|
<span class="font-mono">{key}</span>
|
||||||
{#if key === 'website' || key.startsWith('website:') || key.endsWith(':website') || key === 'contact:facebook' || key === 'contact:instagram' || key === 'contact:twitter'}
|
{#if key === 'website' || key.startsWith('website:') || key.endsWith(':website') || key === 'contact:facebook' || key === 'contact:instagram' || key === 'contact:twitter'}
|
||||||
<a href={value} target="_blank" class="text-link underline">{value}</a>
|
<a href={value} target="_blank" class="text-link underline">{value}</a>
|
||||||
|
{:else if key === 'wikipedia' || key.startsWith('wikipedia:') || key.endsWith(':wikipedia')}
|
||||||
|
<a
|
||||||
|
href="https://wikipedia.org/wiki/{value}"
|
||||||
|
target="_blank"
|
||||||
|
class="text-link underline"
|
||||||
|
>
|
||||||
|
{value}
|
||||||
|
</a>
|
||||||
{:else if key === 'phone' || key === 'contact:phone'}
|
{:else if key === 'phone' || key === 'contact:phone'}
|
||||||
<a href={'tel:' + value} class="text-link underline">{value}</a>
|
<a href={'tel:' + value} class="text-link underline">{value}</a>
|
||||||
{:else if key === 'email' || key === 'contact:email'}
|
{:else if key === 'email' || key === 'contact:email'}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { MapPopup } from '$lib/components/map/map-popup';
|
|||||||
import { settings } from '$lib/logic/settings';
|
import { settings } from '$lib/logic/settings';
|
||||||
import { db } from '$lib/db';
|
import { db } from '$lib/db';
|
||||||
import type { GeoJSONSource } from 'maplibre-gl';
|
import type { GeoJSONSource } from 'maplibre-gl';
|
||||||
import { ANCHOR_LAYER_KEY } from '../style';
|
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
|
||||||
import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager';
|
import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager';
|
||||||
import { loadSVGIcon } from '$lib/utils';
|
import { loadSVGIcon } from '$lib/utils';
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ liveQuery(() => db.overpassdata.toArray()).subscribe((pois) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export class OverpassLayer {
|
export class OverpassLayer {
|
||||||
overpassUrl = 'https://maps.mail.ru/osm/tools/overpass/api/interpreter';
|
overpassUrl = 'https://overpass.gpx.studio/api/interpreter';
|
||||||
minZoom = 12;
|
minZoom = 12;
|
||||||
queryZoom = 12;
|
queryZoom = 12;
|
||||||
expirationTime = 7 * 24 * 3600 * 1000;
|
expirationTime = 7 * 24 * 3600 * 1000;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import type { LayerTreeType } from '$lib/assets/layers';
|
import type { LayerTreeType } from '$lib/assets/layers';
|
||||||
import { writable } from 'svelte/store';
|
|
||||||
|
|
||||||
export function anySelectedLayer(node: LayerTreeType) {
|
export function anySelectedLayer(node: LayerTreeType) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ export class MapLayerEventManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _handleMouseMove(e: maplibregl.MapMouseEvent) {
|
private _handleMouseMove(e: maplibregl.MapMouseEvent) {
|
||||||
|
if (e.originalEvent.buttons > 0) return;
|
||||||
const featuresByLayer = this._getRenderedFeaturesByLayer(e);
|
const featuresByLayer = this._getRenderedFeaturesByLayer(e);
|
||||||
Object.keys(this._listeners).forEach((layerId) => {
|
Object.keys(this._listeners).forEach((layerId) => {
|
||||||
const features = featuresByLayer[layerId] || [];
|
const features = featuresByLayer[layerId] || [];
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export class MapLibreGLMap {
|
|||||||
zoom: 0,
|
zoom: 0,
|
||||||
hash: hash,
|
hash: hash,
|
||||||
boxZoom: false,
|
boxZoom: false,
|
||||||
maxPitch: 85,
|
maxPitch: 90,
|
||||||
});
|
});
|
||||||
this.layerEventManager = new MapLayerEventManager(map);
|
this.layerEventManager = new MapLayerEventManager(map);
|
||||||
map.addControl(
|
map.addControl(
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
<CustomControl class="w-[29px] h-[29px] shrink-0">
|
<CustomControl class="w-[29px] h-[29px] shrink-0">
|
||||||
<ButtonWithTooltip
|
<ButtonWithTooltip
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
class="w-full h-full"
|
class="w-full h-full border-none rounded-sm"
|
||||||
side="left"
|
side="left"
|
||||||
label={i18n._('menu.toggle_street_view')}
|
label={i18n._('menu.toggle_street_view')}
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import maplibregl, { type LayerSpecification, type VectorSourceSpecification } f
|
|||||||
import { Viewer, type ViewerBearingEvent } from 'mapillary-js/dist/mapillary.module';
|
import { Viewer, type ViewerBearingEvent } from 'mapillary-js/dist/mapillary.module';
|
||||||
import 'mapillary-js/dist/mapillary.css';
|
import 'mapillary-js/dist/mapillary.css';
|
||||||
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
|
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
|
||||||
import { ANCHOR_LAYER_KEY } from '../style';
|
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
|
||||||
import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager';
|
import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager';
|
||||||
|
|
||||||
const mapillarySource: VectorSourceSpecification = {
|
const mapillarySource: VectorSourceSpecification = {
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import {
|
|||||||
import { getLayers } from '$lib/components/map/layer-control/utils';
|
import { getLayers } from '$lib/components/map/layer-control/utils';
|
||||||
import { i18n } from '$lib/i18n.svelte';
|
import { i18n } from '$lib/i18n.svelte';
|
||||||
|
|
||||||
const { currentBasemap, currentOverlays, customLayers, opacities, terrainSource } = settings;
|
const { currentBasemap, currentOverlays, customLayers, opacities, terrainSource, distanceUnits } =
|
||||||
|
settings;
|
||||||
|
|
||||||
const emptySource: maplibregl.GeoJSONSourceSpecification = {
|
const emptySource: maplibregl.GeoJSONSourceSpecification = {
|
||||||
type: 'geojson',
|
type: 'geojson',
|
||||||
@@ -57,15 +58,24 @@ export class StyleManager {
|
|||||||
opacities.subscribe(() => this.updateOverlays());
|
opacities.subscribe(() => this.updateOverlays());
|
||||||
terrainSource.subscribe(() => this.updateTerrain());
|
terrainSource.subscribe(() => this.updateTerrain());
|
||||||
customLayers.subscribe(() => this.updateBasemap());
|
customLayers.subscribe(() => this.updateBasemap());
|
||||||
|
distanceUnits.subscribe(() => {
|
||||||
|
const map = get(this._map);
|
||||||
|
if (map && (map.getLayer('contours_m') || map.getLayer('contours_ft'))) {
|
||||||
|
this.updateBasemap();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBasemap() {
|
updateBasemap() {
|
||||||
const map_ = get(this._map);
|
const map_ = get(this._map);
|
||||||
if (!map_) return;
|
if (!map_) return;
|
||||||
this.buildStyle().then((style) => map_.setStyle(style));
|
let basemap = get(currentBasemap);
|
||||||
|
this.buildStyle(basemap).then((style) => {
|
||||||
|
if (get(currentBasemap) === basemap) map_.setStyle(style);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async buildStyle(): Promise<maplibregl.StyleSpecification> {
|
async buildStyle(basemap: string): Promise<maplibregl.StyleSpecification> {
|
||||||
const custom = get(customLayers);
|
const custom = get(customLayers);
|
||||||
|
|
||||||
const style: maplibregl.StyleSpecification = {
|
const style: maplibregl.StyleSpecification = {
|
||||||
@@ -79,10 +89,26 @@ export class StyleManager {
|
|||||||
layers: [],
|
layers: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
let basemap = get(currentBasemap);
|
|
||||||
const basemapInfo = basemaps[basemap] ?? custom[basemap]?.value ?? basemaps[defaultBasemap];
|
const basemapInfo = basemaps[basemap] ?? custom[basemap]?.value ?? basemaps[defaultBasemap];
|
||||||
const basemapStyle = await this.get(basemapInfo);
|
|
||||||
|
|
||||||
|
let basemapStyle = basemaps.openStreetMap as maplibregl.StyleSpecification;
|
||||||
|
try {
|
||||||
|
basemapStyle = await this.get(basemapInfo);
|
||||||
|
for (const source in basemapStyle.sources) {
|
||||||
|
const src = basemapStyle.sources[source];
|
||||||
|
if (
|
||||||
|
src &&
|
||||||
|
typeof src === 'object' &&
|
||||||
|
'url' in src &&
|
||||||
|
typeof src.url === 'string' &&
|
||||||
|
src.url.includes(maptilerKeyPlaceHolder)
|
||||||
|
) {
|
||||||
|
src.url = src.url.replace(maptilerKeyPlaceHolder, this._maptilerKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e.message);
|
||||||
|
}
|
||||||
this.merge(style, basemapStyle);
|
this.merge(style, basemapStyle);
|
||||||
|
|
||||||
const terrain = this.getCurrentTerrain();
|
const terrain = this.getCurrentTerrain();
|
||||||
@@ -107,45 +133,52 @@ export class StyleManager {
|
|||||||
if (!layers[overlay]) {
|
if (!layers[overlay]) {
|
||||||
if (this._pastOverlays.has(overlay)) {
|
if (this._pastOverlays.has(overlay)) {
|
||||||
const overlayInfo = custom[overlay]?.value ?? overlays[overlay];
|
const overlayInfo = custom[overlay]?.value ?? overlays[overlay];
|
||||||
const overlayStyle = await this.get(overlayInfo);
|
try {
|
||||||
for (let layer of overlayStyle.layers ?? []) {
|
const overlayStyle = await this.get(overlayInfo);
|
||||||
if (map_.getLayer(layer.id)) {
|
for (let layer of overlayStyle.layers ?? []) {
|
||||||
map_.removeLayer(layer.id);
|
if (map_.getLayer(layer.id)) {
|
||||||
|
map_.removeLayer(layer.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Should not happen
|
||||||
}
|
}
|
||||||
this._pastOverlays.delete(overlay);
|
this._pastOverlays.delete(overlay);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const overlayInfo = custom[overlay]?.value ?? overlays[overlay];
|
const overlayInfo = custom[overlay]?.value ?? overlays[overlay];
|
||||||
const overlayStyle = await this.get(overlayInfo);
|
try {
|
||||||
const opacity = overlayOpacities[overlay];
|
const overlayStyle = await this.get(overlayInfo);
|
||||||
|
const opacity = overlayOpacities[overlay];
|
||||||
|
|
||||||
for (let sourceId in overlayStyle.sources) {
|
for (let sourceId in overlayStyle.sources) {
|
||||||
if (!map_.getSource(sourceId)) {
|
if (!map_.getSource(sourceId)) {
|
||||||
map_.addSource(sourceId, overlayStyle.sources[sourceId]);
|
map_.addSource(sourceId, overlayStyle.sources[sourceId]);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let layer of overlayStyle.layers ?? []) {
|
|
||||||
if (!map_.getLayer(layer.id)) {
|
|
||||||
if (opacity !== undefined) {
|
|
||||||
if (layer.type === 'raster') {
|
|
||||||
if (!layer.paint) {
|
|
||||||
layer.paint = {};
|
|
||||||
}
|
|
||||||
layer.paint['raster-opacity'] = opacity;
|
|
||||||
} else if (layer.type === 'hillshade') {
|
|
||||||
if (!layer.paint) {
|
|
||||||
layer.paint = {};
|
|
||||||
}
|
|
||||||
layer.paint['hillshade-exaggeration'] = opacity / 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
map_.addLayer(layer, ANCHOR_LAYER_KEY.overlays);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this._pastOverlays.add(overlay);
|
for (let layer of overlayStyle.layers ?? []) {
|
||||||
|
if (!map_.getLayer(layer.id)) {
|
||||||
|
if (opacity !== undefined) {
|
||||||
|
if (layer.type === 'raster') {
|
||||||
|
if (!layer.paint) {
|
||||||
|
layer.paint = {};
|
||||||
|
}
|
||||||
|
layer.paint['raster-opacity'] = opacity;
|
||||||
|
} else if (layer.type === 'hillshade') {
|
||||||
|
if (!layer.paint) {
|
||||||
|
layer.paint = {};
|
||||||
|
}
|
||||||
|
layer.paint['hillshade-exaggeration'] = opacity / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map_.addLayer(layer, ANCHOR_LAYER_KEY.overlays);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._pastOverlays.add(overlay);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
@@ -174,10 +207,10 @@ export class StyleManager {
|
|||||||
): Promise<maplibregl.StyleSpecification> {
|
): Promise<maplibregl.StyleSpecification> {
|
||||||
if (typeof styleInfo === 'string') {
|
if (typeof styleInfo === 'string') {
|
||||||
let styleUrl = styleInfo as string;
|
let styleUrl = styleInfo as string;
|
||||||
if (styleUrl.includes(maptilerKeyPlaceHolder)) {
|
|
||||||
styleUrl = styleUrl.replace(maptilerKeyPlaceHolder, this._maptilerKey);
|
|
||||||
}
|
|
||||||
const response = await fetch(styleUrl, { cache: 'force-cache' });
|
const response = await fetch(styleUrl, { cache: 'force-cache' });
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error fetching style "${styleInfo}": ${response.status}`);
|
||||||
|
}
|
||||||
const style = await response.json();
|
const style = await response.json();
|
||||||
return style;
|
return style;
|
||||||
} else {
|
} else {
|
||||||
@@ -187,23 +220,46 @@ export class StyleManager {
|
|||||||
|
|
||||||
merge(style: maplibregl.StyleSpecification, other: maplibregl.StyleSpecification) {
|
merge(style: maplibregl.StyleSpecification, other: maplibregl.StyleSpecification) {
|
||||||
style.sources = { ...style.sources, ...other.sources };
|
style.sources = { ...style.sources, ...other.sources };
|
||||||
|
const units = get(distanceUnits);
|
||||||
for (let layer of other.layers ?? []) {
|
for (let layer of other.layers ?? []) {
|
||||||
|
if ('source' in layer) {
|
||||||
|
if (layer.source == 'contours_m' && units === 'imperial') continue;
|
||||||
|
if (layer.source == 'contours_ft' && units !== 'imperial') continue;
|
||||||
|
}
|
||||||
if (layer.type === 'symbol' && layer.layout && layer.layout['text-field']) {
|
if (layer.type === 'symbol' && layer.layout && layer.layout['text-field']) {
|
||||||
const textField = layer.layout['text-field'];
|
const textField = layer.layout['text-field'];
|
||||||
if (
|
if (Array.isArray(textField)) {
|
||||||
Array.isArray(textField) &&
|
if (
|
||||||
textField.length >= 2 &&
|
textField.length == 4 &&
|
||||||
textField[0] === 'coalesce' &&
|
Array.isArray(textField[3]) &&
|
||||||
Array.isArray(textField[1]) &&
|
textField[3][0] === 'coalesce' &&
|
||||||
textField[1][0] === 'get' &&
|
Array.isArray(textField[3][1]) &&
|
||||||
typeof textField[1][1] === 'string' &&
|
textField[3][1][0] === 'get' &&
|
||||||
textField[1][1].startsWith('name')
|
typeof textField[3][1][1] === 'string' &&
|
||||||
) {
|
textField[3][1][1].startsWith('name')
|
||||||
layer.layout['text-field'] = [
|
) {
|
||||||
'coalesce',
|
// OpenFreeMap styles
|
||||||
['get', `name:${i18n.lang}`],
|
layer.layout['text-field'] = [
|
||||||
['get', 'name'],
|
'coalesce',
|
||||||
];
|
['get', `name:${i18n.lang}`],
|
||||||
|
['get', 'name'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
textField.length == 3 &&
|
||||||
|
textField[0] === 'coalesce' &&
|
||||||
|
Array.isArray(textField[1]) &&
|
||||||
|
textField[1][0] === 'get' &&
|
||||||
|
typeof textField[1][1] === 'string' &&
|
||||||
|
textField[1][1].startsWith('name')
|
||||||
|
) {
|
||||||
|
// OpenMapTiles styles
|
||||||
|
layer.layout['text-field'] = [
|
||||||
|
'coalesce',
|
||||||
|
['get', `name:${i18n.lang}`],
|
||||||
|
['get', 'name'],
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
style.layers.push(layer);
|
style.layers.push(layer);
|
||||||
@@ -218,10 +274,6 @@ export class StyleManager {
|
|||||||
|
|
||||||
getCurrentTerrain() {
|
getCurrentTerrain() {
|
||||||
const terrain = get(terrainSource);
|
const terrain = get(terrainSource);
|
||||||
const source = terrainSources[terrain];
|
|
||||||
if (source.url && source.url.includes(maptilerKeyPlaceHolder)) {
|
|
||||||
source.url = source.url.replace(maptilerKeyPlaceHolder, this._maptilerKey);
|
|
||||||
}
|
|
||||||
const map_ = get(this._map);
|
const map_ = get(this._map);
|
||||||
return {
|
return {
|
||||||
source: terrain,
|
source: terrain,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<div class="flex flex-col gap-3 w-full max-w-80 {props.class ?? ''}">
|
<div class="flex flex-col gap-3 w-full max-w-80 {props.class ?? ''}">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="whitespace-normal h-fit"
|
class="whitespace-normal h-fit min-h-8 py-1"
|
||||||
disabled={!validSelection}
|
disabled={!validSelection}
|
||||||
onclick={() => fileActions.addElevationToSelection()}
|
onclick={() => fileActions.addElevationToSelection()}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="whitespace-normal h-fit"
|
class="whitespace-normal h-fit min-h-8 py-1"
|
||||||
disabled={(mergeType === MergeType.TRACES && !canMergeTraces) ||
|
disabled={(mergeType === MergeType.TRACES && !canMergeTraces) ||
|
||||||
(mergeType === MergeType.CONTENTS && !canMergeContents)}
|
(mergeType === MergeType.CONTENTS && !canMergeContents)}
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
|
|||||||
@@ -185,8 +185,8 @@
|
|||||||
|
|
||||||
<div class="flex flex-col gap-3 w-full max-w-80 {props.class ?? ''}">
|
<div class="flex flex-col gap-3 w-full max-w-80 {props.class ?? ''}">
|
||||||
<fieldset class="flex flex-col gap-2">
|
<fieldset class="flex flex-col gap-2">
|
||||||
<div class="flex flex-row gap-2 justify-center">
|
<div class="flex flex-row gap-1.5 justify-center">
|
||||||
<div class="flex flex-col gap-2 grow">
|
<div class="flex flex-col gap-1 grow">
|
||||||
<Label for="speed" class="flex flex-row">
|
<Label for="speed" class="flex flex-row">
|
||||||
<Zap size="16" />
|
<Zap size="16" />
|
||||||
{#if $velocityUnits === 'speed'}
|
{#if $velocityUnits === 'speed'}
|
||||||
@@ -239,7 +239,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-2 grow">
|
<div class="flex flex-col gap-1 grow">
|
||||||
<Label for="duration" class="flex flex-row">
|
<Label for="duration" class="flex flex-row">
|
||||||
<Timer size="16" />
|
<Timer size="16" />
|
||||||
{i18n._('toolbar.time.total_time')}
|
{i18n._('toolbar.time.total_time')}
|
||||||
@@ -253,57 +253,61 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Label class="flex flex-row">
|
<div class="flex flex-col gap-1">
|
||||||
<CirclePlay size="16" />
|
<Label class="flex flex-row">
|
||||||
{i18n._('toolbar.time.start')}
|
<CirclePlay size="16" />
|
||||||
</Label>
|
{i18n._('toolbar.time.start')}
|
||||||
<div class="flex flex-row gap-2">
|
</Label>
|
||||||
<DatePicker
|
<div class="flex flex-row gap-1.5">
|
||||||
bind:value={startDate}
|
<DatePicker
|
||||||
disabled={!canUpdate}
|
bind:value={startDate}
|
||||||
locale={i18n.lang}
|
disabled={!canUpdate}
|
||||||
placeholder={i18n._('toolbar.time.pick_date')}
|
locale={i18n.lang}
|
||||||
class="w-fit grow"
|
placeholder={i18n._('toolbar.time.pick_date')}
|
||||||
onchange={() => {
|
class="w-fit grow"
|
||||||
untrack(() => updateEnd());
|
onchange={() => {
|
||||||
}}
|
untrack(() => updateEnd());
|
||||||
/>
|
}}
|
||||||
<Input
|
/>
|
||||||
type="time"
|
<Input
|
||||||
step={1}
|
type="time"
|
||||||
disabled={!canUpdate}
|
step={1}
|
||||||
bind:value={startTime}
|
disabled={!canUpdate}
|
||||||
class="w-fit"
|
bind:value={startTime}
|
||||||
onchange={() => {
|
class="w-fit"
|
||||||
untrack(() => updateEnd());
|
onchange={() => {
|
||||||
}}
|
untrack(() => updateEnd());
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Label class="flex flex-row">
|
<div class="flex flex-col gap-1">
|
||||||
<CircleStop size="16" />
|
<Label class="flex flex-row">
|
||||||
{i18n._('toolbar.time.end')}
|
<CircleStop size="16" />
|
||||||
</Label>
|
{i18n._('toolbar.time.end')}
|
||||||
<div class="flex flex-row gap-2">
|
</Label>
|
||||||
<DatePicker
|
<div class="flex flex-row gap-1.5">
|
||||||
bind:value={endDate}
|
<DatePicker
|
||||||
disabled={!canUpdate}
|
bind:value={endDate}
|
||||||
locale={i18n.lang}
|
disabled={!canUpdate}
|
||||||
placeholder={i18n._('toolbar.time.pick_date')}
|
locale={i18n.lang}
|
||||||
class="w-fit grow"
|
placeholder={i18n._('toolbar.time.pick_date')}
|
||||||
onchange={() => {
|
class="w-fit grow"
|
||||||
untrack(() => updateStart());
|
onchange={() => {
|
||||||
}}
|
untrack(() => updateStart());
|
||||||
/>
|
}}
|
||||||
<Input
|
/>
|
||||||
type="time"
|
<Input
|
||||||
step={1}
|
type="time"
|
||||||
disabled={!canUpdate}
|
step={1}
|
||||||
bind:value={endTime}
|
disabled={!canUpdate}
|
||||||
class="w-fit"
|
bind:value={endTime}
|
||||||
onchange={() => {
|
class="w-fit"
|
||||||
untrack(() => updateStart());
|
onchange={() => {
|
||||||
}}
|
untrack(() => updateStart());
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#if $gpxStatistics.global.time.moving === 0 || $gpxStatistics.global.time.moving === undefined}
|
{#if $gpxStatistics.global.time.moving === 0 || $gpxStatistics.global.time.moving === undefined}
|
||||||
<div class="mt-0.5 flex flex-row gap-1 items-center">
|
<div class="mt-0.5 flex flex-row gap-1 items-center">
|
||||||
@@ -314,11 +318,11 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<div class="flex flex-row gap-2 items-center">
|
<div class="flex flex-row gap-1.5 items-center">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
disabled={!canUpdate}
|
disabled={!canUpdate}
|
||||||
class="grow whitespace-normal h-fit"
|
class="grow shrink whitespace-normal h-fit min-h-8 py-1"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
let effectiveSpeed = getSpeed();
|
let effectiveSpeed = getSpeed();
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
let props: { class?: string } = $props();
|
let props: { class?: string } = $props();
|
||||||
|
|
||||||
let sliderValue = $state([50]);
|
let sliderValue = $state(50);
|
||||||
const maxTolerance = 10000;
|
const maxTolerance = 10000;
|
||||||
|
|
||||||
let validSelection = $derived(
|
let validSelection = $derived(
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
tolerance.set(
|
tolerance.set(
|
||||||
minTolerance * 2 ** (sliderValue[0] / (100 / Math.log2(maxTolerance / minTolerance)))
|
minTolerance * 2 ** (sliderValue / (100 / Math.log2(maxTolerance / minTolerance)))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
<div class="flex flex-col gap-3 w-full max-w-80 {props.class ?? ''}">
|
<div class="flex flex-col gap-3 w-full max-w-80 {props.class ?? ''}">
|
||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<Slider bind:value={sliderValue} min={0} max={100} step={1} type="multiple" />
|
<Slider bind:value={sliderValue} min={0} max={100} step={1} type="single" />
|
||||||
</div>
|
</div>
|
||||||
<Label class="flex flex-row justify-between">
|
<Label class="flex flex-row justify-between">
|
||||||
<span>{i18n._('toolbar.reduce.tolerance')}</span>
|
<span>{i18n._('toolbar.reduce.tolerance')}</span>
|
||||||
|
|||||||
@@ -163,6 +163,9 @@ export class ReducedGPXLayerCollection {
|
|||||||
reduce() {
|
reduce() {
|
||||||
let itemsAndPoints = new Map<ListItem, TrackPoint[]>();
|
let itemsAndPoints = new Map<ListItem, TrackPoint[]>();
|
||||||
this._simplified.forEach(([item, maxPts, points], itemFullId) => {
|
this._simplified.forEach(([item, maxPts, points], itemFullId) => {
|
||||||
|
if (!get(selection).hasAnyParent(item)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
itemsAndPoints.set(
|
itemsAndPoints.set(
|
||||||
item,
|
item,
|
||||||
points
|
points
|
||||||
|
|||||||
@@ -191,7 +191,7 @@
|
|||||||
<ButtonWithTooltip
|
<ButtonWithTooltip
|
||||||
label={i18n._('toolbar.routing.reverse.tooltip')}
|
label={i18n._('toolbar.routing.reverse.tooltip')}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="gap-1 text-xs"
|
class="gap-1 text-xs px-1.5 py-1.5 h-fit"
|
||||||
disabled={!validSelection}
|
disabled={!validSelection}
|
||||||
onclick={fileActions.reverseSelection}
|
onclick={fileActions.reverseSelection}
|
||||||
>
|
>
|
||||||
@@ -200,7 +200,7 @@
|
|||||||
<ButtonWithTooltip
|
<ButtonWithTooltip
|
||||||
label={i18n._('toolbar.routing.route_back_to_start.tooltip')}
|
label={i18n._('toolbar.routing.route_back_to_start.tooltip')}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="gap-1 text-xs"
|
class="gap-1 text-xs px-1.5 py-1.5 h-fit"
|
||||||
disabled={!validSelection}
|
disabled={!validSelection}
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
const selected = selection.getOrderedSelection();
|
const selected = selection.getOrderedSelection();
|
||||||
@@ -236,14 +236,14 @@
|
|||||||
<ButtonWithTooltip
|
<ButtonWithTooltip
|
||||||
label={i18n._('toolbar.routing.round_trip.tooltip')}
|
label={i18n._('toolbar.routing.round_trip.tooltip')}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="gap-1 text-xs"
|
class="gap-1 text-xs px-1.5 py-1.5 h-fit"
|
||||||
disabled={!validSelection}
|
disabled={!validSelection}
|
||||||
onclick={fileActions.createRoundTripForSelection}
|
onclick={fileActions.createRoundTripForSelection}
|
||||||
>
|
>
|
||||||
<Repeat class="size-3" />{i18n._('toolbar.routing.round_trip.button')}
|
<Repeat class="size-3" />{i18n._('toolbar.routing.round_trip.button')}
|
||||||
</ButtonWithTooltip>
|
</ButtonWithTooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full flex flex-row gap-2 items-end justify-between">
|
<div class="w-full flex flex-row gap-1 items-end justify-between">
|
||||||
<Help link={getURLForLanguage(i18n.lang, '/help/toolbar/routing')}>
|
<Help link={getURLForLanguage(i18n.lang, '/help/toolbar/routing')}>
|
||||||
{#if !validSelection}
|
{#if !validSelection}
|
||||||
{i18n._('toolbar.routing.help_no_file')}
|
{i18n._('toolbar.routing.help_no_file')}
|
||||||
|
|||||||
@@ -55,9 +55,12 @@ export class RoutingControls {
|
|||||||
fileUnsubscribe: () => void = () => {};
|
fileUnsubscribe: () => void = () => {};
|
||||||
unsubscribes: Function[] = [];
|
unsubscribes: Function[] = [];
|
||||||
|
|
||||||
|
updateControlsBinded: () => void = this.updateControls.bind(this);
|
||||||
appendAnchorBinded: (e: MapMouseEvent) => void = this.appendAnchor.bind(this);
|
appendAnchorBinded: (e: MapMouseEvent) => void = this.appendAnchor.bind(this);
|
||||||
|
addIntermediateAnchorBinded: (e: MapMouseEvent) => void = this.addIntermediateAnchor.bind(this);
|
||||||
|
|
||||||
draggedAnchorIndex: number | null = null;
|
draggedAnchorIndex: number | null = null;
|
||||||
|
lastDraggedAnchorEventTime: number = 0;
|
||||||
draggingStartingPosition: maplibregl.Point = new maplibregl.Point(0, 0);
|
draggingStartingPosition: maplibregl.Point = new maplibregl.Point(0, 0);
|
||||||
onMouseEnterBinded: () => void = this.onMouseEnter.bind(this);
|
onMouseEnterBinded: () => void = this.onMouseEnter.bind(this);
|
||||||
onMouseLeaveBinded: () => void = this.onMouseLeave.bind(this);
|
onMouseLeaveBinded: () => void = this.onMouseLeave.bind(this);
|
||||||
@@ -84,7 +87,7 @@ export class RoutingControls {
|
|||||||
this.file = file;
|
this.file = file;
|
||||||
for (let zoom = MIN_ANCHOR_ZOOM; zoom <= MAX_ANCHOR_ZOOM; zoom++) {
|
for (let zoom = MIN_ANCHOR_ZOOM; zoom <= MAX_ANCHOR_ZOOM; zoom++) {
|
||||||
this.layers.set(zoom, {
|
this.layers.set(zoom, {
|
||||||
id: `routing-controls-${zoom}`,
|
id: `routing-controls-${this.fileId}-${zoom}`,
|
||||||
anchors: [],
|
anchors: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -129,10 +132,12 @@ export class RoutingControls {
|
|||||||
|
|
||||||
this.loadIcons();
|
this.loadIcons();
|
||||||
|
|
||||||
|
map_.on('style.load', this.updateControlsBinded);
|
||||||
map_.on('click', this.appendAnchorBinded);
|
map_.on('click', this.appendAnchorBinded);
|
||||||
layerEventManager.on('mousemove', this.fileId, this.showTemporaryAnchorBinded);
|
layerEventManager.on('mousemove', this.fileId, this.showTemporaryAnchorBinded);
|
||||||
|
layerEventManager.on('click', this.fileId, this.addIntermediateAnchorBinded);
|
||||||
|
|
||||||
this.fileUnsubscribe = this.file.subscribe(this.updateControls.bind(this));
|
this.fileUnsubscribe = this.file.subscribe(this.updateControlsBinded);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateControls() {
|
updateControls() {
|
||||||
@@ -232,8 +237,10 @@ export class RoutingControls {
|
|||||||
|
|
||||||
this.active = false;
|
this.active = false;
|
||||||
|
|
||||||
|
map_?.off('style.load', this.updateControlsBinded);
|
||||||
map_?.off('click', this.appendAnchorBinded);
|
map_?.off('click', this.appendAnchorBinded);
|
||||||
layerEventManager?.off('mousemove', this.fileId, this.showTemporaryAnchorBinded);
|
layerEventManager?.off('mousemove', this.fileId, this.showTemporaryAnchorBinded);
|
||||||
|
layerEventManager?.off('click', this.fileId, this.addIntermediateAnchorBinded);
|
||||||
map_?.off('mousemove', this.updateTemporaryAnchorBinded);
|
map_?.off('mousemove', this.updateTemporaryAnchorBinded);
|
||||||
|
|
||||||
this.layers.forEach((layer) => {
|
this.layers.forEach((layer) => {
|
||||||
@@ -518,15 +525,19 @@ export class RoutingControls {
|
|||||||
if (get(streetViewEnabled) && get(streetViewSource) === 'google') {
|
if (get(streetViewEnabled) && get(streetViewSource) === 'google') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
this.draggedAnchorIndex !== null ||
|
||||||
|
Date.now() - this.lastDraggedAnchorEventTime < 100
|
||||||
|
) {
|
||||||
|
// Exit if anchor is being dragged
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
e.target.queryRenderedFeatures(e.point, {
|
e.target.queryRenderedFeatures(e.point, {
|
||||||
layers: this.layers
|
layers: [this.fileId, ...[...this.layers.values()].map((layer) => layer.id)],
|
||||||
.values()
|
|
||||||
.map((layer) => layer.id)
|
|
||||||
.toArray(),
|
|
||||||
}).length
|
}).length
|
||||||
) {
|
) {
|
||||||
// Clicked on routing control, ignoring
|
// Clicked on routing control or layer, ignoring
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.appendAnchorWithCoordinates({
|
this.appendAnchorWithCoordinates({
|
||||||
@@ -598,6 +609,15 @@ export class RoutingControls {
|
|||||||
await this.routeBetweenAnchors([lastAnchor, newAnchor], [lastAnchorPoint, newAnchorPoint]);
|
await this.routeBetweenAnchors([lastAnchor, newAnchor], [lastAnchorPoint, newAnchorPoint]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addIntermediateAnchor(e: maplibregl.MapMouseEvent) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (this.temporaryAnchor !== null) {
|
||||||
|
this.turnIntoPermanentAnchor();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getNeighbouringAnchors(anchor: Anchor): [Anchor | null, Anchor | null] {
|
getNeighbouringAnchors(anchor: Anchor): [Anchor | null, Anchor | null] {
|
||||||
let previousAnchor: Anchor | null = null;
|
let previousAnchor: Anchor | null = null;
|
||||||
let nextAnchor: Anchor | null = null;
|
let nextAnchor: Anchor | null = null;
|
||||||
@@ -683,17 +703,7 @@ export class RoutingControls {
|
|||||||
try {
|
try {
|
||||||
response = await route(targetTrackPoints.map((trkpt) => trkpt.getCoordinates()));
|
response = await route(targetTrackPoints.map((trkpt) => trkpt.getCoordinates()));
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (e.message.includes('from-position not mapped in existing datafile')) {
|
toast.error(i18n._(e.message, e.message));
|
||||||
toast.error(i18n._('toolbar.routing.error.from'));
|
|
||||||
} else if (e.message.includes('via1-position not mapped in existing datafile')) {
|
|
||||||
toast.error(i18n._('toolbar.routing.error.via'));
|
|
||||||
} else if (e.message.includes('to-position not mapped in existing datafile')) {
|
|
||||||
toast.error(i18n._('toolbar.routing.error.to'));
|
|
||||||
} else if (e.message.includes('Time-out')) {
|
|
||||||
toast.error(i18n._('toolbar.routing.error.timeout'));
|
|
||||||
} else {
|
|
||||||
toast.error(e.message);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -810,7 +820,7 @@ export class RoutingControls {
|
|||||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
||||||
<circle cx="10" cy="10" r="8" fill="white" stroke="black" stroke-width="2" />
|
<circle cx="10" cy="10" r="8" fill="white" stroke="black" stroke-width="2" />
|
||||||
</svg>`,
|
</svg>`,
|
||||||
_map.getCanvasContainer().offsetWidth > 1000 ? 50 : 80
|
_map.getCanvasContainer().offsetWidth > 1000 ? 56 : 80
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -828,8 +838,11 @@ export class RoutingControls {
|
|||||||
onClick(e: MapLayerMouseEvent) {
|
onClick(e: MapLayerMouseEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (this.temporaryAnchor !== null) {
|
if (
|
||||||
this.turnIntoPermanentAnchor();
|
this.draggedAnchorIndex !== null ||
|
||||||
|
Date.now() - this.lastDraggedAnchorEventTime < 100
|
||||||
|
) {
|
||||||
|
// Exit if anchor is being dragged
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -918,6 +931,8 @@ export class RoutingControls {
|
|||||||
lat: e.lngLat.lat,
|
lat: e.lngLat.lat,
|
||||||
lon: e.lngLat.lng,
|
lon: e.lngLat.lng,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.lastDraggedAnchorEventTime = Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseUp(e: MapLayerMouseEvent | MapLayerTouchEvent) {
|
onMouseUp(e: MapLayerMouseEvent | MapLayerTouchEvent) {
|
||||||
@@ -956,6 +971,7 @@ export class RoutingControls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.draggedAnchorIndex = null;
|
this.draggedAnchorIndex = null;
|
||||||
|
this.lastDraggedAnchorEventTime = Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
showTemporaryAnchor(e: MapLayerMouseEvent) {
|
showTemporaryAnchor(e: MapLayerMouseEvent) {
|
||||||
@@ -1083,7 +1099,9 @@ export class RoutingControls {
|
|||||||
if (!this.temporaryAnchor) {
|
if (!this.temporaryAnchor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let source = get(map)?.getSource('routing-controls-0') as GeoJSONSource | undefined;
|
let source = get(map)?.getSource(`routing-controls-${this.fileId}-0`) as
|
||||||
|
| GeoJSONSource
|
||||||
|
| undefined;
|
||||||
if (source) {
|
if (source) {
|
||||||
if (this.temporaryAnchor) {
|
if (this.temporaryAnchor) {
|
||||||
source.updateData({
|
source.updateData({
|
||||||
@@ -1098,7 +1116,9 @@ export class RoutingControls {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const map_ = get(map);
|
const map_ = get(map);
|
||||||
let source = map_?.getSource('routing-controls-0') as GeoJSONSource | undefined;
|
let source = map_?.getSource(`routing-controls-${this.fileId}-0`) as
|
||||||
|
| GeoJSONSource
|
||||||
|
| undefined;
|
||||||
if (source) {
|
if (source) {
|
||||||
if (this.temporaryAnchor) {
|
if (this.temporaryAnchor) {
|
||||||
source.updateData({
|
source.updateData({
|
||||||
|
|||||||
@@ -6,37 +6,213 @@ import { get } from 'svelte/store';
|
|||||||
|
|
||||||
const { routing, routingProfile, privateRoads } = settings;
|
const { routing, routingProfile, privateRoads } = settings;
|
||||||
|
|
||||||
export const routingProfiles: { [key: string]: string } = {
|
export type RoutingProfile = {
|
||||||
bike: 'Trekking-dry',
|
engine: 'graphhopper' | 'brouter';
|
||||||
racing_bike: 'fastbike',
|
profile: string;
|
||||||
gravel_bike: 'gravel',
|
};
|
||||||
mountain_bike: 'MTB',
|
|
||||||
foot: 'Hiking-Alpine-SAC6',
|
export const routingProfiles: { [key: string]: RoutingProfile } = {
|
||||||
motorcycle: 'Car-FastEco',
|
bike: { engine: 'graphhopper', profile: 'bike' },
|
||||||
water: 'river',
|
racing_bike: { engine: 'graphhopper', profile: 'racingbike' },
|
||||||
railway: 'rail',
|
gravel_bike: { engine: 'graphhopper', profile: 'gravelbike' },
|
||||||
|
mountain_bike: { engine: 'graphhopper', profile: 'mtb' },
|
||||||
|
foot: { engine: 'graphhopper', profile: 'foot' },
|
||||||
|
motorcycle: { engine: 'graphhopper', profile: 'motorbike' },
|
||||||
|
water: { engine: 'brouter', profile: 'river' },
|
||||||
|
railway: { engine: 'brouter', profile: 'rail' },
|
||||||
};
|
};
|
||||||
|
|
||||||
export function route(points: Coordinates[]): Promise<TrackPoint[]> {
|
export function route(points: Coordinates[]): Promise<TrackPoint[]> {
|
||||||
if (get(routing)) {
|
if (get(routing)) {
|
||||||
return getRoute(points, routingProfiles[get(routingProfile)], get(privateRoads));
|
const profile = routingProfiles[get(routingProfile)];
|
||||||
|
if (profile.engine === 'graphhopper') {
|
||||||
|
return getGraphHopperRoute(points, profile.profile, get(privateRoads));
|
||||||
|
} else {
|
||||||
|
return getBRouterRoute(points, profile.profile);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return getIntermediatePoints(points);
|
return getIntermediatePoints(points);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getRoute(
|
const graphhopperDetails = ['road_class', 'surface', 'hike_rating', 'mtb_rating'];
|
||||||
|
const hikeRatingToSACScale: { [key: string]: string } = {
|
||||||
|
'1': 'hiking',
|
||||||
|
'2': 'mountain_hiking',
|
||||||
|
'3': 'demanding_mountain_hiking',
|
||||||
|
'4': 'alpine_hiking',
|
||||||
|
'5': 'demanding_alpine_hiking',
|
||||||
|
'6': 'difficult_alpine_hiking',
|
||||||
|
};
|
||||||
|
const mtbRatingToScale: { [key: string]: string } = {
|
||||||
|
'1': '0',
|
||||||
|
'2': '1',
|
||||||
|
'3': '2',
|
||||||
|
'4': '3',
|
||||||
|
'5': '4',
|
||||||
|
'6': '5',
|
||||||
|
'7': '6',
|
||||||
|
};
|
||||||
|
|
||||||
|
const graphhopperBlockPrivateCustomModels: { [key: string]: any } = {
|
||||||
|
bike: {
|
||||||
|
priority: [
|
||||||
|
{
|
||||||
|
if: 'bike_road_access == PRIVATE',
|
||||||
|
multiply_by: '0.0',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
racingbike: {
|
||||||
|
priority: [
|
||||||
|
{
|
||||||
|
if: 'bike_road_access == PRIVATE',
|
||||||
|
multiply_by: '0.0',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
gravelbike: {
|
||||||
|
priority: [
|
||||||
|
{
|
||||||
|
if: 'bike_road_access == PRIVATE',
|
||||||
|
multiply_by: '0.0',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
mtb: {
|
||||||
|
priority: [
|
||||||
|
{
|
||||||
|
if: 'bike_road_access == PRIVATE',
|
||||||
|
multiply_by: '0.0',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
foot: {
|
||||||
|
priority: [
|
||||||
|
{
|
||||||
|
if: 'foot_road_access == PRIVATE',
|
||||||
|
multiply_by: '0.0',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
motorcycle: {
|
||||||
|
priority: [
|
||||||
|
{
|
||||||
|
if: 'road_access == PRIVATE',
|
||||||
|
multiply_by: '0.0',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
async function getGraphHopperRoute(
|
||||||
points: Coordinates[],
|
points: Coordinates[],
|
||||||
brouterProfile: string,
|
graphHopperProfile: string,
|
||||||
privateRoads: boolean
|
privateRoads: boolean
|
||||||
): Promise<TrackPoint[]> {
|
): Promise<TrackPoint[]> {
|
||||||
let url = `https://brouter.gpx.studio?lonlats=${points.map((point) => `${point.lon.toFixed(8)},${point.lat.toFixed(8)}`).join('|')}&profile=${brouterProfile + (privateRoads ? '-private' : '')}&format=geojson&alternativeidx=0`;
|
let response = await fetch('https://graphhopper.gpx.studio/route', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
points: points.map((point) => [point.lon, point.lat]),
|
||||||
|
profile: graphHopperProfile,
|
||||||
|
elevation: true,
|
||||||
|
points_encoded: false,
|
||||||
|
details: graphhopperDetails,
|
||||||
|
custom_model: privateRoads
|
||||||
|
? {}
|
||||||
|
: graphhopperBlockPrivateCustomModels[graphHopperProfile] || {},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const error = await response.json();
|
||||||
|
if (error.message.includes('Cannot find point 0')) {
|
||||||
|
throw new Error('toolbar.routing.error.from');
|
||||||
|
} else if (error.message.includes('Cannot find point 1')) {
|
||||||
|
if (points.length == 3) {
|
||||||
|
throw new Error('toolbar.routing.error.via');
|
||||||
|
} else {
|
||||||
|
throw new Error('toolbar.routing.error.to');
|
||||||
|
}
|
||||||
|
} else if (error.hints[0].details.includes('PointDistanceExceededException')) {
|
||||||
|
throw new Error('toolbar.routing.error.distance');
|
||||||
|
} else if (error.hints[0].details.includes('ConnectionNotFoundException')) {
|
||||||
|
throw new Error('toolbar.routing.error.connection');
|
||||||
|
} else {
|
||||||
|
throw new Error(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let json = await response.json();
|
||||||
|
|
||||||
|
let route: TrackPoint[] = [];
|
||||||
|
let coordinates = json.paths[0].points.coordinates;
|
||||||
|
let details = json.paths[0].details;
|
||||||
|
|
||||||
|
for (let i = 0; i < coordinates.length; i++) {
|
||||||
|
route.push(
|
||||||
|
new TrackPoint({
|
||||||
|
attributes: {
|
||||||
|
lat: coordinates[i][1],
|
||||||
|
lon: coordinates[i][0],
|
||||||
|
},
|
||||||
|
ele: coordinates[i][2] ?? (i > 0 ? route[i - 1].ele : 0),
|
||||||
|
extensions: {},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let key of graphhopperDetails) {
|
||||||
|
let detail = details[key];
|
||||||
|
for (let i = 0; i < detail.length; i++) {
|
||||||
|
for (let j = detail[i][0]; j < detail[i][1] + (i == detail.length - 1); j++) {
|
||||||
|
if (detail[i][2] !== undefined && detail[i][2] !== 'missing') {
|
||||||
|
if (key === 'road_class') {
|
||||||
|
route[j].setExtension('highway', detail[i][2]);
|
||||||
|
} else if (key === 'hike_rating') {
|
||||||
|
const sacScale = hikeRatingToSACScale[detail[i][2]];
|
||||||
|
if (sacScale) {
|
||||||
|
route[j].setExtension('sac_scale', sacScale);
|
||||||
|
}
|
||||||
|
} else if (key === 'mtb_rating') {
|
||||||
|
const mtbScale = mtbRatingToScale[detail[i][2]];
|
||||||
|
if (mtbScale) {
|
||||||
|
route[j].setExtension('mtb_scale', mtbScale);
|
||||||
|
}
|
||||||
|
} else if (key === 'surface' && detail[i][2] !== 'other') {
|
||||||
|
route[j].setExtension('surface', detail[i][2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return route;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getBRouterRoute(
|
||||||
|
points: Coordinates[],
|
||||||
|
brouterProfile: string
|
||||||
|
): Promise<TrackPoint[]> {
|
||||||
|
let url = `https://brouter.de/brouter?lonlats=${points.map((point) => `${point.lon.toFixed(8)},${point.lat.toFixed(8)}`).join('|')}&profile=${brouterProfile}&format=geojson&alternativeidx=0`;
|
||||||
|
|
||||||
let response = await fetch(url);
|
let response = await fetch(url);
|
||||||
|
|
||||||
// Check if the response is ok
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`${await response.text()}`);
|
const error = await response.text();
|
||||||
|
if (error.includes('from-position not mapped in existing datafile')) {
|
||||||
|
throw new Error('toolbar.routing.error.from');
|
||||||
|
} else if (error.includes('via1-position not mapped in existing datafile')) {
|
||||||
|
throw new Error('toolbar.routing.error.via');
|
||||||
|
} else if (error.includes('to-position not mapped in existing datafile')) {
|
||||||
|
throw new Error('toolbar.routing.error.to');
|
||||||
|
} else if (error.includes('Time-out')) {
|
||||||
|
throw new Error('toolbar.routing.error.timeout');
|
||||||
|
} else {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let geojson = await response.json();
|
let geojson = await response.json();
|
||||||
@@ -52,14 +228,13 @@ async function getRoute(
|
|||||||
let tags = messageIdx < messages.length ? getTags(messages[messageIdx][tagIdx]) : {};
|
let tags = messageIdx < messages.length ? getTags(messages[messageIdx][tagIdx]) : {};
|
||||||
|
|
||||||
for (let i = 0; i < coordinates.length; i++) {
|
for (let i = 0; i < coordinates.length; i++) {
|
||||||
let coord = coordinates[i];
|
|
||||||
route.push(
|
route.push(
|
||||||
new TrackPoint({
|
new TrackPoint({
|
||||||
attributes: {
|
attributes: {
|
||||||
lat: coord[1],
|
lat: coordinates[i][1],
|
||||||
lon: coord[0],
|
lon: coordinates[i][0],
|
||||||
},
|
},
|
||||||
ele: coord[2] ?? (i > 0 ? route[i - 1].ele : 0),
|
ele: coordinates[i][2] ?? (i > 0 ? route[i - 1].ele : 0),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||