Le package osrm
assure le lien entre R et l’API d’OSRM. OSRM est un service de routage basé sur les données OpenStreetMap.
Ce package permet d’obtenir le temps de trajet, la distance et le plus court chemin entre deux points via le réseau routier d’OpenStreetMap. Il est également possible d’obtenir des matrices de distances entre deux séries de points.
Voici un rapide aperçu des fonctions du package osrm
:
osrmTable
: Matrices de distances entre points.osrmTableOD
: Matrices de distances entre points où les origines et les destinations peuvent être différentes.osrmViaRoute
: Temps de trajet et distance routière entre deux points.osrmViarouteGeom
: Géométrie du plus court chemin entre deux points.
Par défaut le package utilise l’API publique d’OSRM (condition d’utilisation de l’API). Il est possible d’utiliser une autre instance du service si l’on veut en faire un usage intensif.
Voici un petit exemple de ce que l’on peut faire avec le package. Les cartes sont faites avec le le package cartography
que j’ai déjà présenté ici.
L’idée dans cet exemple est de comparer l’accessibilité globale des communes de Loire-Atlantique à vol d’oiseau et par la route. Pour cela nous utiliserons l’indice d’accessibilité de Shimbel1 qui rapporte la somme des écarts de tous les sommets à la somme des écarts d’un sommet :
où SHi est l’indice de Shimbel pour la commune i et d(i,j) une mesure de distance entre i et j.
Chargement des données et des librairies
# Chargement des données
load("data/LoireAtlantique.RData")
# chargement des librairies
library(osrm)
library(rgeos)
library(cartography)
# création d'un data frame des communes avec leurs coordonées en WGS84
COM44.df <- data.frame(as.character(COM44.spdf$INSEE_COM),
coordinates(spTransform(COM44.spdf,
CRSobj =
"+init=epsg:4326")))
# renommer les colonnes
colnames(COM44.df) <- c("id", "x", "y")
Création de la matrice des distances euclidiennes
mateuclid <- rgeos::gDistance(COM44.spdf, byid = T)
Les 5 premières lignes et colonnes de mateuclid
:
44148 | 44139 | 44221 | 44094 | 44125 | |
---|---|---|---|---|---|
44148 | 0.00 | 40163.20 | 29042.71 | 43736.88 | 78722.46 |
44139 | 40163.20 | 0.00 | 16747.42 | 37174.32 | 38623.89 |
44221 | 29042.71 | 16747.42 | 0.00 | 20492.02 | 60500.21 |
44094 | 43736.88 | 37174.32 | 20492.02 | 0.00 | 77979.86 |
44125 | 78722.46 | 38623.89 | 60500.21 | 77979.86 | 0.00 |
Nous venons de créer la matrice des distances euclidiennes (en mètres) entre les communes.
Création de la matrice des temps de trajets
Pour créer celle des distances routières nous pourrions utiliser la fonction osrmTable
mais l’API public d’OSRM n’accepte pas les requêtes dépassant les 100 points. Nous allons donc utiliser la fonction osrmTableOD
qui permet de combiner plusieurs requêtes.
# création d'une matrice distances routières
matroute <- osrmTableOD(dfo = COM44.df,
ido = "id", xo = "x", yo = "y",
dfd = COM44.df,
idd = "id", xd = "x", yd = "y")
Les 5 premières lignes et colonnes de matroute
:
44148 | 44139 | 44221 | 44094 | 44125 | |
---|---|---|---|---|---|
44148 | 0.00 | 61.60 | 41.60 | 70.20 | 100.20 |
44139 | 61.80 | 0.00 | 30.10 | 51.40 | 53.70 |
44221 | 40.70 | 30.10 | 0.00 | 40.10 | 68.70 |
44094 | 70.20 | 49.80 | 38.40 | 0.00 | 79.30 |
44125 | 101.90 | 56.20 | 70.20 | 80.90 | 0.00 |
Les temps de trajet sont en minutes.
Calcul et cartographie des indices d’accessibilité de Shimbel
Nous calculons ensuite les indices de Shimbel à partir de ces deux matrices.
# Calcul d'indice d'accessibilité local d'ensemble
shimbel <- data.frame(id = COM44.df$id,
ShimbelRoute = sum(matroute) / colSums(matroute),
ShimbelEuclid = sum(mateuclid) / colSums(mateuclid))
Et nous pouvons ensuite cartographier ces indices, en commençant par l’accessibilité euclidienne.
# plot vide pour cadrer la carte
plot(COM44.spdf, col = NA, border = NA, bg = "#A6CAE0")
# plot du fond france
plot(FRA.spdf, add=T, col = "#E3DEBF", border = "#03779E")
# Index de Shimbel avec les distances euvclidiennes
choroLayer(spdf = COM44.spdf, spdfid = "INSEE_COM",
df = shimbel,
var = 'ShimbelEuclid', nclass = 6,
legend.pos = "left",
legend.title.txt = "Indice de\nShimbel",
add=T)
# Ajout d'un habillage
layoutLayer(title = "Accessibilité euclidienne globale des communes de Loire-Atlantique",
sources = "T. Giraud, 2015",
author = "Fond de carte : GEOFLA 2015, IGN")
Plus une commune aura une position centrale dans le département plus son accessibilité sera forte.
# plot vide pour cadrer la carte
plot(COM44.spdf, col = NA, border = NA, bg = "#A6CAE0")
# plot du fond france
plot(FRA.spdf, add=T, col = "#E3DEBF", border = "#03779E")
# Index de Shimbel avec les distances euvclidiennes
choroLayer(spdf = COM44.spdf, spdfid = "INSEE_COM",
df = shimbel,
var = 'ShimbelRoute', nclass = 6,
legend.pos = "left",
legend.title.txt = "Indice de\nShimbel",
add=T)
# Ajout d'un habillage
layoutLayer(title = "Accessibilité routière globale des communes de Loire-Atlantique",
sources = "T. Giraud, 2015",
author = "Fond de carte : GEOFLA 2015, IGN ; Data (c) OpenStreetMap contributors ; Routes: OSRM. http://project-osrm.org/")
L’accessibilité des communes via le réseau routier est plus nuancée que la simple accessibilité euclidienne (en cercles concentriques).
Calcul de l’efficacité routière
Pour mesurer l’efficacité du réseau routier nous pouvons faire le rapport entre les deux indices. Nous utilisons le fond OSM-transport comme fond de carte pour confronter cette efficacité avec le réseau routier qui sous-tend les mesures d’accessibilité routière.
# calcul du rapport entre les deux indices
shimbel$eff <- shimbel$ShimbelRoute/shimbel$ShimbelEuclid
# obtension d'une tuile osm-transport sur le departement
# avec la fonction getTiles de cartography
tiles44 <- getTiles(spdf = COM44.spdf, type = "osm-transport")
## affichage de la carte
# plot vide pour cadrer la carte
plot(COM44.spdf, col = NA, border = NA)
# plot du fond de carte osm-transport
tilesLayer(tiles44, add=T)
# Index de Shimbel avec les distances euvclidiennes
choroLayer(spdf = COM44.spdf, spdfid = "INSEE_COM",
df = shimbel,
var = 'eff',
breaks = c(min(shimbel$eff),
0.8,0.9,0.95, 1/0.95, 1/0.9,
max(shimbel$eff)),
col = carto.pal(pal1 = "green.pal",3,
"wine.pal",2,
transparency = T,
middle = T),
lwd = 0.2,
legend.pos = "left",
legend.title.txt = "Efficacité",
legend.frame = TRUE,
legend.values.rnd = 2,
add=T)
# Ajout d'un habillage
layoutLayer(title = "Efficacité du réseau routier des communes de Loire-Atlantique",
sources = "T. Giraud, 2015",
author = "Fond de carte : OpenStreetMap contributors ; Routes: OSRM. http://project-osrm.org/")
Les communes les plus périphériques sont favorisées par le réseau routier, elle sont desservies par des voies rapides qui améliorent leur accessibilité. Certaines communes plus centrales sont au contraire moins accessibles que ce que l’on pourrait imaginer. Cela est sûrement dû, pour certaines, à leur position au bord de la Loire qui implique des détours pour emprunter les quelques ponts qui enjambent le fleuve.
Quelques trajets routiers
Pour illustrer le contournement de la Loire nous pouvons afficher quelques trajets à partir de la commune la moins accessible avec la fonction osrmViarouteGeom
.
L’ensemble du code et des données utilisées ici est disponible sur GitHub, tout comme la version de développement du package.
1. Pumain Denise, Saint-Julien Thérèse (1997), L’analyse spatiale. Localisations dans l’espace. Paris, Armand Colin.(p110) ↩
OpenEdition vous propose de citer ce billet de la manière suivante :
Timothée Giraud (12 octobre 2015). Temps de trajet et matrices de distances avec R et OpenStreetMap. R Géomatique. Consulté le 11 octobre 2024 à l’adresse https://doi.org/10.58079/tp3l
Bonjour,
La fonction osrmTableOD n’existe plus dans le package osrm, a-t-elle était modifié sous un autre nom?
Elle était avantageuse si l’on avait plusieurs requêtes.
Bien à vous
Bonjour,
Cette fonction a disparu en janvier 2016. La fonction
osrmTable
l’a remplacée et donne les mêmes résultats. Vous pouvez voir des examples dans l’aide du package (?osrmTable
) et sur sa page GitHub (https://github.com/rCarto/osrm).Cordialement,
T.
Bonjour,
je voudrais savoir s’il est possible pour une ville donnée d’obtenir les villes qui se trouvent à moins d’un temps de trajet fixé (par ex 30 mins) de cette ville et les temps de trajets associés.
Cordialement,
sylvain
Bonjour,
Vous pouvez sans doute arriver à quelque chose en utilisant osrmIsochrone (pour obtenir les zones à moins de x min) puis osrmRoute pour obtenir les données. Sinon, si vous avez déjà la liste des villes, vous pouvez utiliser osrmTable.
Bonjour,
je souhaite récupérer les matrices de distance sous forme d’un dataframe pour pouvoir les exporter (en csv ou txt). J’ai essayé avec la fonction as.dataframe() mais les résultats ne sont guère concluants. Sauriez vous comment faire ?
Bonjour,
Ce n’est pas la peine de transformer la matrice en data.frame pour l’exporter :
library(osrm)
data(“berlin”)
distA <- osrmTable(loc = apotheke.df[1:50, c("id","lon","lat")])
write.csv(distA$durations, file = 'mat.csv')
Le fichier mat.csv contient bien la matrice des distances.
Bonjour,
Merci pour votre tuto qui est d’une grande aide. Petit problème avec la fonction osrmTableOD qui me renvoi “impossible de trouver la fonction “osrmTableOD””. Je ne trouve rien sur cette fonction sur internet… Pouvez-vous m’aidez?
Merci,
Coralie
Bonjour,
Depuis la publication de ce billet le package osrm a évolué. Vous trouverer les dernières infos sur la page github suivante https://github.com/rCarto/osrm/
En l’occurrence il faut maintenant utiliser la fonction osrmTable.
Bien à vous,
T.
Merci Timothée pour votre réponse et pour le lien !
D’accord je ne suis qu’un simple économètre.
Ou puis-je trouver ces données ?
Vous trouverez des fonds de carte des communes française sur le site de l’IGN : http://professionnels.ign.fr/geofla
Bonjour comment fait-on pour obtenir le Rdata ?
Je dois faire une matrice de distance pour le loiret.
merci
Bonjour,
Les fichiers .RData sont des fichiers contenant des objets R.
Dans cet exemple le fichier LoireAtlantique.RData contient deux objets : COM44.spdf qui est un SpatialPolygonsDataFrame des communes de Loire-Atlantique et FRA.spdf qui est un SpatialPolygonsDataFrame du contour de la France. Ces deux fichiers sont utiles pour créer les cartes et pour obtenir les coordonnées des centroides des communes.
Ce sont ces coordonnées, stockées dans une data.frame, qui sont utilisées pour effectuer les calculs de distance avec les fonctions du package osrm.
Pour calculer une matrice de distance vous n’aurez besoin que d’un data.frame contenant au moins trois colonnes (identifiant des communes, longitude et latitude en WGS84). Il vous faut donc créer un fichier contenant ces identifiants et coordonnées et l’importer dans R, vous n’avez pas forcément besoin de stocker ces données en RData.
Bien à vous,
Timothée