GPS trackers are now part of the hobby for many hikers. Minaturized devices display maps, track walks, and produce data known as GPS *traces*. A lot of these hiking traces are available on the web, on open data portals. An exchange format, called **GPX** for [GPS] e[X]change format, offers a simple way to organize these data into small and pratical files.

A GPX file contains a collection of points, forming a trace when put together. Some metadata like the name, author or copyright of the trace can be added to the file. The city of Grenoble, in southeastern France, publishes a dataset of many hiking routes around its surroundings [1] . Many traces are available as GPX files, free to download and use for hikers.

One of them can be downloaded using this URL:

http://www.grenoble-montagne.com/uploads/Ballade/95/36_216_dent-de-crolles.gpx

This trace shows a path around the Dent de Crolles, *Crolles Tooth*, a mountain at the north east of Grenoble, France.

# Reading GPX data

To load GPX data, the `readOGR`

function from the `rgdal`

[2] package can be used. The function needs teh user to name the layer containing GPS points, in our case `track_points`

.

`library(rgdal)`

```
gpx <- rgdal::readOGR("36_216_dent-de-crolles.gpx",
layer = "track_points")
```

The gpx variable is now a `SpatialPointsDataFrame`

object, or an ordered collection of points. It must be converted to a line object to use it as a trace.

# From multiple GPS points to a single trace

To convert a `SpatialPoints`

object to a trace, the `sp`

[3] package comes to help. First, 2 dimensional points are converted to GPS coordinates using the `coordinates`

function. Then the `Line`

function concatenates the coordiantes into a single line. To finish, we lay the `Line`

object into a list, assigning an identifier to encapsulate it in a `SpatialLines`

object. Many functions use objects from the `SpatialLines`

class to display or modify traces.

`library(sp)`

```
track <- coordinates(gpx)
track <- Line(track)
track <- list(Lines(track,
ID = "Dent de Crolles"))
track <- SpatialLines(track)
```

# Map projection

Map projection is the ensemble of techniques allowing us to display non-flat surface (Like earth) on flat surface (Like maps) [4] . Many projection techniques exist [5], as rectangular maps are not the only available solution for this problem.

In our case, a `SpatialLines`

object must contain the projection metadata of the geodata it carries. This infomrmation can be retreived form the GPX file, using the `proj4string`

function on the gpx variable containing GPX raw data.

`proj4string(gpx)`

`## [1] "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"`

This long string contains all the references needed to display the points on a regular map. `WGS84`

stands for [W]orld [G]eodetic [S]ystem, a standard projection in GPS systems. The projection metadata can now be assigned to the `SpatialLines`

object stored in the `track`

variable.

`proj4string(track) <- proj4string(gpx)`

# Display the trace on a regular map

The `leaflet`

R package [6] makes it easy to display maps using R. It encapsulates the popular Leaflet Javascript library [7].

`library(leaflet)`

Only a few functions are needed to display the trace. `leaflet`

initialize the map, while `addTiles`

adds the default map background from OpenStreetMap [8]. To finish, `addPolylines`

adds all the lines containes in the `track`

variable.

```
map <- leaflet()
map <- addTiles(map)
map <- addPolylines(map, data = track)
map
```

# Getting elevation data

Displaying a trace on a 2D can be usefull, but many hikers also need informations about the elevation to plan and prepare for a hike. Elevation is often contained in GPS data. However, points may not all at equal distance from each other. Distance between points is needed to display a correct elevation graph for a given track. For this case, the `geosphere`

package can be used to compute the distance between each point of our track.

`library(geosphere)`

A distance vector is initialized to 0, as there is no point preceding it, thus a null distance. A simple loop iterates each point of the track, using the `distm`

function to compute the distance of the point from the previous one. The Haversine formula [9] is used here, meaning the shortest distance between two points situated on a sphere.

```
gpx$distance <- 0
for(i in c(1:nrow(gpx))){
point <- gpx[i,]
if(i > 1){
gpx$distance[i] <- distm(
coordinates(gpx[(i-1),]),
coordinates(gpx[i,]),
fun = distHaversine) +
gpx$distance[i-1]
}
}
```

Finally, the elevation data can be plotted, here using the `plotly`

library.

```
library(plotly)
p <- plot_ly(data.frame(gpx),
x=~distance,
y=~ele,
mode = 'lines',
type = 'scatter')
p <- layout(p,
xaxis = list(title = "Distance (meters)"),
yaxis = list(title = "Elevation (meters)"))
p
```

# Net gain, Ascent and Descent

Height, Ascent and Descent are aggregated values used by hiker to quickly get an idea of a path difficulty, without looking at the elevation chart we previously plotted.

Height, Ascent and Descent are 3 distinct indicators:

**Net gain**: The difference between arrival elevation and departure elevation.**Ascent**: The sum of all elevation gains.**Descent**: The sum of all elevation losses.

Net gain is ineed an easy formula:

`max(gpx$ele) - min(gpx$ele)`

`## [1] 599`

To compute ascent and descent, we can use a loop to iterate over each point elevation and add the differences in the right vector.

```
ascent <- 0
descent <- 0
for(i in c(2:length(gpx$ele))){
diff <- gpx$ele[i] - gpx$ele[i-1]
if(diff > 0){
ascent <- ascent + diff
} else {
descent <- descent + diff
}
}
```

`ascent`

`## [1] 874`

`descent`

`## [1] -874`

The Dent de Crolles path starts and finishes in the same place. Ascent and absolute descent are thus the same values.

# References

[1] G. Montagne, Parcourir nos massifs, (n.d.). http://www.grenoble-montagne.com/779-parcourir-nos-massifs.htm (accessed April 9, 2019).

[2] R. Bivand, T. Keitt, B. Rowlingson, E. Pebesma, Rgdal: Bindings for the geospatial data abstraction library, R Package Version 0.8-16. (2014).

[3] E. Pebesma, R.S. Bivand, S classes and methods for spatial data: The sp package, Unpublished Report. (2005).

[4] M. kennedy, Understanding map projections, (n.d.). https://kartoweb.itc.nl/geometrics/Map%20projections/Understanding%20Map%20Projections.pdf (accessed April 9, 2019).

[5] Map projections examples, (n.d.). https://www.mapthematics.com/Downloads/Images/Cornucopia33.jpg (accessed April 9, 2019).

[6] Leaflet for r, (n.d.). https://rstudio.github.io/leaflet/ (accessed April 9, 2019).

[7] Leaflet, an open-source javascript library for mobile-friendly interactive maps, (n.d.). https://leafletjs.com/ (accessed April 9, 2019).

[8] OpenStreetMap, (n.d.). https://www.openstreetmap.org (accessed April 9, 2019).

[9] R.W. Sinnott, Virtues of the haversine, Sky Telesc. 68 (1984) 159.