Since January 1, 2021, the French National Institute for Geographic and Forestry Information (IGN) has made its public data on French topography, infrastructure, and terrain freely available. The opening of IGN data under the Etalab 2.0 open license means free access and use for all.
Among the important data that are now open, we can mention the BD TOPO (3D modeling of the territory and its infrastructures), the BD ORTHO (departmental orthophotography), the BD Forêt and the RGE Alti (meshed digital terrain model that describes the French relief). This represents 100 terabytes of data.
To facilitate access to this data, IGN has implemented a set of APIs based on OGC standards. In other words, it is possible with correctly formatted URLs to access IGN data. In spite of a well supplied documentation, the use of APIs remains complex to set up. The happign
package has been created to facilitate this, so let’s get started.
You can install the released version of happign from CRAN with:
install.packages("happign")
And the development version from GitHub with:
# install.packages("devtools")
::install_github("paul-carteron/happign") devtools
We can load the happign
package, and some additional packages we will need while we are here.
library(happign)
library(sf)
library(tmap)
happign
use two data type from IGN web service :
More detailed information are available here for WMS and here for WFS.
To download data you need :
The layer name and API key can be directly retrieved on the IGN website in the expert web services (I recommend you at this point to go and have a look).
For example, if I take the first category “Administratif”, I see that the API key is “administratif” and the first layer name in WFS format is “ADMINEXPRESS-COG.LATEST:arrondissement”
With happign
, there is no need to go through the website because all api keys are available by running the function get_apikeys()
.
get_apikeys()
#> [1] "administratif" "adresse" "agriculture" "altimetrie"
#> [5] "cartes" "cartovecto" "clc" "economie"
#> [9] "environnement" "geodesie" "lambert93" "ortho"
#> [13] "orthohisto" "parcellaire" "satellite" "sol"
#> [17] "topographie" "transports"
After choosing the API key containing our resource, you can access all layer names with get_layers_metadata()
.
Rq :
<- get_apikeys()[1]
apikey get_layers_metadata(apikey = apikey, data_type = "wfs")
#> # A tibble: 36 x 4
#> keywords name abstract defaultcrs
#> <chr> <chr> <chr> <chr>
#> 1 Unités administratives ADMINEXPRESS-COG-CARTO.LATEST:ar~ édition ~ EPSG::4326
#> 2 Unités administratives ADMINEXPRESS-COG-CARTO.LATEST:ar~ édition ~ EPSG::4326
#> 3 Unités administratives ADMINEXPRESS-COG-CARTO.LATEST:ca~ édition ~ EPSG::4326
#> 4 Unités administratives ADMINEXPRESS-COG-CARTO.LATEST:ch~ édition ~ EPSG::4326
#> 5 Unités administratives ADMINEXPRESS-COG-CARTO.LATEST:ch~ édition ~ EPSG::4326
#> 6 Unités administratives ADMINEXPRESS-COG-CARTO.LATEST:ch~ édition ~ EPSG::4326
#> 7 Unités administratives ADMINEXPRESS-COG-CARTO.LATEST:co~ édition ~ EPSG::4326
#> 8 Unités administratives ADMINEXPRESS-COG-CARTO.LATEST:co~ édition ~ EPSG::4326
#> 9 Unités administratives ADMINEXPRESS-COG-CARTO.LATEST:co~ édition ~ EPSG::4326
#> 10 Unités administratives ADMINEXPRESS-COG-CARTO.LATEST:de~ édition ~ EPSG::4326
#> # ... with 26 more rows
For the example we will look at the beautiful town of Penmarch in France and we are going to get these borders.
The get_wfs()
function connects to WFS service of the IGN that contain borders of the communes. It is also necessary to take a point inside penmarch so that the function detects all the shape that intersect this point.
<- st_sfc(st_point(c(-4.370, 47.800)), crs = 4326)
penmarch_point <- get_wfs(shape = penmarch_point,
penmarch_borders apikey = "administratif",
layer_name = "LIMITES_ADMINISTRATIVES_EXPRESS.LATEST:commune")
#> Request 1/1 downloading...
# Checking result
tm_shape(penmarch_borders) + # Borders of penmarch
tm_polygons(alpha = 0, lwd = 2) +
tm_shape(penmarch_point) + # Point use to retrieve data
tm_dots(col = "red", size = 2) +
tm_add_legend(type = "symbol", label = "lat : -4.370, long : 47.800",
col = "red", size = 1) +
tm_layout(main.title = "Penmarch borders from IGN",
main.title.position = "center",
legend.position = c("right", "bottom"),
frame = FALSE)
It’s as simple as that! Now you have to rely on your curiosity to explore the multiple possibilities that IGN offers. For example, who has never wondered how many road junctions there are in Penmarch?
Spoiler : there are 220 of them
<- get_wfs(shape = penmarch_borders,
dikes apikey = get_apikeys()[6],
layer_name = "BDCARTO_BDD_WLD_WGS84G:noeud_routier")
#> Request 1/1 downloading...
# Checking result
tm_shape(penmarch_borders) + # Borders of penmarch
tm_polygons(alpha = 0, lwd = 2) +
tm_shape(dikes) + # Point use to retrieve data
tm_dots(col = "red") +
tm_add_legend(type = "symbol", label = "Road junction", col = "red") +
tm_layout(main.title = "Road nodes recorded by the IGN in Penmarch",
main.title.position = "center",
legend.position = c("right", "bottom"),
frame = FALSE)
For raster, the process is the same but with the function get_wms_raster()
. There’s plenty of elevation resources inside “altimetrie” category. The basic one is the Digital Elevation Model (DEM or MNT in French).
Rq :
get_wms_raster()
are stars object from the stars
package. To learn more about conversion between other raster type in R go check this out.<- get_apikeys()[4]
apikey <- get_layers_metadata("altimetrie", "wms")
layers_metadata <- layers_metadata[2, "name"]
dem_layer_name
<- get_wms_raster(shape = penmarch_borders,
mnt apikey = apikey,
layer_name = dem_layer_name,
resolution = 25)
#> x cell_size : 24.873 [m]
#> y cell_size : 24.937 [m]
< 0] <- NA # remove negative values in case of singularity
mnt[mnt names(mnt) <- "Elevation [m]" # Rename raster ie the title legend
tm_shape(mnt) +
tm_raster(colorNA = NULL) +
tm_layout(title = "DEM of Penmarch", frame = FALSE)