Skip to contents

Read simple features from IGN Web Feature Service (WFS). Three minimal info are needed : a location, an apikey and the name of layer. You can find those information from IGN website


get_wfs(x = NULL,
        apikey = NULL,
        layer = NULL,
        filename = NULL,
        spatial_filter = "bbox",
        ecql_filter = NULL,
        overwrite = FALSE,
        interactive = FALSE)



Object of class sf or sfc. Needs to be located in France.


character; API key from get_apikeys() or directly from IGN website


character; name of the layer from get_layers_metadata(apikey, "wfs") or directly from IGN website


Either a character string naming a file or a connection open for writing. (ex : "test.shp" or "~/test.shp")


character; spatial predicate from ECQL language. See detail and examples for more info.


character; corresponding to an ECQL query. See detail and examples for more info.


logical; if TRUE, file is overwrite.


character; if TRUE, no need to specify apikey and layer, you'll be ask.


sf object from sf package or NULL if no data.


  • get_wfs use ECQL language : a query language created by the OpenGeospatial Consortium. It provide multiple spatial filter : "intersects", "disjoint", "contains", "within", "touches", "crosses", "overlaps", "equals", "relate", "beyond", "dwithin". For "relate", "beyond", "dwithin", argument can be provide using vector like : spatial_filter = c("dwithin", distance, units). More info about ECQL language here. Be aware that "dwithin" is broken and it doesn't accept units properly. Only degrees can be used. To avoid this, create a buffer and then use "within" instead od "dwithin".

  • ECQL query can be provided to ecql_filter. This allows direct query of the IGN's WFS geoservers. If x is set, then the ecql_filter comes in addition to the spatial_filter. More info for writing ECQL here


if (FALSE) {

# Shape from the best town in France
penmarch <- read_sf(system.file("extdata/penmarch.shp", package = "happign"))

# For quick testing, use interactive = TRUE
shape <- get_wfs(x = penmarch,
                 interactive = TRUE)

# For specific use, choose apikey with get_apikey() and layer with get_layers_metadata()
## Getting borders of best town in France
apikey <- get_apikeys()[1]
metadata_table <- get_layers_metadata(apikey, "wfs")
layer <- metadata_table[32,1] # LIMITES_ADMINISTRATIVES_EXPRESS.LATEST:commune

# Downloading borders
borders <- get_wfs(penmarch, apikey, layer)

# Plotting result
qtm(borders, fill = NULL, borders = "firebrick") # easy map

# Get forest_area of the best town in France
forest_area <- get_wfs(x = borders,
                       apikey = "environnement",
                       layer = "LANDCOVER.FORESTINVENTORY.V1:resu_bdv1_shape")

qtm(forest_area, fill = "libelle")

# Using ECQL filters to query IGN server
## First find attributes of the layer
attrs <- get_wfs_attributes(apikey, layer)

## e.g. : find all commune's name starting by "plou"
plou_borders <- get_wfs(x = NULL, # When x is NULL, all France is query
                        apikey = "administratif",
                        layer = "LIMITES_ADMINISTRATIVES_EXPRESS.LATEST:commune",
                        ecql_filter = "nom_m LIKE 'PLOU%'")

## Combining ecql_filters
plou_borders_inf_2000 <- get_wfs(x = NULL, # When x is NULL, all France is query
                                 apikey = "administratif",
                                 layer = "LIMITES_ADMINISTRATIVES_EXPRESS.LATEST:commune",
                                 ecql_filter = "nom_m LIKE 'PLOU%' AND population < 2000")
qtm(plou_borders)+ qtm(plou_borders_inf_2000, fill = "red")