Visualiser des traces de randonnée GPX et des photos avec leaflet

Visualiser des traces de randonnée GPX et des photos avec leaflet

Marion Louveaux

6 minutes


Dans cet article, j’utilise une carte interactive avec {leaflet} pour afficher une randonnée et y positionner des photographies du paysage à l’aide de pop-ups.

Cet été, je suis allée en Bretagne, dans le “Golfe du Morbihan”. Dans le Golfe, il y a beaucoup d’îlots, certains habités, d’autres pas, tous très beaux. J’ai fait une journée de randonnée sur le plus grand îlot, appelé “l’île aux moines”. J’avais avec moi mon appareil photo et une application de randonnée appelée ViewRanger pour enregistrer mon parcours. Comme j’aime jouer avec les données, je me suis immédiatement dit : pourquoi ne pas essayer de positionner mes photos sur la carte une fois rentrée chez moi ?

Dans l’article ci-dessous, j’explique comment charger le fichier .gpx de ma randonnée dans R, comment le visualiser avec {leaflet} et comment afficher les photos dans des fenêtres pop-up sur la carte, à l’endroit où elles ont été prises. Pour positionner les photos, je compare l’horodatage présent dans les métadonnées du fichier à l’horodatage des points de ma trace .gpx.

library(dplyr)
library(ggplot2)
library(leaflet)
library(leafpop)
library(lubridate)
library(purrr)
library(readr)
library(sf)
library(tibble)
library(tidyr)

Importer une trace GPX dans R

Tout d’abord, je charge dans R le fichier de trace de randonnée .gpx créé par ViewRanger, une application de randonnée pour smartphone, en utilisant la fonction st_read() du paquet {sf}.

Le fichier .gpx que j’utilise peut être téléchargé en utilisant la commande ci-dessous (Afficher le code en cliquant sur le bouton “code”) ou en cliquant ici : 20200903_ile_aux_moines.gpx.

curl::curl_download("https://marionlouveaux.fr/blog/2020-10-24_gpx_tracks_and_leaflet_map/20200903_ile_aux_moines.gpx",
                    destfile = "20200903_ile_aux_moines.gpx")
gpx_file <- "20200903_ile_aux_moines.gpx"

La fonction st_layers() m’indique que le fichier .gpx contient plusieurs couches. Pour la suite, j’utiliserai la couche track_points.

st_layers(gpx_file)
## Driver: GPX 
## Available layers:
##     layer_name     geometry_type features fields
## 1    waypoints             Point        0     23
## 2       routes       Line String        0     12
## 3       tracks Multi Line String        1     13
## 4 route_points             Point        0     25
## 5 track_points             Point     1326     26

Ensuite, je réorganise les données de la trace de randonnée. Je sépare la colonne de temps en une colonne de date et de pas de temps pour faciliter la comparaison ultérieure avec les métadonnées de l’image. Enfin j’affiche la carte avec {ggplot2}.

track1 <- read_sf(gpx_file, layer = "track_points") %>%
  separate(col = time, into = c("date", "timepoint"), sep = " ", remove = FALSE)

ggplot(track1) +
  geom_sf() +
  theme_bw()

Afficher un fond de carte avec {leaflet}

J’ai choisi d’utiliser une carte interactive {leaflet} pour avoir la possibilité d’afficher mes photos dans des pop-ups et de faire des zooms avant et arrière sur la carte. Le package R {leaflet} fournit une interface pratique avec la librairie JavaScript Leaflet.

J’utilise la fonction leaflet() pour créer une carte {leaflet} et addProviderTiles() pour ajouter un fond de carte. Il existe de nombreux fournisseurs de cartes. Pour choisir un fond de carte, j’utilise ce site web de pré-visualisation de fonds de carte leaflet. Pour illustrer la diversité des fonds de carte dans cet article, j’utiliserai d’abord Stamen.Watercolor, un fond plutôt artistique, puis OpenStreetMap.France, qui est plus précis et plus facile à lire.

map_leaflet <- leaflet() %>%
  addProviderTiles('Stamen.Watercolor')

map_leaflet

Ajouter une trace de randonnée sur une carte {leaflet}

Je peux maintenant ajouter le chemin de randonnée gpx à la carte {leaflet}. Je convertis les points qui constituent le sentier de randonnée en une ligne en utilisant st_combine() et st_cast(), puis je convertis la ligne en un objet sf en utilisant st_sf().

track2 <- track1 %>%
  st_combine() %>%
  st_cast(to = "LINESTRING") %>%
  st_sf()

J’ajoute la ligne du sentier de randonnée à la carte {leaflet} avec addPolylines().

map_leaflet <- leaflet() %>%
  addProviderTiles("Stamen.Watercolor")

map_leaflet %>%
  addPolylines(data = track2)

Ajouter des pop-ups sur une carte {leaflet} pour afficher les photos de la randonnée

Je voulais ajouter les photos que j’avais prises pendant la randonnée avec mon appareil photo sur la carte {leaflet}. Les métadonnées des fichiers de mes photos ne contiennent pas directement une position GPS, mais elles contiennent une date de création. Je peux utiliser cet horodatage pour joindre la photo à une coordonnée géographique sur le chemin de randonnée.
Les photos peuvent être téléchargées à l’aide des commandes ci-dessous (déplier le code en cliquant sur le bouton “code”) ou en cliquant ici: images.zip

curl::curl_download((url = "https://marionlouveaux.fr/blog/2020-10-24_gpx_tracks_and_leaflet_map/images.zip", 
                     destfile = "images.zip")
unzip("images.zip")
dir_path <- "images"
photo_path <- list.files(dir_path, full.names = TRUE)

Je créé un fichier .csv pour stocker un joli titre pour chaque photo.
Les images que j’utilise et le fichier .csv peuvent être téléchargés à l’aide des commandes ci-dessous (déplier le code en cliquant sur le bouton “code”) ou en cliquant ici: photo_titles.csv.

curl::curl_download((url = "https://marionlouveaux.fr/blog/2020-10-24_gpx_tracks_and_leaflet_map/photo_titles.csv", 
                     destfile = "photo_titles.csv")
photo_titles <- read_csv("photo_titles.csv")

Ici, je dois également corriger l’heure de création de mes photos avant de les ajouter à la carte, car je n’ai pas réglé l’horloge de mon appareil photo avant la randonnée.

photos_metadata <- tibble(photo_path = photo_path) %>% 
  mutate(info = map(photo_path, ~ file.info(.x)),
         photo_name = basename(photo_path))  %>% 
  unnest(info) %>% 
  select(photo_name, mtime) %>% 
  inner_join(photo_titles, by = "photo_name") %>% 
  mutate(corrected_mtime = mtime - duration(68, "minutes"),
         photo_path_leaflet = file.path(dir_path, photo_name))

Ensuite, je dois joindre chaque image au point le plus proche disponible dans les données de la trace de la randonnée. Pour ce faire, je recherche la plus petite différence absolue entre l’horodatage de création corrigé de l’image et l’horodatage des points de la trace.

#' Match a given timestamp with the closest timestamp in a vector of timestamps 
#'
#' @param track1 .gpx track imported in R (track point data)
#' @param photo_time picture creation time
#'
#' @return
#' @export
#'
#' @examples
closest <- function(track1, photo_time) {
  difftime(track1$time, photo_time) %>% 
  abs() %>% 
  which.min() %>% 
  track1[., ]
}

photos_metadata_sf <- photos_metadata %>% 
  mutate(closest_point = map(corrected_mtime, ~closest(track1, photo_time = .x) )) %>% 
  unnest(cols = closest_point) %>% 
  st_as_sf()

Je peux maintenant ajouter les photos à la carte {leaflet}. J’utilise la fonction addMarkers() pour ajouter une icône d’appareil photo et la fonction addPopupImages() du paquet {leafpop} pour afficher l’image sous forme de pop-up. L’icône provient de Wikimedia et peut être téléchargé à l’aide de la commande ci-dessous (déplier le morceau de code en cliquant sur le bouton “code”) ou en cliquant ici : 240px-Icone_appareil_photo.png

curl::curl_download(url = "https://marionlouveaux.fr/blog/2020-10-24_gpx_tracks_and_leaflet_map/240px-Icone_appareil_photo.png",
                    destfile = "240px-Icone_appareil_photo.png")
cameraIcon <- iconList(makeIcon("240px-Icone_appareil_photo.png", iconWidth = 30))
leaflet() %>%
  addProviderTiles("OpenStreetMap.France") %>%
  addPolylines(data = track2) %>% 
  addMarkers(data = photos_metadata_sf, label = ~title, group = "photos", icon = ~cameraIcon) %>%
  addPopupImages(photos_metadata_sf$photo_path_leaflet, group = "photos", width = 500) 

Conclusion

Dans cet article, j’ai expliqué comment visualiser une trace de randonnée et des photographies prises lors de cette randonnée sur une carte interactive. J’ai créé la carte interactive avec {leaflet}, j’ai importé le tracé de la randonnée à partir du fichier .gpx sur le fond de carte {leaflet} et j’ai ensuite ajouté les photos sous forme de fenêtres pop-up sur la carte, aux coordonnées géographiques où les photos ont été prises.

Remerciements

J’ai pu me mettre aux cartes interactives {leaflet} grâce à cet article de blog (en français) de ThinkR.



Citation :

Merci de citer ce travail avec :
Louveaux M. (2020, Oct. 24). "Visualiser des traces de randonnée GPX et des photos avec leaflet". Retrieved from https://marionlouveaux.fr/fr/blog/gpx-tracks-and-leaflet-interactive-map/.

Citation BibTex :
@misc{Louve2020Visua,
    author = {Louveaux M},
    title = {Visualiser des traces de randonnée GPX et des photos avec leaflet},
    url = {https://marionlouveaux.fr/fr/blog/gpx-tracks-and-leaflet-interactive-map/},
    year = {2020}
  }
comments powered by Disqus