-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.html
228 lines (203 loc) · 17.5 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Plot A Route From A GPX File • gpx3d</title>
<!-- jquery --><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script><!-- Bootstrap --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha256-bZLfwXAP04zRMK2BjiO8iu9pf4FbLqX6zitd+tIvLhE=" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha256-nuL8/2cJ5NDSSwnKD8VqreErSWHtnEP9E7AySL+1ev4=" crossorigin="anonymous"></script><!-- bootstrap-toc --><link rel="stylesheet" href="bootstrap-toc.css">
<script src="bootstrap-toc.js"></script><!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous">
<!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- pkgdown --><link href="pkgdown.css" rel="stylesheet">
<script src="pkgdown.js"></script><meta property="og:title" content="3D Plot A Route From A GPX File">
<meta property="og:description" content="Extract a data from a GPX file into a an sf-class dataframe, then
plot a 3D rendering of the route. Designed with workout-route data from the
Apple Health app in mind.">
<!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body data-spy="scroll" data-target="#toc">
<div class="container template-home">
<header><div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="navbar-brand">
<a class="navbar-link" href="index.html">gpx3d</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="">0.0.0.9002</span>
</span>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>
<a href="reference/index.html">Reference</a>
</li>
<li>
<a href="news/index.html">Changelog</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="https://github.com/matt-dray/gpx3d/" class="external-link">
<span class="fab fa-github fa-lg"></span>
</a>
</li>
</ul>
</div>
<!--/.nav-collapse -->
</div>
<!--/.container -->
</div>
<!--/.navbar -->
</header><div class="row">
<div class="contents col-md-9">
<div class="section level1">
<div class="page-header"><h1 id="gpx3d">{gpx3d}<a class="anchor" aria-label="anchor" href="#gpx3d"></a>
</h1></div>
<!-- badges: start -->
<p>An in-development, opinionated R package to create interactive 3D plots of workout routes.</p>
<p>Takes a .gpx file—downloaded from the Apple Health app, for example—and extracts the time, coordinates and elevation into an sf-class object. You can then plot this as a 3D interactive object thanks to <a href="https://coolbutuseless.github.io/package/ggrgl/index.html" class="external-link">{ggrgl}</a>.</p>
<p>Read more <a href="https://www.rostrum.blog/2021/12/30/gpx3d/" class="external-link">in the accompanying blogpost</a> or visit <a href="https://matt-dray.github.io/gpx3d/" class="external-link">the documentation website</a>.</p>
<div class="section level2">
<h2 id="install">Install<a class="anchor" aria-label="anchor" href="#install"></a>
</h2>
<p>The package is available from GitHub only.</p>
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="fu"><a href="https://rdrr.io/r/utils/install.packages.html" class="external-link">install.packages</a></span><span class="op">(</span><span class="st">"remotes"</span><span class="op">)</span> <span class="co"># if not installed already</span>
<span class="fu">remotes</span><span class="fu">::</span><span class="fu">install_github</span><span class="op">(</span><span class="st">"matt-dray/gpx3d"</span><span class="op">)</span>
<span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://github.com/matt-dray/gpx3d" class="external-link">gpx3d</a></span><span class="op">)</span></code></pre></div>
<p>There are a number of dependencies, including many that are not available on CRAN; see <a href="https://coolbutuseless.github.io/package/ggrgl/index.html#installation" class="external-link">the README for {ggrgl}</a> for details. You must also <a href="https://www.xquartz.org/" class="external-link">install XQuartz</a>, if you haven’t already.</p>
</div>
<div class="section level2">
<h2 id="demo">Demo<a class="anchor" aria-label="anchor" href="#demo"></a>
</h2>
<p>The package contains an example GPX file with an edited segment of a route I took as part of a 10 km run on Christmas morning 2021. It can be read in with <code><a href="reference/extract_gpx3d.html">extract_gpx3d()</a></code>, which outputs an sf-class data.frame with geospatial information. (Alternatively, you can output a simpler data.frame object with the <code><a href="reference/extract_gpx3d.html">extract_gpx3d()</a></code> argument <code>sf_out = FALSE</code>.)</p>
<div class="sourceCode" id="cb2"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="va">x</span> <span class="op"><-</span> <span class="fu"><a href="https://rdrr.io/r/base/system.file.html" class="external-link">system.file</a></span><span class="op">(</span><span class="st">"extdata"</span>, <span class="st">"segment.gpx"</span>, package <span class="op">=</span> <span class="st">"gpx3d"</span><span class="op">)</span>
<span class="va">y</span> <span class="op"><-</span> <span class="fu"><a href="reference/extract_gpx3d.html">extract_gpx3d</a></span><span class="op">(</span><span class="va">x</span><span class="op">)</span>
<span class="va">y</span></code></pre></div>
<div class="sourceCode" id="cb3"><pre class="sourceCode R"><code class="sourceCode r"><span id="cb3-1"><a href="#cb3-1"></a><span class="co"># Simple feature collection with 501 features and 5 fields</span></span>
<span id="cb3-2"><a href="#cb3-2"></a><span class="co"># Geometry type: POINT</span></span>
<span id="cb3-3"><a href="#cb3-3"></a><span class="co"># Dimension: XY</span></span>
<span id="cb3-4"><a href="#cb3-4"></a><span class="co"># Bounding box: xmin: 0.552347 ymin: 50.85061 xmax: 0.559273 ymax: 50.85968</span></span>
<span id="cb3-5"><a href="#cb3-5"></a><span class="co"># Geodetic CRS: WGS 84</span></span>
<span id="cb3-6"><a href="#cb3-6"></a><span class="co"># First 10 features:</span></span>
<span id="cb3-7"><a href="#cb3-7"></a><span class="co"># time ele lon lat geometry distance</span></span>
<span id="cb3-8"><a href="#cb3-8"></a><span class="co"># 1 2021-12-25 09:13:29 8.406136 0.559273 50.85109 POINT (0.559273 50.85109) 0.000000 [m]</span></span>
<span id="cb3-9"><a href="#cb3-9"></a><span class="co"># 2 2021-12-25 09:13:30 8.498508 0.559209 50.85109 POINT (0.559209 50.85109) 4.494285 [m]</span></span>
<span id="cb3-10"><a href="#cb3-10"></a><span class="co"># 3 2021-12-25 09:13:31 8.599027 0.559144 50.85109 POINT (0.559144 50.85109) 4.564465 [m]</span></span>
<span id="cb3-11"><a href="#cb3-11"></a><span class="co"># 4 2021-12-25 09:13:32 8.721706 0.559079 50.85109 POINT (0.559079 50.85109) 4.564465 [m]</span></span>
<span id="cb3-12"><a href="#cb3-12"></a><span class="co"># 5 2021-12-25 09:13:34 8.858613 0.559015 50.85109 POINT (0.559015 50.85109) 4.492909 [m]</span></span>
<span id="cb3-13"><a href="#cb3-13"></a><span class="co"># 6 2021-12-25 09:13:35 9.007253 0.558952 50.85109 POINT (0.558952 50.85109) 4.422707 [m]</span></span>
<span id="cb3-14"><a href="#cb3-14"></a><span class="co"># 7 2021-12-25 09:13:36 9.154713 0.558889 50.85109 POINT (0.558889 50.85109) 4.424104 [m]</span></span>
<span id="cb3-15"><a href="#cb3-15"></a><span class="co"># 8 2021-12-25 09:13:37 9.315786 0.558825 50.85109 POINT (0.558825 50.85109) 4.494284 [m]</span></span>
<span id="cb3-16"><a href="#cb3-16"></a><span class="co"># 9 2021-12-25 09:13:38 9.493576 0.558762 50.85109 POINT (0.558762 50.85109) 4.422707 [m]</span></span>
<span id="cb3-17"><a href="#cb3-17"></a><span class="co"># 10 2021-12-25 09:13:39 9.686247 0.558699 50.85109 POINT (0.558699 50.85109) 4.424104 [m]</span></span></code></pre></div>
<p>Note that the result of <code>extract_gpx3d(x)</code> is also available in the package as the demo dataset <code>gpx_segment</code>.</p>
<p>Now you can use <code><a href="reference/plot_gpx3d.html">plot_gpx3d()</a></code> to plot the output from <code><a href="reference/extract_gpx3d.html">extract_gpx3d()</a></code>. This opens in an external RGL device.</p>
<div class="sourceCode" id="cb4"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="fu"><a href="reference/plot_gpx3d.html">plot_gpx3d</a></span><span class="op">(</span><span class="va">y</span><span class="op">)</span></code></pre></div>
<p>The plots can’t be embedded here, so here’s a low-quality screenshot of the device:</p>
<div class="figure">
<p><img src="reference/figures/plot_v9002.png" alt="Screenshot of a 3D linechart which represents a workout route. X, Y and Z dimensions are latitude, longitude and elevation. The title is '1.4 km route with elevation disparity of 71 m' with a subtitle giving the date and start and end times. The route shows an ascent from near sea level to the top of a hill." width="50%"></p>
</div>
<p>The title gives the route length (1.4 km) and the elevation difference from lowest to highest points (71 m); the subtitle gives the date (2021-12-25) and the start (09:13:29) to end (09:21:49) times. X and Y are longitude and latiutude.</p>
<p>You can use <code>route_only = TRUE</code> to remove all of the chart elements except for the route itself:</p>
<div class="sourceCode" id="cb5"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="fu"><a href="reference/plot_gpx3d.html">plot_gpx3d</a></span><span class="op">(</span><span class="va">y</span>, route_only <span class="op">=</span> <span class="cn">TRUE</span><span class="op">)</span></code></pre></div>
<div class="figure">
<p><img src="reference/figures/plot_route-only_v9002.png" alt="Screenshot of a 3D linechart that represents a workout route. X, Y and Z dimensions are latitude, longitude and elevation. All chart decoration has been removed. The route shows an ascent from near sea level to the top of a hill." width="50%"></p>
</div>
<p>The <code><a href="reference/plot_gpx3d.html">plot_gpx3d()</a></code> output is interactive so you can click and drag it, and scroll to zoom. Here’s a more exaggerated view of the elevation:</p>
<div class="figure">
<p><img src="reference/figures/plot_route-only-adjusted_v9002.png" alt="Screenshot of a 3D linechart that represents a workout route. X, Y and Z dimensions are latitude, longitude and elevation. All chart decoration has been removed. The route shows an ascent from near sea level to the top of a hill. The angle of the chart has been changed to exaggerate the elevation." width="50%"></p>
</div>
<p>This highlights how useful the third dimension is, given the ascent from sea-level to the top of a hill in this example.</p>
</div>
<div class="section level2">
<h2 id="thanks">Thanks<a class="anchor" aria-label="anchor" href="#thanks"></a>
</h2>
<p>This package wouldn’t be possible without:</p>
<ul>
<li>
<a href="https://coolbutuseless.github.io/package/ggrgl/index.html" class="external-link">{ggrgl}</a> and friends by <a href="https://coolbutuseless.github.io/" class="external-link">mikefc (AKA coolbutuseless)</a>
</li>
<li><a href="https://ggplot2.tidyverse.org/" class="external-link">{ggplot2} by Hadley Wickham</a></li>
<li><a href="https://xml2.r-lib.org/" class="external-link">{xml2} by Hadley Wickham, Jim Hester and Jeroen Ooms</a></li>
<li><a href="https://r-spatial.github.io/sf/appl" class="external-link">{sf} by Edzer Pebesma</a></li>
<li><a href="https://www.apple.com/uk/ios/health/mikefc" class="external-link">Apple’s Health app</a></li>
</ul>
</div>
<div class="section level2">
<h2 id="code-of-conduct">Code of Conduct<a class="anchor" aria-label="anchor" href="#code-of-conduct"></a>
</h2>
<p>Please note that the {gpx3d} project is released with a <a href="https://contributor-covenant.org/version/2/0/CODE_OF_CONDUCT.html" class="external-link">Contributor Code of Conduct</a>. By contributing to this project, you agree to abide by its terms.</p>
</div>
</div>
</div>
<div class="col-md-3 hidden-xs hidden-sm" id="pkgdown-sidebar">
<div class="links">
<h2 data-toc-skip>Links</h2>
<ul class="list-unstyled">
<li><a href="https://github.com/matt-dray/gpx3d/" class="external-link">Browse source code</a></li>
<li><a href="https://github.com/matt-dray/gpx3d/issues" class="external-link">Report a bug</a></li>
</ul>
</div>
<div class="license">
<h2 data-toc-skip>License</h2>
<ul class="list-unstyled">
<li><a href="LICENSE.html">Full license</a></li>
<li><small><a href="https://opensource.org/licenses/mit-license.php" class="external-link">MIT</a> + file <a href="LICENSE-text.html">LICENSE</a></small></li>
</ul>
</div>
<div class="community">
<h2 data-toc-skip>Community</h2>
<ul class="list-unstyled">
<li><a href="CODE_OF_CONDUCT.html">Code of conduct</a></li>
</ul>
</div>
<div class="citation">
<h2 data-toc-skip>Citation</h2>
<ul class="list-unstyled">
<li><a href="authors.html#citation">Citing gpx3d</a></li>
</ul>
</div>
<div class="developers">
<h2 data-toc-skip>Developers</h2>
<ul class="list-unstyled">
<li>Matt Dray <br><small class="roles"> Author, maintainer </small> </li>
</ul>
</div>
<div class="dev-status">
<h2 data-toc-skip>Dev status</h2>
<ul class="list-unstyled">
<li><a href="https://www.repostatus.org/#wip" class="external-link"><img src="https://www.repostatus.org/badges/latest/wip.svg" alt="Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public."></a></li>
<li><a href="https://CRAN.R-project.org/package=gfx3d" class="external-link"><img src="https://www.r-pkg.org/badges/version/gfx3d" alt="CRAN status"></a></li>
<li><a href="https://github.com/matt-dray/gpx3d/actions" class="external-link"><img src="https://github.com/matt-dray/gpx3d/workflows/R-CMD-check/badge.svg" alt="R-CMD-check"></a></li>
<li><a href="https://codecov.io/gh/matt-dray/gpx3d?branch=main" class="external-link"><img src="https://codecov.io/gh/matt-dray/gpx3d/branch/main/graph/badge.svg" alt="Codecov test coverage"></a></li>
<li><a href="https://www.rostrum.blog/2021/12/30/gpx3d/" class="external-link"><img src="https://img.shields.io/badge/rostrum.blog-post-008900?labelColor=000000&logo=data%3Aimage%2Fgif%3Bbase64%2CR0lGODlhEAAQAPEAAAAAABWCBAAAAAAAACH5BAlkAAIAIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAAQAAAC55QkISIiEoQQQgghRBBCiCAIgiAIgiAIQiAIgSAIgiAIQiAIgRAEQiAQBAQCgUAQEAQEgYAgIAgIBAKBQBAQCAKBQEAgCAgEAoFAIAgEBAKBIBAQCAQCgUAgEAgCgUBAICAgICAgIBAgEBAgEBAgEBAgECAgICAgECAQIBAQIBAgECAgICAgICAgECAQECAQICAgICAgICAgEBAgEBAgEBAgICAgICAgECAQIBAQIBAgECAgICAgIBAgECAQECAQIBAgICAgIBAgIBAgEBAgECAgECAgICAgICAgECAgECAgQIAAAQIKAAAh%2BQQJZAACACwAAAAAEAAQAAAC55QkIiESIoQQQgghhAhCBCEIgiAIgiAIQiAIgSAIgiAIQiAIgRAEQiAQBAQCgUAQEAQEgYAgIAgIBAKBQBAQCAKBQEAgCAgEAoFAIAgEBAKBIBAQCAQCgUAgEAgCgUBAICAgICAgIBAgEBAgEBAgEBAgECAgICAgECAQIBAQIBAgECAgICAgICAgECAQECAQICAgICAgICAgEBAgEBAgEBAgICAgICAgECAQIBAQIBAgECAgICAgIBAgECAQECAQIBAgICAgIBAgIBAgEBAgECAgECAgICAgICAgECAgECAgQIAAAQIKAAA7" alt="Blog post"></a></li>
</ul>
</div>
</div>
</div>
<footer><div class="copyright">
<p></p>
<p>Developed by Matt Dray.</p>
</div>
<div class="pkgdown">
<p></p>
<p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.0.1.</p>
</div>
</footer>
</div>
</body>
</html>