class: title-slide background-image: url("images/Raddicts.png") background-position: 110% 98% background-size: 75% # Données géospatiales et cartographie avec R ### Nicolas Roelandt #### vendredi 28 juin 2019 --- # Intervenant * Nicolas Roelandt * Géomaticien * membre de l'[OSGeo](https://www.osgeo.org/) et de l'[OSGeo-fr](https://www.osgeo.asso.fr/) ![:scale 100%](images/logo_osgeofr.png) --- * Manipule de la data géo -- * avec QGIS, Python, PostGreSQL/PostGIS -- * et R ;) -- * Cartographie --- # Contenu 1. Comprendre les données géospatiales 2. les packages R dédiés 3. Code Officiel Géographique avec R --- class: inverse, center, middle # 1. Comprendre les données géospatiales --- # Data géo ## Un monde de couches * superposition de couches * couches vectorielles * bâtiments * routes * parcellaire * etc --- # Data géo ## Un monde de couches * couches raster - imagerie satellites ou aérienne - élévation - fond de plan cartographique - etc --- # Data géo ## Un monde de couches .center[ ![:scale 90%](images/dataLayers_32282.jpg) ] ??? source: https://www.gao.gov/assets/660/650293.pdf --- # Data géo ## Données vectorielles #### Types .font90[ * points * lignes * polygones * Multi-* * Collections ] ![:scale 100%](images/DatendimensionenImGIS.jpg) ??? source : https://commons.wikimedia.org/wiki/File:DatendimensionenImGIS.jpg --- class: split-two .column[ # Data géo ## Données vectorielles #### Formats * shapefile * (Geo)JSON * CSV * **GeoPackage** ] .column[ ![:scale 40%](images/CustomShapeFileRealLogo.jpg) ### ![:scale 50%](images/geopkg.png) ] --- # Data géo ## Données raster -- "Données images où l'espace est divisé de manière régulière (en petits rectangles); à chaque petit rectangle (pixel) sont associées une ou plusieurs valeurs décrivant les caractéristiques de l'espace." [Vince - PortailSIG](http://www.portailsig.org/content/qu-est-ce-qu-un-raster) --- class: split-two .column[ # Data géo ## Données raster .font90[ * Types * Modèle Numérique de Terrain / Elevation * imagerie visible et/ou multi-spectrale * imagerie radar * LIDAR * NetCDF ] ] .column[.font90[ * Formats * (geo)TIFF * JPEG * ERDAS * CSV ] ] --- # Data géo ## Données raster ![:scale 60%](images/raster_exemple.png) ??? source: http://desktop.arcgis.com/en/arcmap/10.3/manage-data/raster-and-images/what-is-raster-data.htm --- background-image: url("images/map-projections-types.jpg") background-position: 95% 5% background-size: 35% # Data géo ## Systèmes de référence de coordonnées et projections -- .font80[ * Formules mathématiques permettant de passer des coordonnées d'une sphère à un plan 2D (et inversement) ] -- 2 cas : -- .font80[ * Systèmes de coordonnées **géographiques** * Latitude : ɸ, * Longitude : ʎ, * (Hauteur ellipsoïdale : h) ] -- .font80[ * Systèmes de coordonnées **plans** (ou projetés) * Coordonnées X/Y ou E/N ] --- background-image: url("images/map-projections-types.jpg") background-position: 95% 5% background-size: 35% # Data géo ## Types de projections .font90[* 2 cas généraux : * *conforme* : conserve les angles * *équivalente* : conserve les surfaces ] -- .font90[ * Types courants : * projection cylindrique * projection conique * projection azimutale ] -- .font90[Pour aller plus loin : [Video "Why every world map is wrong" by Jay Foreman (YT)](https://www.youtube.com/watch?v=jtBV3GgQLg8) ] --- background-image: url("images/map-projections-types.jpg") background-position: 95% 5% background-size: 35% # Data géo ## SRC et projections -- .font80[ * En France métropolitaine : * RGF93/Lambert93, système légal 2D projeté : **EPSG:2154** * WGS84 (système GPS) : **EPSG:4326** ] -- .font80[ * Pour les DOM: * Systèmes UTM locaux * WGS84 ] ??? Lambert93: X/Y WGS84: lat/lon --- # Sémiologie graphique .center[![:scale 110%](images/lightsemio.png) (Illustration (c) by Thimothée Giraud - UMR RIATE/CNRS) ] --- ## Où trouver de la data géo ? -- .font80[ * données IGN : * Open data : * http://www.professionnels.ign.fr/donnees * [adminexpress](http://www.professionnels.ign.fr/adminexpress) ] -- .font80[ * données open data * [data.gouv.fr](https://www.data.gouv.fr/fr/) * Portails open data locaux : [Paris](https://opendata.paris.fr/), [Nantes Métropole](https://data.nantesmetropole.fr), [Grand Lyon](https://data.grandlyon.com), etc. ] -- .font80[ * données enquêtes * géolocalisation GPS * Adresses => [géocodage](https://adresse.data.gouv.fr/) ] --- class: inverse, center, middle # Et R dans tout ça ? -- De nombreux packages peuvent manipuler de la data géo -- {sf} {ggplot} {cartography} ... --- ## {sf} .center[![:scale 85%](images/sf_illustratation.jpg) (Illustration (c) by [Allison Horst](https://twitter.com/allison_horst/status/1071456081308614656)) ] --- background-image: url("images/sf_logo.gif") background-position: 95% 5% background-size: 20% ## {sf} ### Intérêts .font80[ * hérite de {sp}, {rgdal}, {rgeos} * se connecte à `GDAL`, `GEOS`, `PROJ` * étend le `dataframe` en ajoutant une colonne `GEOMETRY` * compatible Tidyverse * fonctions spatiales de base * st_read() / st_write() * st_intersection() / st_intersects() * st_buffer() / st_union() * etc ] --- background-image: url("images/sf_xfig.png") background-position: 50% 50% background-size:100% ##{sf} ### Structure de données ??? source: https://r-spatial.github.io/sf/articles/sf1.html --- background-image: url("images/sf_logo.gif") background-position: 95% 5% background-size: 20% ## {sf} ### Astuces .font80[ Manipulation de la data géo facileté mais : * `st_set_CRS()` ou `st_transform()` au chargement * `st_drop_geometry()` * `nested-join` à préférer à `left-join` (**dplyr >= 0.8.0**) ] ??? `nested-join` à préférer à `left-join` pour les jointures spatiales / non-spatial --- ## Données raster -- * {raster} * {stars} * {rayshader} --- ## Que puis-je faire de mes data géo ? -- * data classique : filtrage, sélection, mutation, statistiques -- * data géo: statistiques spatiales (régression spatiale, Moran, Geary, Kriegage) * [{spdep}](https://r-spatial.github.io/spdep/) * [{ade4}](http://pbil.univ-lyon1.fr/ADE-4/) --- ## Que puis-je faire de mes data géo ? * Cartographie -- - {ggplot2} - {cartography} - {tmap} - {leaflet} - {mapview} --- ## {ggplot2} + {ggspatial} * Part of the {tidyverse} * Hadley Wickham, Thomas Lin Pedersen, Kara Woo * Basé sur une accumulation de couche * compatible avec {sf} et les outils du {tidyverse} * Orienté data visualisation * {ggspatial} fournit les décorations (flèche nord, échelle, etc) --- ## ggplot2 ```r library(sf) library(ggplot2) ggplot() + geom_sf(data = dep, colour = "ivory3",fill = "ivory") + geom_sf(data = sm, aes(fill = pcad), colour = "grey80") + geom_sf(data = river.geom, colour = "azure",size=2) + geom_sf(data = roads.geom, colour = "#666666",size=0.5) + geom_text(data=labgg,aes(x=x,y=y,label=LIBELLE))+ scale_fill_gradientn(name = "Share of managers (%)", values=bks/max(bks), colours = carto.pal("green.pal", 3,"wine.pal",3)) + coord_sf(crs = 2154, datum = NA, xlim = st_bbox(sm)[c(1,3)], ylim = st_bbox(sm)[c(2,4)]) + theme_minimal() + theme(panel.background = element_rect(fill = "azure",color=NA)) + labs(title = "Managers", caption = "Insee, 2018\nKim, Tim & Comeetie, 2019",x="",y="") ``` --- ## {ggplot2} .center[![:scale 110%](images/exemple_ggplot2.png?inline=false)] source: [Atelier SatRday 2019 - Kim, Tim & Comeetie](https://github.com/comeetie/satRday) --- ## {Cartography} .left-code[ * RIATE (laboratoire du CNRS) - Timothée Giraud - Nicolas Lambert * dédié à la cartographie Documentation : [riatelab.github.io/cartography/](https://riatelab.github.io/cartography/docs/) ] .right-plot[ ![:scale 75%](images/logo_cartography.png) ] --- ## {Cartography} .code70[ ```r library(sf, cartography) # path to the geopackage file embedded in cartography path_to_gpkg <- system.file("gpkg/mtq.gpkg", package="cartography") # import to an sf object mtq <- st_read(dsn = path_to_gpkg, quiet = TRUE) # Plot the municipalities plot(st_geometry(mtq), col="darkseagreen3", border="darkseagreen4", bg = "lightblue1", lwd = 0.5) # Plot symbols with choropleth coloration propSymbolsChoroLayer( x = mtq, var = "POP", inches = 0.4, border = "grey50", lwd = 1, legend.var.pos = "topright", legend.var.title.txt = "Population", var2 = "MED", method = "equal", nclass = 4, col = carto.pal(pal1 = "sand.pal", n1 = 4), legend.var2.values.rnd = -2, legend.var2.pos = "left", legend.var2.title.txt = "Median\nIncome\n(in euros)" ) ``` ] --- ## {Cartography} .code70[ ```r # layout layoutLayer(title="Population & Wealth in Martinique, 2015", author = "cartography 2.1.3", sources = "Sources: Insee and IGN, 2018", scale = 5, tabtitle = TRUE, frame = FALSE) # north arrow north(pos = "topleft") ``` ] --- ## {Cartography} .center[![:scale 55%](images/exemple_cartography.png)] source: [cran.r-project.org/web/packages/cartography/vignettes](https://cran.r-project.org/web/packages/cartography/vignettes/cartography.html) --- ## {Tmap} * conçu pour les cartes thématiques * écrit par Martijn Tennekes * philosophie de *A Layered Grammar of Graphics* by Hadley Wickham * sortie plot + JS https://cran.r-project.org/web/packages/tmap/vignettes/tmap-getstarted.html --- ## {Tmap} .code70[ ```r library(tmap) # load spatial data included in the tmap package data("World", "metro") # calculate annual growth rate metro$growth <- (metro$pop2020 - metro$pop2010) / (metro$pop2010 * 10) * 100 # plot tm_shape(World) + tm_polygons("income_grp", palette = "-Blues", title = "Income class", contrast = 0.7, border.col = "gray30", id = "name") + tm_text("iso_a3", size = "AREA", col = "gray30", root=3) + tm_shape(metro) + tm_bubbles("pop2010", col = "growth", border.col = "black", border.alpha = 0.5, breaks = c(-Inf, 0, 2, 4, 6, Inf) , palette = "-RdYlGn", title.size = "Metro population (2010)", title.col = "Annual growth rate (%)", id = "name", popup.vars=c("pop2010", "pop2020", "growth")) + tm_format_World() + tm_style_gray() ``` ] --- ## {Tmap} .center[![:scale 100%](images/tmap_carte.png)] --- ## Tmap .code70[ ```r # view tmap_mode("view") last_map() tmap_mode("plot") ``` ] .center[![:scale 100%](images/tmap-mapview.jfif)] --- ## {Leaflet} * Bibliothèque légère de cartographie * JS .code70[ ```r library(leaflet) long <- 2.346 lat <- 48.8695 ``` ] --- ### {leaflet} .code70[ ```r l <- leaflet() %>% addTiles() %>% setView(long, lat, zoom = 17) l ```
] --- ### {leaflet} .code70[ ```r l %>% addMarkers(long, lat, popup = "AssessFirst", label = "2O rue du Sentier") ```
] --- .code70[ ```r l %>% addRectangles( lng1= 2.345, lat1=48.8698, lng2= 2.347, lat2=48.8691, fillColor = "transparent" ) ```
] --- ## {Mapview} * créé par Tim Appelhans * Cartographie dynamique en javascript * directement intégré à R * une fonction principale: `mapview()` --- ### {Mapview} .code70[ ```r mapview(list(franconia, breweries), zcol = list("district", NULL), legend = list(TRUE, FALSE)) ```
] --- ## {Rayshader} .left-code[ * [Tyler Morgan-Wall](https://www.tylermw.com) * Visualisation de données 3D * Simulation du niveau des eaux (sécheresse, inondations, ) Documentation : [https://www.rayshader.com/](rayshader.com) ] .right-plot[ ![:scale 75%](images/rayshader_logo.png) ] --- # {Rayshader} .code70[ ```r library(rayshader) #Here, I load a map with the raster package. loadzip = tempfile() download.file("https://tylermw.com/data/dem_01.tif.zip", loadzip) localtif = raster::raster(unzip(loadzip, "dem_01.tif")) unlink(loadzip) #And convert it to a matrix: elmat = matrix(raster::extract(localtif,raster::extent(localtif),buffer=1000), nrow=ncol(localtif),ncol=nrow(localtif)) elmat %>% sphere_shade(texture = "desert") %>% add_water(detect_water(elmat), color="desert") %>% add_shadow(ray_shade(elmat,zscale=3,maxsearch = 300),0.5) %>% add_shadow(ambmat,0.5) %>% plot_3d(elmat,zscale=10,fov=0,theta=135,zoom=0.75,phi=45, windowsize = c(1000,800)) render_snapshot() ``` ] --- # {Rayshader} ![:scale 75%](images/smallhobart.gif) (animation non contractuelle) --- class: center, middle # Exception culturelle française --- class: split-two .column[ Dompter le Code Officiel Géographique avec [**COGugaison**](https://antuki.github.io/COGugaison/) et [**CARTElette**](https://github.com/antuki/CARTElette) * Créés par Kim Antune**Z** (@antuki13) * [**COGugaison**](https://antuki.github.io/COGugaison/): manipulation du COG pour les données communales et supracommunales * [**CARTElette**](https://github.com/antuki/CARTElette) : fichiers shapefile correspondants ] .column[ ![:scale 50%](images/cogugaison.png) ![:scale 50%](images/cartelette.png) ] --- ## C'est quoi le COG ? * Code Officiel Géographique * édité par l'INSEE * plusieurs niveaux * 13 régions + 5 DROM * 100 départements * +/- 35000 communes suivant le millésime * +/ 50000 IRIS (Îlots regroupés pour l'information statistique) --- ## C'est quoi le COG ? * permet d'associer une géométrie à des données stats: * [ADMIN EXPRESS - IGN](http://www.professionnels.ign.fr/adminexpress) * Régions * Départements * Arrondissements départementaux * EPCI * Communes * Chef-lieu de commune * [Contours Iris -IGN](http://professionnels.ign.fr/contoursiris) --- ### *COGugaison* et *CARTElette* dans tout ça ? .font80[ * Niveau communal et supra-communal * pas les IRIS * Communes * Arrondissements * EPCI * Bassin de vie * Aires urbaines * Unités urbaines * Départements * Régions * Zone d'emploi * Cantons ] --- .font80[ ### *COGugaison* et *CARTElette* dans tout ça ? * {COGugaison} * détecte le millésime d'un jeu de données * transformation année X -> année Y (Population, Type, etc) * 1968 -> 2019 * {CARTElette} * permet de récupérer les géométries * 2015 -> 2019 * Présentation RLadies 03/2018:] .font70[ [antuki.github.io/slides/180306_RLadies_COGugaison_carto/180306_RLadies_COGugaison_carto.html](https://antuki.github.io/slides/180306_RLadies_COGugaison_carto/180306_RLadies_COGugaison_carto.html) ] --- ### CARTElette ```r library(CARTElette) ZE_sf <- loadMap(COG=2016,nivsupra="ZE2010") par(mar=c(0,0,0,0)) plot(sf::st_geometry(ZE_sf)) ``` ![:scale 100%](images/plot_cartelette.png) --- # {Oceanis} Package de cartographie créé par l'INSEE * Utilise `plot` et {leaflet} * Dispose de fonctions dédiées à {shiny} * CRAN: [cran.r-project.org/web/packages/oceanis](https://cran.r-project.org/web/packages/oceanis/index.html) * Vignette : [https://cran.r-project.org/web/packages/oceanis/vignettes](https://cran.r-project.org/web/packages/oceanis/vignettes/oceanis.html) --- # {Oceanis} ## `plot()` ![:scale 90%](images/oceanis_plot.png) --- # {Oceanis} ## {shiny} + {leaflet} ### ![:scale 100%](images/oceanis_shiny_leaflet.png) --- # Ressources * sites et vignettes des paquets * [Tuto satRday 2019](https://github.com/comeetie/satRday) * [Geocomputation with R](https://geocompr.robinlovelace.net/) - Lovelace, Nowosad, Muenchow * [Manuel d’analyse spatiale](https://www.insee.fr/fr/information/3635442) - INSEE - Octobre 2018 * Formation R au MTES/MCTRCT (à venir) : [mtes-mct.github.io/parcours-r](https://mtes-mct.github.io/parcours-r/) * Observatoire des territoires : [Exemple d'utilisation de COGugaison en production](http://outils.observatoire-des-territoires.gouv.fr/mob_resid/) --- class: title-slide background-image: url("images/Raddicts.png") background-position: 110% 75% background-size: 40% # Données géospatiales et cartographie avec R ### Nicolas Roelandt #### vendredi 28 juin 2019 .white[ .font75[ * Blog : [roelandtn.frama.io](https://roelandtn.frama.io) * Slides : [roelandtn.frama.io/slides/2090628_meetup_Raddict_datageo.html](https://roelandtn.frama.io/slides/2090628_meetup_Raddict_datageo.html) ] .font50[ Slides created with the R package [**xaringan**](https://github.com/yihui/xaringan) and Emi Tanaka's [**ninja theme**](https://github.com/emitanaka/ninja-theme).] ]