Simplifying polygons layers

[This article was first published on, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here) Want to share your content on R-bloggers? click here if you have a blog, or here if you don’t.

The current 2021 french administrative limits database (Adminexpress from IGN) is more detailed than the original version (from 50 MB zipped in 2017 to 500 MB zipped now), thanks to a more detailed geometry being currently based on the BDTOPO. However we don’t always need large scale details especially for web applications. The commune layer itself is a huge 400 MB shapefile not really usable for example in a small scale leaflet map.

Using sf::st_simplify() in R or a similar command in QGIS on these shapefiles would create holes or overlapping polygons, shapefiles not being topologically aware. We could probably convert to lines, build topology, simplify, clean, build polygons in GRASS or ArcGis, but it’s quite a hassle…

A nice solution is using Mapshaper on, or better for reproducibility using {mapshaper} in R. For such large dataset it is advised to use a node.js install instead of relying on the package’s embedded version.

in red the original, in black the simplified version with départements in bold

On Debian-like :

> sudo apt-get install nodejs npm

or on windows : install If needed add C:\Users\xxxxxxxx\AppData\Roaming\npm to your $PATH.

> npm config set proxy "http://login:password@proxy:8080" # if necessary
> npm install -g mapshaper

For ms_simplify() we will set sys = TRUE to take advantage of the node.js executable. Experiment with the other parameters to get a resolution that suits you. Here we use Visvalingam at 3%, squeezing the commune layer from 400 MB to 30 MB. From here we rebuild departement, region and epci with ms_dissolve() commands. Then we join back with original attributes and export in a geopackage with some metadata.

library(fs) # ADMIN EXPRESS COG France entière édition 2021 (in WGS84)
# also available on :
# # originals --------------------------------------------------------------- source_ign <- "~/sig/ADMINEXPRESS/ADMIN-EXPRESS-COG_3-0__SHP__FRA_2021-05-19/ADMIN-EXPRESS-COG/1_DONNEES_LIVRAISON_2021-05-19/ADECOG_3-0_SHP_WGS84G_FRA" com <- source_ign %>% path("COMMUNE.shp") %>% read_sf() %>% clean_names() dep <- source_ign %>% path("DEPARTEMENT.shp") %>% read_sf() %>% clean_names() reg <- source_ign %>% path("REGION.SHP") %>% read_sf() %>% clean_names() epci <- source_ign %>% path("EPCI.shp") %>% read_sf() %>% clean_names() # simplify --------------------------------------------------------------- check_sys_mapshaper() # 6 min
# using a conversion to geojson_json to avoid encoding problems
com_simpl <- com %>% geojson_json(lat = "lat", lon = "long", group = "INSEE_COM", geometry = "polygon", precision = 6) %>% ms_simplify(keep = 0.03, method = "vis", keep_shapes = TRUE, sys = TRUE) dep_simpl <- com_simpl %>% ms_dissolve(field = "insee_dep", sys = TRUE) reg_simpl <- com_simpl %>% ms_dissolve(field = "insee_reg", sys = TRUE) epci_simpl <- com_simpl %>% ms_dissolve(field = "siren_epci", sys = TRUE) # add attributes and export ---------------------------------------------- destination <- "~/donnees/ign/adminexpress_simpl.gpkg" com_simpl %>% geojson_sf() %>% st_write(destination, layer = "commune", layer_options = c("IDENTIFIER=Communes Adminexpress 2021 simplifiées", "DESCRIPTION=France WGS84 version COG (2021-05). Simplification mapshaper.")) dep_simpl %>% geojson_sf() %>% left_join(st_drop_geometry(dep), by = "insee_dep") %>% st_write(destination, layer = "departement", layer_options = c("IDENTIFIER=Départements Adminexpress 2021 simplifiés", "DESCRIPTION=France WGS84 version COG (2021-05). Simplification mapshaper.")) reg_simpl %>% geojson_sf() %>% left_join(st_drop_geometry(reg), by = "insee_reg") %>% st_write(destination, layer = "region", layer_options = c("IDENTIFIER=Régions Adminexpress 2021 simplifiées", "DESCRIPTION=France WGS84 version COG (2021-05). Simplification mapshaper.")) epci_simpl %>% geojson_sf() %>% mutate(siren_epci = str_remove(siren_epci, "200054781/")) %>% # remove Grand Paris left_join(st_drop_geometry(epci), by = c("siren_epci" = "code_siren")) %>% st_write(destination, layer = "epci", layer_options = c("IDENTIFIER=EPCI Adminexpress 2021 simplifiés", "DESCRIPTION=Établissement public de coopération intercommunale France WGS84 version COG (2021-05). Simplification mapshaper.")) 
To leave a comment for the author, please follow the link and comment on their blog: offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you’re looking to post or find an R/data-science job. Want to share your content on R-bloggers? click here if you have a blog, or here if you don’t.

Continue reading: Simplifying polygons layers Source

11 thoughts on “Simplifying polygons layers”

  1. Hello There. I found your weblog the usage
    of msn. This is a really well written article.
    I’ll make sure to bookmark it and return to read extra of your helpful information. Thank you for the post.
    I’ll definitely comeback.

  2. I have learn some just right stuff here.

    Certainly price bookmarking for revisiting. I wonder how a
    lot attempt you put to create this type of great informative website.

  3. Hey! I could have sworn I’ve been to this blog
    before but after reading through some of the post I realized it’s new to me.
    Nonetheless, I’m definitely glad I found it and I’ll be book-marking and checking back often!

  4. When someone writes an post he/she keeps the thought
    of a user in his/her brain that how a user can understand it.
    Therefore that’s why this post is perfect. Thanks!

  5. Undeniably believe that that you stated. Your favourite reason appeared to be at the internet the easiest thing to be aware of.
    I say to you, I definitely get annoyed while folks think about concerns that they just don’t know about.
    You controlled to hit the nail upon the top as neatly as defined out the entire thing
    with no need side effect , other people can take a signal.
    Will probably be again to get more. Thank you

  6. Hi, i think that i saw you visited my website so i came to “return the favor”.I’m trying to find things
    to improve my web site!I suppose its ok to use some of your ideas!!

  7. Good day! I know this is kinda off topic nevertheless I’d figured
    I’d ask. Would you be interested in exchanging links or maybe guest writing a
    blog article or vice-versa? My site covers a lot of the same topics as yours and I think we could greatly benefit from each other.

    If you’re interested feel free to send me an email. I look
    forward to hearing from you! Great blog by the way!

Leave a Reply

Your email address will not be published. Required fields are marked *