Datavisualisation des données sur une carte avec le package leaflet

Cette dernière partie du sujet consiste à visualiser les émissions de CO2 précédemment calculées sur une carte interactive avec le package leaflet et des fonds de carte de Stadia Maps afin d’identifier visuellement les liaisons aériennes les plus émissives.

Exercice 5 : Visualiser des données géographiques
  1. De la même manière que pour TravelTime, il est nécessaire de se créer un compte sur Stadia Maps afin d’avoir accès à leur API.

  2. Une fois que votre compte est créé et vérifié votre compte, créez une property et nommez la “funathon”.

  3. Cliquer sur Add API Key, puis la copier dans le fichier secrets.yaml créé dans lors de l’exercice 1.

    secrets.yaml
    stadiaMaps:
      API_KEY: "votre_clé_api_ici"
  4. L’API de Stadia Maps permet de récupérer des fonds de carte avec des styles différents en fonction des besoins et préféreces. En s’aidant de la documentation de l’API, reconstituer l’URL qui récupère une tuile Stadia Maps pour un style donné.

Note

A la différence de l’API de routage de TravelTime, l’API de Stadia Maps pour obtenir un fond de carte est plus simple d’utilisation puisque la requête HTTP se fait simplement via un lien HTML (sans JSON). En effet, nous utilisons la méthode GET et l’authentification se fait directement via l’URL (ce qui n’est pas optimal en terme de sécurité).

Afficher l’aide
Astuce

Pour récupérer le format de l’URL vous pouvez regarder ces pages de la documentation :

Cliquer pour voir la réponse
secrets <- yaml::read_yaml("secrets.yaml")
STADIA_MAPS_API_KEY <- secrets$stadiaMaps$API_KEY

STYLE <- "outdoors"

TILES_URL <- sprintf("https://tiles.stadiamaps.com/tiles/%s/{z}/{x}/{y}{r}.png?api_key=%s", STYLE, STADIA_MAPS_API_KEY)
  1. Créer un dataframe avec tous les éléments pour cartographier les émissions sur les lignes repérées (les noms, les latitudes et les longitudes des villes de départ et d’arrivée, et les émissions de CO2 des lignes associées)
Cliquer pour voir la réponse
GCO2_PER_PKT <- 80

emission_by_route_list <- list()

for (pair in city_pairs) {
  coordinates <- lapply(names(pair), get_station_coordinates, data = stations_data, verbose = FALSE)
  emissions <- get_air_traffic_between_cities(pair[1], pair[2], air_traffic_df) * GCO2_PER_PKT / 1000000

  # Ajouter les données à la liste
  emission_by_route_list[[length(emission_by_route_list) + 1]] <- list(
    city1 = pair[1],
    city2 = pair[2],
    lat1 = coordinates[[1]][1],
    lng1 = coordinates[[1]][2],
    lat2 = coordinates[[2]][1],
    lng2 = coordinates[[2]][2],
    emissions = emissions
  )
}

emission_by_route_df <- dplyr::bind_rows(emission_by_route_list)
Afficher les données
city1 city2 lat1 lng1 lat2 lng2 emissions
Lyon Paris 45.74842 4.8256735 48.88164 2.3561600 17710.595
Marseille Paris 43.30288 5.3808816 48.88164 2.3561600 79601.238
Lille Paris 50.63681 3.0717930 48.88164 2.3561600 0.000
Bordeaux Paris 44.82592 -0.5559775 48.88164 2.3561600 49831.726
Nantes Paris 47.21657 -1.5440749 48.88164 2.3561600 13398.339
Strasbourg Paris 48.58449 7.7356260 48.88164 2.3561600 0.000
Montpellier Paris 43.60609 3.8827575 48.88164 2.3561600 47297.213
Marseille Lyon 43.30288 5.3808816 45.74842 4.8256735 0.000
Lille Lyon 50.63681 3.0717930 45.74842 4.8256735 0.000
Strasbourg Lyon 48.58449 7.7356260 45.74842 4.8256735 0.000
Montpellier Lyon 43.60609 3.8827575 45.74842 4.8256735 0.000
Toulouse Marseille 43.61070 1.4543961 43.30288 5.3808816 0.000
Nice Marseille 43.70479 7.2617424 43.30288 5.3808816 0.000
Montpellier Marseille 43.60609 3.8827575 43.30288 5.3808816 0.000
Bordeaux Toulouse 44.82592 -0.5559775 43.61070 1.4543961 0.000
Montpellier Toulouse 43.60609 3.8827575 43.61070 1.4543961 0.000
Bordeaux Lille 44.82592 -0.5559775 50.63681 3.0717930 5412.944
Nantes Lille 47.21657 -1.5440749 50.63681 3.0717930 0.000
Strasbourg Lille 48.58449 7.7356260 50.63681 3.0717930 0.000
Nantes Bordeaux 47.21657 -1.5440749 44.82592 -0.5559775 0.000
Montpellier Nantes 43.60609 3.8827575 47.21657 -1.5440749 0.000
  1. Créer une carte de base avec le fond de carte Stadia Maps avec la fonction addTiles de leaflet
Cliquer pour voir la réponse
map <- leaflet::leaflet() |>
  leaflet::addTiles(urlTemplate = TILES_URL)
  1. Faire une boucle pour ajouter toutes les lignes repérées à la carte avec la fonction addPolylines de leaflet :
  • Si les émissions sont non-nulles, on les affiche en rouge avec une épaisseur de trait proportionnelle aux émissions
  • Si les émissions sont nulles, on les affiche en noir en trait fin
Cliquer pour voir la réponse
# Parcourir chaque ligne du dataframe
for (i in 1:nrow(emission_by_route_df)) {
  # Définir les options par défaut pour les lignes
  lat_vector <- c(emission_by_route_df$lat1[i], emission_by_route_df$lat2[i])
  lng_vector <- c(emission_by_route_df$lng1[i], emission_by_route_df$lng2[i])
  color <- "black" # couleur par défaut
  opacity <- 0.5
  weight <- 1 # poids par défaut

  # Si les émissions sont supérieures à zéro, ajuster la couleur et le poids
  if (emission_by_route_df$emissions[i] > 0) {
    color <- "red"
    weight <- emission_by_route_df$emissions[i] / 10000
  }

  # Ajouter des lignes à la carte
  map <- map |>
    leaflet::addPolylines(lat = lat_vector, lng = lng_vector, color = color, opacity = opacity, weight = weight)
}
  1. Faire une boucle pour ajouter toutes les villes à la carte avec la fonction addCircleMarkers de leaflet.
Cliquer pour voir la réponse
# Définir les options de label personnalisées
custom_label_options <- leaflet::labelOptions(noHide = TRUE, style = list("background" = "rgba(255, 255, 255, 0.5)"))

# Fonction pour ajouter des marqueurs circulaires
add_circle_marker <- function(map, lat, lng, city, label_options) {
  map |>
    leaflet::addCircleMarkers(
      lat = lat,
      lng = lng,
      radius = 5,
      color = "#4444AA",
      label = as.character(city),
      labelOptions = label_options
    )
}

# Boucle pour ajouter des marqueurs pour chaque ligne du dataframe
for (i in 1:nrow(emission_by_route_df)) {
  map <- add_circle_marker(map, emission_by_route_df$lat1[i], emission_by_route_df$lng1[i], emission_by_route_df$city1[i], custom_label_options)
  map <- add_circle_marker(map, emission_by_route_df$lat2[i], emission_by_route_df$lng2[i], emission_by_route_df$city2[i], custom_label_options)
}
  1. Afficher la carte
Cliquer pour voir la réponse
map