# liste des packages nécessaires
<- c("dplyr", "sf", "mapsf", "mapview", "osrm", "leaflet", "units","kableExtra")
liste_packages # liste des éventuels packages à installer (= ceux qui ne sont pas déjà installés)
<- liste_packages[!(liste_packages %in% installed.packages()[,"Package"])]
new_packages # s'il y en a, installation
if(length(new_packages)) install.packages(new_packages)
[SPA2] Des distances à l’accessibilité spatiale
GEO UNIV’R Tunisie 2024
Objectifs de la séance et mise en place du module
Ce deuxième module d’analyse spatiale est construit autour des notions de distance et d’accessibilité qui sont étroitement liées :
La distance est une mesure de l’écart spatial, de la séparation entre deux lieux. Derrière la simplicité apparente de sa définition, cette notion peut être appréhendée différemment selon les manières d’évaluer le “coût” de l’éloignement (en km, en temps, en énergie, …), le mode de déplacement emprunté (en voiture, à pieds, en train…) ou encore le type d’itinéraire privilégié (le plus court chemin ? celui qui permet d’éviter les plus fortes pentes ? etc.). Parce qu’elles peuvent devenir complexes à collecter quand les lieux sont trop nombreux, ces distances “réelles” sont souvent estimées à l’aide de mesures simplifiées qui reposent sur les coordonnées des lieux et sur le calcul de distances théoriques entre ces coordonnées.
L’accessibilité correspond à la “plus ou moins grande facilité avec laquelle des lieux peuvent être atteints” (Chapelon, 2004). Cette facilité repose sur plusieurs dimensions (performance des transports, capacités des individus, capacités d’accueil des services et équipements…). Mais elle dépend toujours au moins en partie de la distance physique entre la population inégalement répartie qui a besoin d’une ressource (un service de santé, un commerce, une école, un emploi…) et les lieux où ces ressources sont inégalement distribuées. C’est pourquoi de nombreux indicateurs d’accessibilité découlent directement de la manipulation et du résumé de matrices de distance.
Ce que vous allez apprendre à faire dans cette séance :
Analyser l’écart entre les distances estimées à l’aide de fonctions mathématiques (en particulier la distance euclidienne, i.e. distance à vol d’oiseau) et les distances sur réseau routier obtenues à partir du calculateur d’itinéraire OSRM : quand on n’a pas de données sur les distances routières, dans quelle mesure peut-on les estimer à partir des distances théoriques ?
Manipuler ces valeurs de distance (observées ou théoriques) pour construire des indicateurs d’accessibilité spatiale, comparer des scénarios d’implantation de nouveaux services/équipements, à partir de différents critères de localisation optimale.
Pré-requis méthodologiques
- Sur l’information géographique : définition des coordonnées spatiales d’objets géographiques
- En statistiques : résumé d’une distribution statistique univariée, construction d’un modèle de régression linéaire
Packages utilisés
sf
: importer, manipuler et exporter des données géographiques vectorielles. vu LUN1, MAR1…leaflet
: pour réaliser une carte interactive vu LUN3, MAR3…mapsf
: pour la cartographie thématique vu MAR3mapview
: pour une cartographie interactive élémentaire vu MAR3osrm
: pour récupérer les valeurs de distance routière sur réseau de l’interface OSRM, construire des isochrones vu LUN3units
: pour modifier des unités de mesure (temps, espace) vu MAR1kableExtra
: mise en forme soignée des tableaux vu MAR1
Installation (si le package n’est pas déjà installé sur votre machine) :
Chargement des packages nécessaires :
library(dplyr)
library(sf)
library(mapsf)
library(units)
library(leaflet)
library(mapview)
library(osrm)
library(kableExtra)
Les données utilisées dans ce module
Les villes tunisiennes et les découpages administratifs tunisiens (cf SPA1)
Les villes tunisiennes (source : Africapolis)
<- st_read(dsn = "data/SPA/vil.gpkg", quiet=TRUE) vil
Fond de carte des délégations, gouvernorats et régions (source : INS & Syfacte/Riate)
<- st_read("data/SPA/tun_admin.gpkg", layer = "delegation", quiet = TRUE)
del <- del[!duplicated(del$del_code),]
del <- st_read("data/SPA/tun_admin.gpkg", layer = "gouvernorat", quiet = TRUE)
gou <- st_read("data/SPA/tun_admin.gpkg", layer = "region", quiet = TRUE) reg
Les populations des délégations (source : INS), à joindre aux géométries déjà importées
<- read.csv(file = "data/SPA/don_del.csv", header = TRUE, sep= ";", encoding = "UTF-8")
popdel # NB : dans le fichier don_del.csv, correction du code (del_code) de Zarzouna : TN.BZ.JA au lieu de TN.BZ.ZA (dans le fichier del)
<- merge(x = del[,"del_code"], # L'objet sf (seulement le champ del_code)
del y = popdel, # le data.frame
by.x = "del_code", # identifiant dans x
by.y = "del_code", # identifiant dans y
all.x = TRUE # conserver toutes les lignes
)
<- del[,c("del_code","del_nom_fr","del_nom_ar","popto_2014")] del
Fond de carte et population 2004 des secteurs (source : INS)
<- st_read("data/SPA2/secteurs.gpkg", quiet=TRUE) secteurs
Les universités tunisiennes (source : OSM)
Le fichier contient les 10 universités extraites de la base OSM (à partir de la catégorie amenity=university), cette liste ayant été vérifiée à partir de Wikipedia (consulté le 3 mai 2024). La localisation d’une université dans chaque ville est associée au point correspondant à une des entrées du site principal (à consolider !).
<- st_read(dsn = "data/SPA2/univOSM.gpkg", quiet=TRUE) univ
1. Calcul de distances théoriques, comparaison avec les distances sur réseau routier
Pour commencer, de Tunis à Ben Guerdane…
Construire une matrice des distances routières via OSRM
Calcul d’une matrice des distances routières à l’aide de la fonction osrmTable
d’OSRM
# Pour avoir les noms des villes comme identifiants de la future matrice, au lieu d'avoir des indices des colonnes et des lignes
rownames(vil) <- vil$Nom
# Calcul d'une matrice de distances routières via OSRM
<- osrmTable(loc=vil,
matdist_osrm measure="distance")
# cette matrice n'est pas tout à fait symétrique, même si les différences sont infimes
Le résultat est une liste avec 3 informations : la matrice des distances routières, les coordonnées des sources et celles des destinations.
Transformation en table de liens, suppression lignes i=j, distance en km (+ arrondi à l’unité)
# suppression des distances sur la diagonale supérieure (en faisant l'hypothèse que Distij~Distji)
$distances[upper.tri(matdist_osrm$distances)] <- NA
matdist_osrm# transformation d'une matrice en tableau XY
<-as.data.frame.table(matdist_osrm$distances)
distrout # ajout des noms de colonnes
names(distrout) <- c("i","j","distrout")
# suppression des valeurs manquantes (l'ancienne partie supérieure de la matrice)
<- na.omit(distrout)
distrout # suppression lignes i=j (distance d'une ville à elle-même)
<- distrout[distrout$distrout!=0,]
distrout # distance en km (+ arrondi à l'unité)
$distrout <- round(distrout$distrout/1000,0)
distrout
# importation directe du tableau de données, au cas où la connexion à OSRM serait trop longue...
# distrout <- read.csv2("data/SPA2/distrout_vil.csv")
Construire une matrice de distance euclidienne (à vol d’oiseau) entre les villes
Construction d’une matrice des distances euclidiennes à l’aide de st_distance()
de sf
# calcul de la distance euclidienne entre les villes
<- st_distance(vil)
matdist_eucli
# n.b.: comme on souhaite avoir une matrice carrée (les lieux en ligne sont identiques aux lieux en colonne), on n'a pas besoin de préciser l'identité des lieux x et y. Sinon on écrirait 'st_distance(x=vil,y=vil)'
# le résultat est une matrice. Par exemple ici si on prend les 5 premières villes :
1:5,1:5] matdist_eucli[
Units: [m]
1 2 3 4 5
1 0.0 358753.3 262753.18 368740.1 207960.29
2 358753.3 0.0 159515.73 162539.4 169045.97
3 262753.2 159515.7 0.00 106449.8 63489.65
4 368740.1 162539.4 106449.83 0.0 167450.28
5 207960.3 169046.0 63489.65 167450.3 0.00
Notez que les distances sont exprimées dans l’unité du système de coordonnées de référence, en l’occurrence ici en mètres.
Comme vu dans LUN3 : amélioration de l’affichage de la matrice
# transformation des distances en km
<- set_units(matdist_eucli, "km")
matdist_eucli # et arrondi à l'unité kilométrique
<- round(matdist_eucli, 0)
matdist_eucli # ajout des noms de villes en identifiants
colnames(matdist_eucli) <- vil$Nom
row.names(matdist_eucli) <- vil$Nom
# retrait de l'unité de mesure
<- drop_units(matdist_eucli)
matdist_eucli
1:5,1:5] matdist_eucli[
Ras Jebel Redeief Regueb Hamma Hajeb Elayoun
Ras Jebel 0 359 263 369 208
Redeief 359 0 160 163 169
Regueb 263 160 0 106 63
Hamma 369 163 106 0 167
Hajeb Elayoun 208 169 63 167 0
Transformation en table de liens, suppression lignes i=j, distance en km
# suppression des distances sur la diagonale supérieure
upper.tri(matdist_eucli)] <- NA
matdist_eucli[# transformation d'une matrice en tableau XY
<-as.data.frame.table(matdist_eucli)
disteucli # retrait des valeurs manquantes (celles de la diagonale supérieure)
<- na.omit(disteucli)
disteucli # ajout des noms de colonnes
colnames(disteucli) <- c("i","j","disteucl")
# suppression des distances nulles (i.e. la distance entre une ville et elle-même)
<- disteucli[disteucli$disteucl!=0 ,] disteucli
Calcul des distances rectilinéaires entre les villes
On souhaite récupérer les distances routières, euclidiennes et rectilinéaires dans un même tableau.
Jointure de la table des distances euclidiennes avec la table des distances routières
# Jointure entre le fichier des distances eucliennes et le fichier des distances routières
<- merge(distrout, disteucli,
distvil by= c("i","j"))
# Avant de joindre cette table des distances à celle des villes, on récupère les coordonnées des villes (utile pour le futur calcul des distances rectilinéaires)
$X <- st_coordinates(vil)[,1] # pour extraire X
vil$Y <- st_coordinates(vil)[,2] # pour extraire Y
vil
# Jointure avec la base des villes pour récupérer le nom des villes de destination j et la date à laquelle elles apparaissent dans la base Africapolis
<- merge(x = distvil,
distvil y = st_drop_geometry(vil[, c("Nom","Apparition1","X","Y")]),
by.x= "j", by.y= "Nom")
names(distvil)[5:7] <- c("Apparitionj","Xj","Yj")
# Nouvelle jointure pour récupérer le nom des villes d'origine i et la date à laquelle elles apparaissent dans la base Africapolis
<- merge(x = distvil,
distvil y = st_drop_geometry(vil[, c("Nom", "Apparition1","X","Y")]),
by.x= "i", by.y= "Nom")
names(distvil)[8:10] <- c("Apparitioni","Xi","Yi")
Ajout à la table des distances des distances rectilinéaires
# Calcul des distances rectilinéaires
$distrect <- round((abs(distvil$Xi-distvil$Xj)
distvil+abs(distvil$Yi-distvil$Yj))/1000,0)
# Pour réarranger l'ordre des colonnes
<- c("i","j","Xi","Yi","Xj","Yj","distrout","disteucl","distrect","Apparitioni","Apparitionj")
ordre <- data.frame(distvil[,ordre]) distvil
A vous de jouer ! Comparez les distances théoriques aux distances réelles
Comparaison des distances euclidiennes et routières
Calcul des écarts relatifs entre distances routières et euclidiennes
$diffrel <- round(((distvil$distrout-distvil$disteucl)/
distvil$disteucl)*100,1)
distvilsummary(distvil$diffrel)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.00 21.80 28.40 31.04 36.20 214.90
Que vous apprend ce résumé de l’écart relatif entre distances routières et distances euclidiennes ? Quel est l’écart moyen ? A quel itinéraire correspond le plus grand écart ?
Un modèle pour estimer les distances routières en fonction des distances à vol d’oiseau ?
Complétez les lignes de ce programme pour construire un modèle de régression linéaire qui estime la distance routière en fonction de la distance euclidienne de la forme Y = a.X + b : distrout = a.disteucl + b
# On crée d'abord un graphique qui représente la distance routière en fonction de la distance euclidenne
plot(... ~ ..., data = ..., pch = 16, cex=0.3,
# Ajout d'un titre principal et des libellés des axes
main="Comparaison des distances entre les villes tunisiennes",
xlab = "Distance à vol d'oiseau (en km)",
ylab = "Distance routière (en km)")
# on construit ensuite un modèle de régression linéaire (linear modeling - lm) de la forme :
<- ...(... ~ ..., data=...)
modeleucl # comment faire pour avoir un résumé des résultats de la régression ?
...(modeleucl)
# Ajout de la droite de régression entre les 2 distances
abline(a=modeleucl$coefficients[1], b=modeleucl$coefficients[2], col="blue", lwd=2)
# La 1ère bissectrice, i.e. l'égalité des distances
abline(a=0, b=1, col="red", lwd=2)
Que pensez-vous des résultats du modèle qui estime les distances routières en fonction des distances euclidiennes ?
Que montrent les écarts relatifs entre distances routières et euclidiennes ?
$diffrel <- round(((distvil$distrout-distvil$disteucl)/
distvil$disteucl)*100,1)
distvilsummary(distvil$diffrel)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.00 21.80 28.40 31.04 36.20 214.90
Que vous apprend ce résumé de l’écart relatif entre distances routières et distances euclidiennes ? Quel est l’écart moyen ? A quel itinéraire correspond le plus grand écart ?
La distance euclidienne est toujours inférieure à la distance routière.
En moyenne, la distance euclidienne sous-estime la distance routière de 31%.
3/4 des distances mesurées montrent un écart compris entre 22% et 36% (distances euclidiennes inférieures de 22% à 36% aux distances routières).
Le plus grand écart s’observe entre Djerba et les îles Kerkhena (101km en dist euclidienne, 318km par la route).
Ajustement linéaire entre distances euclidienne et routière
plot(distrout ~ disteucl, data = distvil, pch = 16, cex=0.3,
# ajout d'un titre principal et des libellés des axes
main="Comparaison des distances entre les villes tunisiennes",
xlab = "Distance à vol d'oiseau (en km)",
ylab = "Distance routière (en km)")
<- lm(distrout ~ disteucl, data=distvil)
modeleucl summary(modeleucl)
Call:
lm(formula = distrout ~ disteucl, data = distvil)
Residuals:
Min 1Q Median 3Q Max
-79.830 -14.561 -3.735 7.872 186.805
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -1.373570 0.966785 -1.421 0.155
disteucl 1.319910 0.004466 295.565 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 28.13 on 3914 degrees of freedom
Multiple R-squared: 0.9571, Adjusted R-squared: 0.9571
F-statistic: 8.736e+04 on 1 and 3914 DF, p-value: < 2.2e-16
# Ajout de la droite de régression entre les 2 distances
abline(a=modeleucl$coefficients[1], b=modeleucl$coefficients[2], col="blue", lwd=2)
# La 1ère bissectrice, i.e. l'égalité des distances
abline(a=0, b=1, col="red", lwd=2)
Que pensez-vous des résultats du modèle qui estime les distances routières en fonction des distances euclidiennes ?
Dist_routière = 1,32 * Dist_eucl - 1,42
Chaque fois que la distance euclidienne augmente de 10 km, la distance routière augmente de 13,2 km
Coefficient de détermination : R²= 96%
p-value : < 2.2e-16
Comparaison des distances rectilinéaires/routières
Calcul des écarts relatifs entre distances rectilinéaires et euclidiennes
$diffrel2 <- round(((distvil$...-distvil$...)/
distvil$...)*100,1)
distvilsummary(distvil$diffrel2)
# valeur absolue des écarts
$absdiffrel2 <- abs(round(((distvil$...-distvil$...)/
distvil$...)*100,1))
distvilsummary(distvil$absdiffrel2)
Que vous apprend ce résumé de l’écart relatif entre distances routières et distances rectilinéaires ? Quel est l’écart moyen ? A quel itinéraire correspond le plus grand écart ?
Un modèle pour estimer les distances routières en fonction des distances rectilinéaires ?
Complétez les lignes de ce programme pour construire un modèle de régression linéaire qui estime la distance routière en fonction de la distance rectilinéaire de la forme Y = a.X + b : distrout = a.distrect + b
plot(... ~ ..., data = ..., pch = 16, cex=0.3,
# ajout d'un titre principal et des libellés des axes
main="Comparaison des distances entre les villes tunisiennes",
xlab = "Distance à vol d'oiseau (en km)",
ylab = "Distance routière (en km)")
<- ...(... ~ ..., data=...)
modeldrect ...(modeldrect)
# Ajout de la droite de régression entre les 2 distances
abline(a=modeldrect$coefficients[1], b=modeldrect$coefficients[2], col="blue", lwd=2)
# La 1ère bissectrice, i.e. l'égalité des distances
abline(a=0, b=1, col="red", lwd=2)
Que pensez-vous des résultats du modèle qui estime les distances routières en fonction des distances rectilinéaires ?
Calcul des écarts relatifs entre distances rectilinéaires et euclidiennes
# Les écarts relatifs
$diffrel2 <- round(((distvil$distrout-distvil$distrect)/
distvil$distrect)*100,1)
distvilsummary(distvil$diffrel2)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-27.300 -7.400 1.200 4.476 13.900 158.500
# La valeur absolue des écarts relatifs
$absdiffrel2 <- abs(round(((distvil$distrout-distvil$distrect)/
distvil$distrect)*100,1))
distvilsummary(distvil$absdiffrel2)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.00 4.70 9.80 12.77 17.20 158.50
Que vous apprend ce résumé de l’écart relatif entre distances routières et distances euclidiennes ? Quel écart moyen ? A quel itinéraire correspond le plus grand écart ?
La distance rectilinéaire est parfois inférieure à la distance routière (par exemple entre Sidi Bouzid et Ksar, distrou : 98 km et distrect : 131 km), parfois supérieure (par exemple entre Kerkenah et Djerba, distrou : 318 km et distrect : 123 km).
En moyenne, l’écart relatif absolu entre la distance rectilinéaire et la distance routière est de 13%.
Pour 3/4 des itinéraires, on a un écart compris entre 5% et 17%.
Ajustement linéaire entre distances rectilinéaire et routière
plot(distrout ~ distrect, data = distvil, pch = 16, cex=0.3,
# ajout d'un titre principal et des libellés des axes
main="Comparaison des distances entre les villes tunisiennes",
xlab = "Distance rectilinéaire (en km)",
ylab = "Distance routière (en km)")
<- lm(distrout ~ distrect, data=distvil)
modeldrect summary(modeldrect)
Call:
lm(formula = distrout ~ distrect, data = distvil)
Residuals:
Min 1Q Median 3Q Max
-132.099 -23.549 -6.679 15.680 193.195
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 6.476253 1.431770 4.523 6.27e-06 ***
distrect 1.013279 0.005235 193.541 < 2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 41.79 on 3914 degrees of freedom
Multiple R-squared: 0.9054, Adjusted R-squared: 0.9054
F-statistic: 3.746e+04 on 1 and 3914 DF, p-value: < 2.2e-16
# Ajout de la droite de régression entre les 2 distances
abline(a=modeldrect$coefficients[1], b=modeldrect$coefficients[2], col="blue", lwd=2)
# La 1ère bissectrice, i.e. l'égalité des distances
abline(a=0, b=1, col="red", lwd=2)
Que pensez-vous des résultats du modèle qui estime les distances routières en fonction des distances rectilinéaires ?
Dist_routière = 1,01 * Dist_recti + 6,4
Coefficient de détermination : R²= 91%
p-value : < 2.2e-16
Pour aller plus loin…
Cours et les applications du module Distances et accessibilité de l’école d’été du CIST au Bénin (2023) : entre autres développements, voir les indices d’efficacité du réseau routier créés à partir de la comparaison entre distance euclidienne et distance routière et de la comparaison entre distance et temps de trajet
“Tissus” de villes, réseaux potentiels d’échanges
Dans l’article Tissu d’un semis de villes européennes, C. Rozenblat (1995) proposait une carte originale pour faire ressortir les réseaux potentiels d’échanges entre villes européennes, à différentes échelles. La 1ère carte à droite s’appuie sur deux hypothèses :
- “Les interactions spatiales [étant] plus importantes entre des villes proches” (p.23), on peut rendre visible les continuités et discontinuités de la trame urbaine en reliant les villes proches : “La distribution des villes dans l’espace, leur espacement et leur agencement peuvent ainsi être à la base d’une réflexion sur leurs pouvoirs collectifs de structuration de l’espace économique, politique et social” (p.23).
- Les seuils de proximité varient selon la taille des villes : pour les plus grandes villes, leur rayonnement plus important justifie le choix de seuils de plus grande portée (par exemple, 150 km pour les villes de plus de 100 000 hab., contre 50 km pour l’ensemble des villes de plus de 10 000 hab.).
Plus récemment, dans le cadre du WorldPopProject, H. Chamberlain (2021) a cartographié les villes africaines de la base Global Human Settlement en reliant chaque centre aux 20 villes les plus proches, et en faisant varier la teinte de chaque lien en fonction de l’espacement observé. Le résultat fait ressortir la position relative de chaque ville, selon qu’elle s’inscrit dans une trame urbaine très dense (tons clairs) ou qu’elle est beaucoup plus isolée.
Vous pouvez construire une carte du “tissu” de villes tunisiennes, par exemple en reliant les villes de plus de 10 000 hab. qui sont distantes de moins de 50 km. Où sont les plus fortes continuités de densités urbaines ? les réseaux potentiels de moindre densité ? les zones où la présence des villes est plus rare ?
Pour aller plus loin, vous pouvez sélectionner plusieurs seuils de distance en fonction de la taille des villes (par exemple 100 km pour les villes de plus de 100 000 habitants), et/ou en choisissant plusieurs dates, en sélectionnant les villes de plusieurs pays voisins à partir de la base Africapolis…
- Comment sélectionner les villes distantes de moins de 50 km ?
Vous pouvez vous aider de la syntaxe df2 <- df[df$variable <50,]
- Comment dessiner les liens entre villes à partir de cette sélection ?
La fonction correspondante dans mapsf
est get_link_layer
.
Ses arguments reposent sur la sélection de deux fichiers : celui des points, celui de la table des liens, les identifiants des deux fichiers devant être identiques (par exemple ici les noms des villes) : liens <- mf_get_links(x = …, df = …)
On peut ensuite construire une carte thématique à partir de ces liens : mf_map(x = liens, …)
Voir l’explication plus détaillée sur le site du package
Sélection des couples de villes distantes de moins de 50 km (2015)
<- distvil[distvil$disteucl<50,] dist50vil
Sélection des couples de grandes villes distantes de moins de 100 km (2015)
# Jointure pour récupérer les populations des villes
<- merge(x = distvil,y =st_drop_geometry(vil[,c("Nom","Pop2015")]),
distvil by.x= "j", by.y= "Nom")
names(distvil)[15] <- "Pop2015j"
<- merge(x = distvil,y =st_drop_geometry(vil[,c("Nom","Pop2015")]),
distvil by.x= "i", by.y= "Nom")
names(distvil)[16] <- "Pop2015i"
# Sélection des couples de villes de plus de 100 000 habitants...
<- distvil[distvil$Pop2015i>100000 & distvil$Pop2015j>100000,]
distvil100k # ... et distantes de moins de 100 km
<- distvil100k[distvil100k$disteucl<100,] dist100vil100k
Carte de liens entre les villes distantes de moins de 50 km ou entre les grandes villes distantes de moins de 100 km
Sélection des identifiants pour le fichier des villes
# Il faut que les identifiants des villes dans le fichier des points soient les mêmes que les identifiants du fichier des liens (les noms des villes) : on ne conserve dans le fichier des villes que la variable "Nom"
<- vil[,c("Nom","Pop2015")] vil
Création du graphe des liens entre toutes les villes proches (<50km) et entre grandes villes proches (<100 km)
<- mf_get_links(x = vil, df = dist50vil)
liens50 <- mf_get_links(x = vil, df = dist100vil100k) liens100
Carte
mf_map(reg, col="bisque", border="white", lwd=0.5)
mf_map(x=vil, pch = 20, cex = 0.8, col = "violet", add=TRUE)
mf_map(x = liens100,
var = "disteucl",
leg_pos = "topright",
leg_title = "Moins de 100 km entre les villes de plus de 100 000 hab.",
col = "purple4", lwd = 2,add=TRUE)
mf_map(x = liens50,
var = "disteucl",
leg_pos = "topright",
leg_title = "Moins de 50 km entre villes",
col = "purple1", lwd = 1,add=TRUE)
# Affichage de qqs noms de villes
mf_label( x = vil[vil$Pop2015>100000,],
var = "Nom",
col = "black",
cex = 0.6,
font = 1,
r = 0.1,
halo = TRUE,
overlap = FALSE,
lines = FALSE
)
mf_title("Villes distantes de moins de 50 km et de moins de 100 km, 2015", cex = 0.8)
mf_scale(pos = "bottomright", lwd = 2, cex = 0.6, scale_units = "km")
mf_credits("Sources : Africapolis 2020, INS & Syfacte/RIATE")
2. Des distances à l’accessibilité
L’accessibilité mesure le degré de facilité avec lequel un lieu, un équipement, une ressource, peuvent être atteints à partir d’un ou de plusieurs autres lieux, en utilisant tout ou partie des moyens de transport existants (Chapelon, 2004). L’accessibilité spatiale s’appuie sur la prise en compte d’une distance entre des populations et des ressources, entendues comme des équipements ou des activités qui répondent aux besoins d’une société ou d’un groupe social (écoles, commerces, lieux d’emploi, lieux de soin…).
L’accessibilité se différencie de l’accès qui concerne le déplacement réellement effectué pour utiliser cette ressource. C’est donc une notion théorique, potentielle, au sens où elle n’est pas liée à une mobilité réalisée. Le passage de l’accessibilité à l’accès effectif dépend en partie de la proximité aux ressources et des conditions de déplacement, mais aussi d’autres composantes non spatiales. Ces dernières peuvent être liées à la perception de l’effort à fournir, au manque d’information sur l’existence de ces ressources, aux horaires d’ouverture (commodités) ainsi qu’à la composante financière de l’accès (coût du service ou bien coût du déplacement).
Il existe de nombreuses mesures possible de l’accessibilité spatiale. Dans cette partie, vous allez voir comment construire plusieurs indicateurs à partir d’une matrice de distances, en vous appuyant sur l’accessibilité des populations (totales) des délégations aux villes universitaires.
De nombreux éléments du code qui suit s’inspirent directement d’un programme construit par R. Ysebaert, dans le cadre d’un projet de recherche sur l’accessibilité aux soins de chirurgie en France mené avec S. Baudet-Michel et B. Conti.
Décrire l’accessibilité locale : une première approche élémentaire à partir d’un site unique et d’un seuil de distance
Dans l’exemple qui suit, vous allez d’abord voir comment créer et représenter la zone accessible autour d’une site unique :
- Carte des distances/temps de trajet autour d’un site (isochrones)
- Combien d’habitants à moins de telle distance/tel temps de trajet de ce site ?
Ici on s’appuiera sur l’ensemble des habitants des secteurs (2004), faute d’avoir une information plus précise sur le nombre de jeunes.
Exemple : quels sont les territoires à moins d’1h par la route de l’Université de Sousse ?
Construction de l’isochrone autour de l’Université de Sousse
à l’aide de la fonction osrmIsochrone
du package osrm
# Sélection de l'université de Sousse
<- univ[univ$Nom=="Sousse",]
UnivSousse # Transformation en WGS84 (pour pouvoir ensuite afficher l'isochrone avec le package Leaflet)
<- st_transform(UnivSousse,4326) %>% select(Nom,geom)
UnivSousseWGS84
# Construction de l'isochrone
<- osrmIsochrone(
isosousse
UnivSousseWGS84,breaks = seq(0,60,60),
res = 30,
osrm.server = getOption("osrm.server"),
osrm.profile = getOption("osrm.profile")
)
# pour récupérer la géométrie de l'isochrone si la connexion au réseau et à OSRM pose problème
# st_read("data/SPA2/isosousse.gpkg")
Afficher l’isochrone avec le fond leaflet
leaflet(UnivSousseWGS84) %>% addTiles() %>% addPolygons(data = isosousse, fillColor = "orange", fillOpacity = 0.3, stroke = FALSE) %>% addCircleMarkers()
Combien d’habitants ont accès à l’Université de Sousse en moins d’1h ?
Sélectionner les secteurs qui se trouvent à moins d’1h de l’Université
<- st_transform(isosousse,crs=3035)
isosousse3035 <- st_transform(secteurs,crs=3035)
secteurs <- st_intersection(x = secteurs, y = isosousse3035) secteursIn
<- secteursIn %>% group_by() %>% summarize(Poptot04 = sum(Population_Tot))
secteursInpop $Poptot04 secteursInpop
[1] 1709571
Quelle est la distance à l’université la plus proche ?
On cherche à sélectionner pour chaque délégation la distance à l’université la plus proche, depuis chaque centroïde de délégation. Cette mesure repose sur l’hypothèse selon laquelle on se rend en priorité à l’université la plus proche.
Etapes suivies :
- Création d’une matrice de distances entre les 264 délégations (origine = centroïdes des dél.) et les 10 universités (source : OSM)
- Sélection pour chaque délégation de la distance minimale à une université
Création d’une matrice des distances (routières) entre les délégations et les universités
On extrait d’abord les centroïdes des délégations
<- st_centroid(del) del_ctr
Puis on construit la matrice des distances routières entre les délégations (origines ori=deleg) et les universités (destinations dest=univ)
# Calcul de temps de trajets avec OSRM
<- osrmTable(src = del_ctr, dst = univ, measure = "duration")
deltime # Extraire les temps de trajet
<- data.frame(deltime$durations)
deltime # Renommer les identifiants des lignes et des colonnes
colnames(deltime) <- as.character(univ$Nom)
row.names(deltime) <- as.character(del_ctr$del_code)
# pour récupérer la matrice deltime si la connexion au réseau et à OSRM pose problème
# readRDS(file = "data/SPA2/deltime.rds")
Carte des temps de trajet vers l’université la plus proche
Récupération pour chaque délégation des temps de trajets les plus courts (distance minimale) …
# Extraire les temps de parcours minimaux
<- apply(deltime, 1, min)
time # Transformation de la matrice en format dataframe
<- data.frame(time)
time $del_code <- rownames(time)
time# Jointure avec le fichier des délégations
<- merge(del, time, by = "del_code", all.x = TRUE) del2
library(mapsf)
mf_init(del)
mf_map(del, col = "lightgrey",
border = NA,
add = TRUE)
mf_map(del2,
type = "choro",
var = "time",
breaks = c(0,15,30,60,120,240,360),
pal = "Purples",
border = "white",
leg_title = "Minutes en voiture",
add = TRUE)
mf_map(univ, pch = 21, col = NA, bg = "red",add=TRUE)
# mf_label(univ,"Nom",col = "black",cex = 0.7,font = 1,r = 0.1,halo = TRUE,overlap = FALSE,lines = FALSE)
mf_scale(size = 10)
mf_title("Temps de trajet vers l'Université la plus proche")
mf_credits("Source : © OpenStreetMap 2024, INS")
Pour récupérer directement le fichier del2 en cas de problème de connexion avec OSRM…
#del2 <- st_read("data/SPA2/del2.gpkg")
Résumer l’accessibilité générale des délégations et des populations aux universités
Indicateurs d’accessibilité moyenne, médiane, maximale
Quelle est la distance minimale moyenne ? médiane ? maximale ? des délégations à l’univ la plus proche
summary(del2$time)
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.40 23.80 55.40 63.38 88.85 339.30
Min. 1st Qu. Median Mean 3rd Qu. Max. 2.40 23.80 55.40 63.39 88.72 342.00
En moyenne, une délégation est distante d’un peu plus d’une heure (63 min) de l’université la plus proche. Les trois quarts des délégations se trouvent entre 24 min et 1h30 de l’université la plus proche. La délégation la plus éloignée (distance maximale) se trouve à près de 6 heures de route de l’université la plus proche.
Distance moyenne pondérée
Certaines délégations très éloignées de l’université la plus proche pèsent fortement dans le calcul de la distance moyenne alors qu’elles comptent peu d’habitants. Pour tenir compte de ces inégalités de populations dans le calcul de la distance moyenne, on peut calculer une distance moyenne pondérée. Cette dernière estime la distance moyenne des populations à l’université la plus proche (et non la distance moyenne des délégations à l’université).
Comme l’illustre la figure ci-dessus, calculer une distance moyenne pondérée revient à multiplier chaque distance par la population de la délégation d’origine et à diviser la somme de ces distances pondérées par la population totale des délégations tunisiennes.
# On multiplie chaque valeur de distance par la population de la délégation d'origine
$timepond <- del2$time * del2$popto_2014
del2# On divise la somme des distances pondérées par la population totale des délégations
<- round(sum(del2$timepond)/ sum(del2$popto_2014),1) dist_moypond
-> Alors, en moyenne, quel est le temps de trajet vers l’université la plus proche pour les habitants des délégations ?
Création d’un tableau qui résume ces résultats
# Resultats à mettre dans un tableau de données
# On crée un nouveau tableau de données (de type 'data frame') nommé "resume_dist" qui aura 8 colonnes et 2 lignes
<- data.frame(matrix(ncol = 4, nrow = 1))
resume_dist colnames(resume_dist) <- c("Variable", "Moyenne", "Moyenne pondérée", "Maximum")
1,1] <- "Dist_univ_pp (min)"
resume_dist[1,2] <- mean(del2$time)
resume_dist[1,3] <- dist_moypond
resume_dist[1,4] <- max(del2$time)
resume_dist[
# Mise en forme soignée à l'aide du package 'kable'
kable(resume_dist, align = "c", escape = F, digits = 0) %>%
kable_paper(full_width = F) %>%
column_spec(1, bold = TRUE)
Variable | Moyenne | Moyenne pondérée | Maximum |
---|---|---|---|
Dist_univ_pp (min) | 63 | 52 | 339 |
Courbe d’accessibilité générale des populations aux universités
La fonction freqCum créée par Ronan Ysebaert produit un graphique qui représente le pourcentage cumulé de la population en fonction d’une distance (en minutes) à l’équipement le plus proche. Elle prend en entrée plusieurs arguments détaillés ci-dessous :
# Arguments de la fonction freqCum :
# x : un data frame qui comprend au minimum une variable exprimant la distance et une variable décrivant une population.<br>
# dist : label de la variable de distance utilisée, comprise dans x.<br>
# pop : label(s) des variables de population utilisées dans l’analyse, comprise(s) dans x.<br>
# label.x : afficher un point (x,y) sur la courbe et son label en fonction d’une ou plusieurs valeurs de x (distance-temps).<br>
# label.y : afficher un point (y,x) sur la courbe et son label en fonction d’une ou plusieurs valeurs de y (population).<br>
# xlab: Label de l’axe des abscisses (temps routier).<br>
# xlim : Emprise du graphique sur l’axe des abscisses (défaut : c(0, 100)).<br>
# ylim : Emprise du graphique sur l’axe des ordonnées (défaut : c(0, 100)).<br>
# lwd : Épaisseur de la ligne (défaut : 0.5).<br>
# lty : Type de ligne (défaut : 1, ligne continue)<br>
# add : Si TRUE, rajouter sur un graphique pré-existant l’affichage de fréquences cumulées (défaut = FALSE).
<- function(x, dist, pop, cols, label.x = NULL, label.y = NULL, xlab, xlim = c(0, 300), ylim = c(0, 100), lwd = 0.5, lty = 1, add = FALSE) {
freqCum
# Sélectionner les valeurs (toutes les lignes + les colonnes dist et pop)
<- x[, c(dist, pop)]
df
# Créer des intervalles de temps (minute par minute)
<- seq(0, max(df[, dist], na.rm = TRUE), by = 0.1)
brks $dist <- findInterval(df[, dist], vec = brks)
df$dist <- brks[df$dist + 1]
df
# Supprimer valeurs manquantes
<- df[!is.na(df$dist), ]
df
# Graphique vide
par(mar = c(4, 4, 1, 1), xaxs = "i", yaxs = "i")
if (add != TRUE) {
plot(1, type = "n", xlab = xlab, ylab = "Effectif cumulé (% population)",
xlim = xlim, ylim = ylim)
abline(h = seq(0, 300, 10), col = "#00000060", lwd = 0.2, lty = 3)
abline(v = seq(0, 300, 10), col = "#00000060", lwd = 0.2, lty = 3)
}
for (i in 1:length(pop)) {
# Agréger les données de pop par pas de temps(les individus du tableau
# deviennent ces intervalles de temps)
<- aggregate(df[, pop[i]], by = list(df$dist), sum)
t
# Création d'une nouvelle variable de fréquence cumulée (d'abord freq
# en effectifs puis cumul en pourcentages) en utilisant la fonction cumsum (base)
$freq <- cumsum(t$x)
t$cumul <- t$freq/t[nrow(t), 3] * 100
tlines(t$Group.1, t$cumul, col = cols[i], lwd = lwd, lty = lty)
if (length(label.x > 0)) {
for (j in 1:length(label.x)) {
<- t[which.min(abs(label.x[j] - t$Group.1)), ]
xy points(y = xy[, "cumul"], x = xy[, "Group.1"], pch = 21, cex = 1.5,
bg = cols[i])
text(y = xy[, "cumul"], x = xy[, "Group.1"], pos = 2, cex = 0.6,
label = paste(round(xy[, "Group.1"], 0), round(xy[, "cumul"], 1),
sep = ", "))
}
}
if (length(label.y > 0)) {
for (j in 1:length(label.y)) {
<- t[which.min(abs(label.y[j] - t$cumul)), ]
xy points(y = label.y[j], x = xy[, "Group.1"], pch = 21, cex = 1.5,
bg = cols[i])
text(y = label.y[j], x = xy[, "Group.1"], pos = 2, cex = 0.6, label = paste(label.y[j],
round(xy[, "Group.1"], 1), sep = ", "))
}
}
} }
Courbe d’accessibilité générale des populations à l’université la plus proche
<- del2
df <- st_drop_geometry(df)
df
# Graphique des distances aux universités, situation initiale
freqCum(x = df, dist = "time", pop = "popto_2014", cols = "blue",
xlab = "Temps routier (minutes) à l'université la plus proche",
xlim = c(0, 300), lwd = 2)
<- deltime
df2
# Création d'une nouvelle colonne dist qui identifie la distance à l'Université la plus proche
$dist <- apply(df2, 1, min)
df2$del_code <- rownames(df2)
df2# Récupération des populations de chaque délégation
<- merge(df2,del,by.x="del_code",by.y="del_code",all.x=TRUE)
df2 # Sélection de 3 colonnes : le code, la distance minimale, la population
<- df2[,c("del_code","dist","popto_2014")]
df2 colnames(df2) <- c("del_code","dist","pop")
# Créer des intervalles de temps (minute par minute)
<- seq(0, max(df2[,"dist"]), by = 1)
brks $dist <- findInterval(df2[,"dist"], vec = brks)
df2
# Supprimer valeurs manquantes
<- df2[!is.na(df2$dist), ]
df2
# Agréger les données de pop par pas de temps(les individus du tableau
# deviennent ces intervalles de temps)
<- aggregate(df2[,"pop"], by = list(df2$dist), sum)
tab colnames(tab)<-c("dist","pop")
# Création d'une nouvelle variable de fréquence cumulée (d'abord freq
# en effectifs puis cumul en pourcentages) en utilisant la fonction cumsum (base)
$freq <- cumsum(tab$pop)
tab$cumul <- round(tab$freq/tab[nrow(tab), 3] * 100,1) tab
A vous de jouer ! Comparez deux scénarios pour l’implantation d’une nouvelle université
Dans cet exercice, on vous propose de comparer les effets de deux scenarios d’implantation d’une nouvelle université, à Kasserine ou à Ben Guerdane, sur l’accessibilité générale des populations des délégations aux universités.
Quelle est l’implantation qui semble a priori la plus favorable ? d’après quels critères ?
Une démarche possible ? :
Créer un nouveau fichier des universités à partir d’univ : soit un fichier univ_K où vous ajouterez une ligne correspondant à la future université de Kasserine (X=4213807,Y=1347151), soit un fichier univ_BG, démarche identique pour Ben Guerdane (X=4434851,Y=1124165)
Construire une nouvelle matrice des distances routières des 264 délégations aux 11 universités (avec soit Kasserine, soit Ben Guerdane en plus)
Extraire la nouvelle valeur de la distance à l’université la plus proche
Calculer les indicateurs d’accessibilité générale (moyenne simple et pondérée, médiane, maximum) et superposer à la courbe d’accessibilité générale vers les 10 universités une deuxième courbe qui prendra en compte la nouvelle implantation universitaire
Création en 4 étapes : 1) on stocke le nom, les coordonnées en X et les coordonnées en Y de la nouvelle université dans un fichier df à l’aide de la fonction nom_nouveau_fichier <- data.frame(var1=” “, var2=” “, var3=” “) 2) on retire les géométries au fichier univ (transformation format sf > df) à l’aide de la fonction nom_nouveau_fichier <- st_set_geometry(nomfichiersf,NULL) 3) on ajoute à univ une ligne correspondant aux coordonnées ponctuelles de la nouvelle univ. à l’aide de la fonction nom_fichier <- rbind(sf1,sf2) 4) on crée un nouveau fichier de géométries à partir des coordonnées ponctuelles de ces 11 universités, à l’aide de la fonction nom_fichier <- st_as_sf(fichierdf,coords = c(“X”,“Y”),crs=st_crs(…))
Pour superposer à la 1ère courbe d’accessibilité générale (avec 10 universités) une deuxième courbe qui prendra en compte la 11ème université, on peut :
joindre au tableau des délégations une nouvelle colonne du temps d’accès à l’université la plus proche pour pouvoir comparer un des deux scenarios A ou B à la situation actuelle
sur le graphique de l’accessibilité générale, ajouter une 2e courbe à l’aide de la fonction freqCum, avec comme dernier argument add=TRUE pour superposer les 2 courbes (situation actuelle, scenario A ou B) freqCum(x = df, dist = “…”, pop = “popto_2014”, cols = “red”, lwd = 2, add = TRUE)
Création de 2 nouveaux fichiers sf
** des universités**
On crée univ_K où on ajoute la localisation de Kasserine
# on récupère les coordonnées de Kasserine et on les stocke dans un fichier df
<- data.frame(Nom="Kasserine",X=4213807,Y=1347151)
Kasserine # on retire les géométries au fichier univ (transformation format sf > df)
<- st_set_geometry(univ,NULL)
univ_K # on ajoute une ligne correspondant aux coordonnées ponctuelles de Kasserine
<- rbind(univ_K,Kasserine)
univ_K # on crée un nouveau fichier de géométries à partir des coordonnées ponctuelles de ces 11 universités
<- st_as_sf(univ_K,coords = c("X","Y"),crs=st_crs(3035)) univ_K
Puis on crée univ_BG où on ajoute la localisation de Ben Guerdane
<- data.frame(Nom="Ben Guerdane",X=4434851,Y=1124165)
BenGuerdane <- st_set_geometry(univ,NULL)
univ_BG <- rbind(univ_BG,BenGuerdane)
univ_BG <- st_as_sf(univ_BG,coords = c("X","Y"),crs=st_crs(3035)) univ_BG
Matrice des distances (routières) entre les délégations et les univ_K + univ_BG
Construction de la matrice des distances routières entre ori=deleg et dest=univ_K
# Calcul de temps de trajets avec OSRM
<- osrmTable(src = del_ctr, dst = univ_K, measure = "duration")
dfK # Extraire les temps de trajet
<- data.frame(dfK$durations)
dfK # Renommer les identifiants des lignes et des colonnes
colnames(dfK) <- as.character(univ_K$Nom)
row.names(dfK) <- as.character(del_ctr$del_code)
head(dfK)
Gabes Monastir Sfax Sousse Tunis Carthage Jendouba Kairouan Gafsa
TN.AN.AR 316.0 151.5 222.1 129.6 20.3 32.2 138.8 151.4 336.5
TN.AN.ET 306.7 142.1 212.8 120.2 16.3 29.0 125.0 142.1 326.4
TN.AN.KA 357.2 192.6 263.2 170.7 61.8 72.3 178.6 192.6 378.2
TN.AN.LS 364.4 199.8 270.5 177.9 68.6 67.4 189.9 199.8 385.5
TN.AN.MN 316.4 151.8 222.4 129.9 23.2 35.0 136.3 151.8 335.9
TN.AN.RA 316.7 152.1 222.8 130.2 21.4 26.4 139.0 152.1 337.8
La_Manouba Kasserine
TN.AN.AR 32.5 264.2
TN.AN.ET 13.3 254.0
TN.AN.KA 71.6 305.8
TN.AN.LS 84.0 313.1
TN.AN.MN 28.9 263.6
TN.AN.RA 32.0 265.4
Construction de la matrice des distances routières entre ori=deleg et dest=univ_BG
# Calcul de temps de trajets avec OSRM
<- osrmTable(src = del_ctr, dst = univ_BG, measure = "duration")
dfBG # Extraire les temps de trajet
<- data.frame(dfBG$durations)
dfBG # Renommer les identifiants des lignes et des colonnes
colnames(dfBG) <- as.character(univ_BG$Nom)
row.names(dfBG) <- as.character(del_ctr$del_code)
head(dfBG)
Gabes Monastir Sfax Sousse Tunis Carthage Jendouba Kairouan Gafsa
TN.AN.AR 316.0 151.5 222.1 129.6 20.3 32.2 138.8 151.4 336.5
TN.AN.ET 306.7 142.1 212.8 120.2 16.3 29.0 125.0 142.1 326.4
TN.AN.KA 357.2 192.6 263.2 170.7 61.8 72.3 178.6 192.6 378.2
TN.AN.LS 364.4 199.8 270.5 177.9 68.6 67.4 189.9 199.8 385.5
TN.AN.MN 316.4 151.8 222.4 129.9 23.2 35.0 136.3 151.8 335.9
TN.AN.RA 316.7 152.1 222.8 130.2 21.4 26.4 139.0 152.1 337.8
La_Manouba Ben Guerdane
TN.AN.AR 32.5 409.8
TN.AN.ET 13.3 400.5
TN.AN.KA 71.6 451.0
TN.AN.LS 84.0 458.2
TN.AN.MN 28.9 410.2
TN.AN.RA 32.0 410.5
Récupérer pour chaque délégation la distance à l’université la plus proche et la cartographier
Extraire les temps de parcours minimaux
# Avec Kasserine (scenario A)
<- apply(dfK, 1, min)
timeK <- data.frame(timeK)
timeK $del_code <- rownames(timeK)
timeK
# Avec Ben Guerdane (scenario B)
<- apply(dfBG, 1, min)
timeBG <- data.frame(timeBG)
timeBG $del_code <- rownames(timeBG) timeBG
Ajout dans le fichier des délégations des temps de parcours avec le scenario A (Kasserine) et le scenario B (Ben Guerdane)
<- merge(del2, timeK, by = "del_code", all.x = TRUE)
del2_K <- merge(del2_K, timeBG, by = "del_code", all.x = TRUE)
del2_K_BG <- del2_K_BG del3
Cartes scenario A et scenario B
# Mise en page (1 lignes, 2 colonnes)
par(mfrow = c(1, 2))
mf_init(del)
mf_map(del3, col = "lightgrey",border = NA,add = TRUE)
mf_map(del3,type = "choro",var = "timeK",breaks = c(0,15,30,60,120,240,360),pal = "Purples",border = "white", leg_title = "Minutes en voiture", add = TRUE)
mf_map(del, col = NA, border = "black",add = TRUE)
mf_map(univ_K, pch = 21, col = NA, bg = "red", add = TRUE)
mf_scale(size = 10)
mf_title("Temps de trajet vers l'Université la plus proche (avec Kasserine)", cex=0.8)
mf_credits(paste0("Source : © OpenStreetMap et © Wikipedia 2024"))
mf_init(del)
mf_map(del3, col = "lightgrey",border = NA,add = TRUE)
mf_map(del3,type = "choro",var = "timeBG",breaks = c(0,15,30,60,120,240,360),pal = "Purples",border = "white", leg_title = "Minutes en voiture", add = TRUE)
mf_map(del, col = NA, border = "black",add = TRUE)
mf_map(univ_BG, pch = 21, col = NA, bg = "red", add = TRUE)
mf_scale(size = 10)
mf_title("Temps de trajet vers l'Université la plus proche (avec Ben Guerdane)", cex=0.8)
mf_credits(paste0("Source : © OpenStreetMap et © Wikipedia 2024"))
Statistiques élémentaires sur la distance minimale à l’université la plus proche
Quelle est la distance moyenne ? moyenne pondérée ? maximale ? des délégations à l’univ la plus proche ?
Tableau qui résume ces résultats : situation initiale (0), scenario A (avec Kasserine), scenario B (avec Ben Guerdane)
<- na.omit(del3)
del3
<- data.frame(matrix(ncol = 4, nrow = 3))
resume_dist colnames(resume_dist) <- c("Distance_univ_pp (min)", "Moyenne", "Moyenne pondérée", "Maximum")
1,1] <- "Situation 0"
resume_dist[1,2] <- mean(del3$time)
resume_dist[1,3] <- sum(del3$time*del3$popto_2014)/ sum(del3$popto_2014)
resume_dist[1,4] <- max(del3$time)
resume_dist[
2,1] <- "Scenario A"
resume_dist[2,2] <- mean(del3$timeK)
resume_dist[2,3] <- sum(del3$timeK * del3$popto_2014)/ sum(del3$popto_2014)
resume_dist[2,4] <- max(del3$timeK)
resume_dist[
3,1] <- "Scenario B"
resume_dist[3,2] <- mean(del3$timeBG)
resume_dist[3,3] <- sum(del3$timeBG * del3$popto_2014)/ sum(del3$popto_2014)
resume_dist[3,4] <- max(del3$timeBG)
resume_dist[
# Mise en forme soignée à l'aide du package 'kable'
library(kableExtra)
kable(resume_dist, align = "c", escape = F, digits = 0) %>%
kable_paper(full_width = F) %>%
column_spec(1, bold = TRUE)
Distance_univ_pp (min) | Moyenne | Moyenne pondérée | Maximum |
---|---|---|---|
Situation 0 | 63 | 52 | 339 |
Scenario A | 60 | 49 | 339 |
Scenario B | 62 | 50 | 308 |
Courbe d’accessibilité générale des populations à l’université la plus proche
# On crée un nouveau tableau df à partir du fichier deltime, dont on a retiré
# les géométries
<- st_set_geometry(del3, NULL)
df
# Graphique distances aux universités, situation initiale
freqCum(x = df, dist = "time", pop = "popto_2014", cols = "blue",
xlab = "Temps routier (minutes) à l'université la plus proche",
xlim = c(0, 300), lwd = 2)
# Graphique distances aux universités, scenario A (avec Kasserine)
freqCum(x = df, dist = "timeK", pop = "popto_2014", cols = "red",
lwd = 2, add = TRUE)
# Graphique distances aux universités, scenario B (avec Ben Guerdane)
freqCum(x = df, dist = "timeBG", pop = "popto_2014", cols = "green",
lwd = 2, add = TRUE)
# Ajout d'une légende au graphique
legend("bottomright", legend = c("Situation initiale (10 universités)", "Scenario A (avec Kasserine)","Scenario B (avec Ben Guerdane)"),
col = c("blue", "red","green"), cex = 0.8, inset = c(0, 0), border = NA, bty = "n", lwd = 2)
Ce support a été créé pour la semaine de formation franco-tunisienne GEO UNIV’R Tunisie 2024 - “Enseigner la statistique, la cartographie et l’analyse spatiale avec R qui se tient à Sousse en mai 2024.
Références
Chapelon L., 2014, “Accessibilité”, Hypergeo, encyclopédie en ligne
Pumain D., Saint-Julien T., 2010, Analyse spatiale : les localisations, Paris : Cursus Armand Colin, p.31.
sessionInfo()
R version 4.4.1 (2024-06-14)
Platform: x86_64-apple-darwin20
Running under: macOS 15.1
Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/4.4-x86_64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.4-x86_64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.0
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
time zone: Europe/Paris
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] kableExtra_1.4.0 osrm_4.2.0 mapview_2.11.2 leaflet_2.2.2
[5] units_0.8-5 mapsf_0.12.0 sf_1.0-19 dplyr_1.1.4
loaded via a namespace (and not attached):
[1] s2_1.1.7 generics_0.1.3 xml2_1.3.6
[4] class_7.3-22 KernSmooth_2.23-24 stringi_1.8.4
[7] lattice_0.22-6 digest_0.6.37 magrittr_2.0.3
[10] evaluate_1.0.1 grid_4.4.1 fastmap_1.2.0
[13] jsonlite_1.9.1 e1071_1.7-16 DBI_1.2.3
[16] viridisLite_0.4.2 crosstalk_1.2.1 scales_1.3.0
[19] jquerylib_0.1.4 isoband_0.2.7 codetools_0.2-20
[22] cli_3.6.4 rlang_1.1.5 munsell_0.5.1
[25] withr_3.0.2 base64enc_0.1-3 yaml_2.3.10
[28] tools_4.4.1 raster_3.6-30 colorspace_2.1-1
[31] curl_6.2.1 vctrs_0.6.5 R6_2.6.1
[34] png_0.1-8 stats4_4.4.1 proxy_0.4-27
[37] lifecycle_1.0.4 classInt_0.4-10 stringr_1.5.1
[40] htmlwidgets_1.6.4 pkgconfig_2.0.3 terra_1.8-29
[43] pillar_1.10.1 glue_1.8.0 Rcpp_1.0.13-1
[46] RcppSimdJson_0.1.12 systemfonts_1.1.0 xfun_0.49
[49] tibble_3.2.1 tidyselect_1.2.1 rstudioapi_0.17.1
[52] knitr_1.49 maplegend_0.1.0 htmltools_0.5.8.1
[55] svglite_2.1.3 leafem_0.2.3 rmarkdown_2.29
[58] wk_0.9.4 satellite_1.0.5 compiler_4.4.1
[61] mapiso_0.3.0 sp_2.1-4
Comment mesurer la distance à vol d’oiseau entre ces deux villes ? Quel est l’écart par rapport à la distance routière ?
De manière générale, une métrique est une fonction mathématique qui permet d’associer à tout couple de coordonnées (i,j) une mesure de distance Dij.
La plus connue et la plus fréquemment utilisée est la métrique euclidienne, mais il en existe d’autres (métrique rectilinéaire, orthodromique…) qui peuvent s’avérer plus adaptées selon les contextes et les objectifs de mesure.
Source de la figure : Pumain D., Saint-Julien T., 2010, Analyse spatiale : les localisations, Paris : Cursus Armand Colin, p.31.
D’après le service de calcul d’itinéraire OSRM, l’itinéraire routier le plus court par la route pour aller de l’agglomération de Tunis à celle de Ben Guerdane fait 550 km.
Dist_rout(Tunis-BenG) = 550 km
Par comparaison, quelle est la distance à vol d’oiseau entre ces deux villes ? et la distance rectilinéaire ? quel est l’écart entre distance routière et distances estimées ? \
X_Tunis = 4 342 371 m, Y_Tunis = 1 525 005 m
X_BenG = 4 434 680 m, Y_BenG = 1 124 046 m
Dist_eucli(Tunis-BenG) = 411 km
La distance euclidienne sous-estime de 34% la distance routière.
Dist_recti(Tunis-BenG) = 493 km
La distance rectilinéaire sous-estime de 12% la distance routière.