## Les packages utilisés pour cet exercice
# install.packages(dplyr)
# install.packages(ggplot2)
# install.packages(sf)
# install.packages(mapview)
# install.packages(units)
library(dplyr)
library(ggplot2)
library(sf)
library(mapview)
library(units)Séance 2 - Exercice 1 : Introduction aux données géolocalisées
Jusqu’à présent, nous avons manipulé des données sous forme de tableau. Nous allons maintenant introduire une nouvelle dimension : l’espace.
Une donnée spatiale contient non seulement des informations sur des objets, mais également des informations permettant de localiser ces objets géographiquement.
Par exemple :
une école peut être représentée par un point ;
une route peut être représentée par une ligne ;
une commune peut être représentée par un polygone.
Le package sf permet de manipuler ce type de données dans R.
1. Les données spatiales avec sf
sf signifie Simple Features. Une couche sf ressemble beaucoup à une base de données classique, mais elle contient en plus une colonne particulière contenant la géométrie. La géométrie permet de savoir où se situe chaque observation.
2. Les communes de Nantes Métropole : des polygones
Nous allons récupérer le jeu de données au format GeoJSON grâce à l’API.
url_communes <- paste0(
"https://data.nantesmetropole.fr/api/explore/v2.1/catalog/datasets/",
"244400404_communes-nantes-metropole/",
"exports/geojson"
)Puis nous utilisons st_read() pour importer la base de données dans notre environnement. La fonction st_read() est une fonction du package sf qui permet de lire une donnée spatiale.
communes <- st_read(url_communes)Reading layer `geojson' from data source
`https://data.nantesmetropole.fr/api/explore/v2.1/catalog/datasets/244400404_communes-nantes-metropole/exports/geojson'
using driver `GeoJSON'
Simple feature collection with 24 features and 6 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: -1.921795 ymin: 47.10192 xmax: -1.358526 ymax: 47.35328
Geodetic CRS: WGS 84
Nous pouvons regarder les premières lignes :
head(communes)Simple feature collection with 6 features and 6 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: -1.921795 ymin: 47.18332 xmax: -1.358526 ymax: 47.34416
Geodetic CRS: WGS 84
gid idobj id_insee maj_date nom
1 9 440074 44074 2022-11-15 INDRE
2 20 440094 44094 2022-11-15 MAUVES-SUR-LOIRE
3 24 440190 44190 2022-11-15 SAINT-SEBASTIEN-SUR-LOIRE
4 8 440114 44114 2022-11-15 ORVAULT
5 5 440120 44120 2022-11-15 LE PELLERIN
6 12 440194 44194 2022-11-15 SAUTRON
toponyme geometry
1 Indre POLYGON ((-1.694991 47.1997...
2 Mauves-sur-Loire POLYGON ((-1.395976 47.2849...
3 Saint-Sébastien-sur-Loire POLYGON ((-1.474128 47.1867...
4 Orvault POLYGON ((-1.589394 47.2392...
5 Le Pellerin POLYGON ((-1.747217 47.2052...
6 Sautron POLYGON ((-1.66799 47.25178...
Vous remarquerez qu’en plus des variables classiques, l’objet contient une colonne geometry. C’est cette colonne qui contient l’information spatiale.
3. Le système de coordonnées — CRS
Une question essentielle se pose maintenant :
Comment R sait-il où se trouvent ces communes ?
La réponse repose sur le système de coordonnées de référence, ou CRS (Coordinate Reference System).
Nous pouvons connaître le CRS d’une couche avec :
st_crs(communes)Coordinate Reference System:
User input: WGS 84
wkt:
GEOGCRS["WGS 84",
DATUM["World Geodetic System 1984",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
CS[ellipsoidal,2],
AXIS["geodetic latitude (Lat)",north,
ORDER[1],
ANGLEUNIT["degree",0.0174532925199433]],
AXIS["geodetic longitude (Lon)",east,
ORDER[2],
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4326]]
Le CRS indique notamment comment interpréter les coordonnées contenues dans la géométrie.
Il est essentiel lorsque nous souhaitons :
superposer plusieurs couches ;
calculer des distances ;
calculer des surfaces ;
effectuer des opérations spatiales ;
produire des cartes.
4. Transformer le système de coordonnées
Nous pouvons transformer la couche dans un autre système de coordonnées avec st_transform().
Dans notre exemple, nous allons utiliser le Lambert-93, dont le code EPSG est 2154.
communes_lambert <- st_transform(communes, crs = 2154)Nous pouvons vérifier le résultat :
st_crs(communes_lambert)Coordinate Reference System:
User input: EPSG:2154
wkt:
PROJCRS["RGF93 v1 / Lambert-93",
BASEGEOGCRS["RGF93 v1",
DATUM["Reseau Geodesique Francais 1993 v1",
ELLIPSOID["GRS 1980",6378137,298.257222101,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4171]],
CONVERSION["Lambert-93",
METHOD["Lambert Conic Conformal (2SP)",
ID["EPSG",9802]],
PARAMETER["Latitude of false origin",46.5,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8821]],
PARAMETER["Longitude of false origin",3,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8822]],
PARAMETER["Latitude of 1st standard parallel",49,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8823]],
PARAMETER["Latitude of 2nd standard parallel",44,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8824]],
PARAMETER["Easting at false origin",700000,
LENGTHUNIT["metre",1],
ID["EPSG",8826]],
PARAMETER["Northing at false origin",6600000,
LENGTHUNIT["metre",1],
ID["EPSG",8827]]],
CS[Cartesian,2],
AXIS["easting (X)",east,
ORDER[1],
LENGTHUNIT["metre",1]],
AXIS["northing (Y)",north,
ORDER[2],
LENGTHUNIT["metre",1]],
USAGE[
SCOPE["Engineering survey, topographic mapping."],
AREA["France - onshore and offshore, mainland and Corsica (France métropolitaine including Corsica)."],
BBOX[41.15,-9.86,51.56,10.38]],
ID["EPSG",2154]]
Pour représenter des données géographiques en France métropolitaine, deux systèmes de coordonnées sont particulièrement courants :
1. WGS84 — EPSG:4326
Le système WGS84 utilise des coordonnées géographiques exprimées en degrés :
Longitude (x) : environ de −5,2° à +9,6°
Latitude (y) : environ de +41,3° à +51,1°
2. Lambert 93 — EPSG:2154
Le système Lambert 93 est le système de référence officiel utilisé en France métropolitaine.
Les coordonnées sont exprimées en mètres, ce qui est particulièrement adapté au calcul des distances et des superficies.
Coordonnée x : environ de 100 000 à 1 300 000 m
Coordonnée y : environ de 6 000 000 à 7 200 000 m
5. Première carte avec mapview et ggplot
Nous pouvons maintenant représenter nos communes sur une carte de deux façons.
Avec mapview, nous obtenons une carte interactive, particulièrement pratique pour explorer les données :
mapview(communes)Avec ggplot2, nous pouvons créer une carte statique, davantage adaptée à une présentation ou à un rapport :
ggplot(communes) +
geom_sf(aes(fill = nom), alpha = 0.5) + # aes(fill = ) permet de colorier les communes selon leur nom
#geom_sf_label(aes(label = nom), size = 3) +
theme_void() +
theme(legend.position = "none")
La ligne geom_sf_label() est ici commentée (#). Elle peut être décommentée pour afficher le nom de chaque commune sur la carte.
6. Calculs de superficie
La superficie d'un territoire est une information importante pour de nombreuses analyses géographiques. Par exemple, pour calculer une densité de population, on rapporte le nombre d'habitants à la superficie du territoire.
La fonction st_area() permet de calculer la superficie de polygones.
Calculons la superficie de la commune de Nantes à partir de sa géométrie (Lambert-93), en mètres carré puis en kilomètres carrés :
superficie_nantes_m2 <- communes_lambert %>%
filter(toponyme=="Nantes") %>%
st_area(geometry)
superficie_nantes_km2 <- superficie_nantes_m2 %>%
set_units("km^2")Calculez l'aire de chaque commune et identifiez la commune ayant la plus grande superficie.
7. Les tronçons de voies : des lignes
Nous allons maintenant travailler avec un troisième type de géométrie : les lignes.
Nous allons récupérer les tronçons de voies de Nantes Métropole. Le portail propose notamment un export au format GeoJSON pour ce jeu de données.
url_voies <- paste0(
"https://data.nantesmetropole.fr/api/explore/v2.1/catalog/datasets/",
"244400404_troncons-voies-nantes-metropole/",
"exports/geojson"
)
voies <- st_read(url_voies)Reading layer `geojson' from data source
`https://data.nantesmetropole.fr/api/explore/v2.1/catalog/datasets/244400404_troncons-voies-nantes-metropole/exports/geojson'
using driver `GeoJSON'
Simple feature collection with 40541 features and 30 fields
Geometry type: MULTILINESTRING
Dimension: XY
Bounding box: xmin: -1.904228 ymin: 47.11702 xmax: -1.360156 ymax: 47.3533
Geodetic CRS: WGS 84
Nous pouvons explorer l’objet :
View(voies)Nous avons différents types de voies :
unique(voies$classement_pdu) [1] "Voie Secondaire" "Voie principale de catégorie B"
[3] "Voie principale de catégorie A" "Voie Magistrale"
[5] NA
unique(voies$classement_circulation) [1] "Circulation Non Sensible" "Circulation Sensible"
[3] "Circulation Très Sensible" NA
unique(voies$statut)[1] "Voie publique" "Voie privée" "Mixte" NA
[5] "Inconnu"
Visualiser la base de données :
- Combien a-t-elle de lignes et de colonnes ?
- Comment s’appelle la géométrie utilisée ?
- Quel CRS est utilisé ?
- Faites une carte en ne faisant apparaître que les voies principales et magistrales de la zone d’étude.
- Calculer la longueur totale des voies principales et magistrales en utilisant la fonction
set_units(st_length(), "km")). - Créez un nouvel objet, que vous appelez
voies_lambert, où la géométrie est codée en Lambert-93. - A partir de ce nouvel objet, calculez la longueur totale des voies principales et magistrales. Que constatez vous ?
8. Les équipements publics : des points
Nous allons maintenant travailler avec les équipements publics de Nantes Métropole.
Nous construisons l’URL et importons les données :
url_equip_pub <- paste0(
"https://data.nantesmetropole.fr/api/explore/v2.1/catalog/datasets/",
"244400404_equipements-publics-nantes-metropole/",
"exports/geojson"
)
equip_pub <- st_read(url_equip_pub)Reading layer `geojson' from data source
`https://data.nantesmetropole.fr/api/explore/v2.1/catalog/datasets/244400404_equipements-publics-nantes-metropole/exports/geojson'
using driver `GeoJSON'
Simple feature collection with 3844 features and 42 fields
Geometry type: POINT
Dimension: XY
Bounding box: xmin: -1.827033 ymin: 47.12003 xmax: -1.371781 ymax: 47.34134
Geodetic CRS: WGS 84
- Choisissez un type d’équipement publique et faites une carte (interactive ou non) pour montrer leur localisation au sein de la métropole nantaise.
- Visualiser un unique point sur une carte : notre IAE.
- Compter le nombre d’infrastructures de sport et loisirs présents dans chaque commune de la métropole de Nantes.
- Faites une carte chloropèthe affichant le nombre d’infrastructures de sport et loisirs par commune.
9. Spatial join
Pour répondre aux questions précédentes (7.3 et 7.4), vous avez probablement utilisé une jointure classique à partir du nom ou du code de la commune. Cela était possible car ces informations étaient disponibles dans les données des équipements publics.
Mais ce ne sera pas toujours le cas. Certaines données géolocalisées ne contiennent aucune information permettant d’identifier directement le territoire auquel appartient chaque objet. Il faut alors utiliser la géométrie.
Ici, nous allons réaliser une jointure spatiale entre les équipements publics et les communes : l’objectif est d’identifier dans quel polygone communal se trouve chaque équipement.
Pour commencer, supprimons les informations permettant d’identifier directement la commune :
equip_pub_simple <- equip_pub %>%
select(idobj_equipub, nom, nom_complet, theme, categorie, type, geometry)Nous allons maintenant essayer de joindre cet objet avec les communes :
equip_pub_commune <- st_join(equip_pub_simple,communes_lambert)Observez le message qui s’affiche.
Le problème vient du CRS : les deux objets n’utilisent pas le même système de coordonnées.
Pour réaliser une opération spatiale entre deux couches, leurs CRS doivent être identiques. Il faut donc d’abord transformer les équipements dans le même système de coordonnées que les communes, ici le Lambert-93 (EPSG:2154) :
equip_pub_commune <- equip_pub_simple %>%
st_transform(geometry,crs = 2154) %>%
st_join(communes_lambert)La jointure spatiale peut maintenant être réalisée. Chaque équipement est associé à la commune dont le polygone contient son point.
Avant toute opération spatiale entre deux couches, vérifiez toujours leur CRS avec st_crs().
10. Les centroïdes
Nous allons maintenant utiliser une autre opération spatiale très courante : le calcul du centroïde.
Le centroïde correspond à un point représentant approximativement le centre géométrique d’un objet spatial.
Par exemple, si nous disposons des polygones des communes :
centroides <- st_centroid(communes_lambert)Warning: st_centroid assumes attributes are constant over geometries
Nous pouvons visualiser les centroïdes :
ggplot() +
geom_sf(data = communes, fill = "white", color = "grey50") +
geom_sf(data = centroides, color = "red", size = 2) +
theme_void()
Nous obtenons ainsi un point pour chaque commune.
Pourquoi utiliser les centroïdes ?
Les centroïdes peuvent être utiles lorsque nous souhaitons représenter un territoire sous la forme d’un point, notamment pour afficher des étiquettes sur des cartes, et surtout pour calculer des distances.
Le centroïde est un centre géométrique et ne correspond pas nécessairement au centre géographique ou au centre de population d’un territoire.
Pour une commune de forme irrégulière, le centroïde peut même se trouver à l’extérieur du polygone. Dans notre exemple, le centroïde de la commune de Le Pellerin (44120) est situé à sa frontière.
Lorsque l’on souhaite obtenir un point situé à l’intérieur du polygone, on peut utiliser :
points_internes <- st_point_on_surface(communes_lambert)
Calculez les points internes de chaque commune et réalisez une carte faisant apparaître :
les contours des communes en noir ;
les centroïdes en rouge ;
les points internes en vert.
Observez la différence entre les deux types de points.
11. Calculs de distance euclidienne
La fonction st_distance() permet de calculer la distance entre des objets géographiques. Par exemple ici, on calcule la distance en kilomètres entre les centroïdes de Nantes et de Couëron.
nantes <- centroides %>%
filter(toponyme == "Nantes")
coueron <- centroides %>%
filter(toponyme == "Couëron")
distance <- st_distance(nantes, coueron)
distance_km <- set_units(distance, "km")
distance_kmUnits: [km]
[,1]
[1,] 13.77579
Conclusion
Dans cet exercice, nous avons appris à manipuler des données géographiques avec sf et à réaliser différentes opérations spatiales (jointures, calculs de longueur de segments, calculs d'aire de polygones, calculs de distance entre des points).
Nous avons également appris à les visualiser les données sur ces cartes, de manière interactive avec mapview et de manière statique avec ggplot2.
Tous ces outils permettent d'intégrer la dimension spatiale dans l'analyse des données et constituent une première étape vers des analyses géographiques plus avancées.