TransWikia.com

Reducing number of polygons in a shapefile to increase the render speed for R Leaflet?

Geographic Information Systems Asked by dlopez on December 7, 2020

I’m trying to increase the speed of my R Leaflet map by reducing the size of the polygons.

I found a great solution on stack exchange here, but for some reason, I get the following error when I try to plot the shapes. “Error in pgons@Polygons[[index]] : subscript out of bounds”

I’m guessing the issue stems from the getSmallPolys function, but I don’t know how to fix it. If this would work, it would increase the speed of my Leaflet map a lot.

library(sp)
library(rgeos)
library(raster)
library(leaflet)
library(readr)
# Source of getSmallPolys function: "https://gis.stackexchange.com/questions/62292/how-to-speed-up-the-plotting-of-polygons-in-r"

# Get the main polygons, will determine by area.
getSmallPolys <- function(poly, minarea=0.01) {
  # Get the areas
  areas <- lapply(poly@polygons, 
                  function(x) sapply(x@Polygons, function(y) y@area))

  # Quick summary of the areas
  print(quantile(unlist(areas)))

  # Which are the big polygons?
  bigpolys <- lapply(areas, function(x) which(x > minarea))
  length(unlist(bigpolys))

  # Get only the big polygons and extract them
  for(i in 1:length(bigpolys)){
    if(length(bigpolys[[i]]) >= 1 && bigpolys[[i]] >= 1){
      poly@polygons[[i]]@Polygons <- poly@polygons[[i]]@Polygons[bigpolys[[i]]]
      poly@polygons[[i]]@plotOrder <- 1:length(poly@polygons[[i]]@Polygons)
    }
  }
  return(poly)
}

AUS <- getData("GADM", country = "AUS", level = 1)
CAN <- getData("GADM", country = "CAN", level = 1)
USA <- getData("GADM", country = "USA", level = 1)
GBR <- getData("GADM", country = "GBR", level = 1)
shape <- 
  rbind(AUS, CAN, USA, GBR)

# From 195 mb to 78.7 mb (32.1 mb if filtered)
shapesSimple <-
  gSimplify(shape, tol=0.1, topologyPreserve=TRUE) %>%
  SpatialPolygonsDataFrame(., data = shape@data)

# This would be ideal for render speed but I get an error when I try to plot it
# From 195 mb to 1.9 mb (1 mb if filtered)
shapesSimple <-
  gSimplify(shape, tol=0.1, topologyPreserve=TRUE) %>%
  getSmallPolys() %>%
  SpatialPolygonsDataFrame(., data = shape@data)

# Testing the speed
start_time <- Sys.time()
leaflet() %>% 
  addTiles() %>% 
  addPolygons(data = shapesSimple)
end_time <- Sys.time()
end_time - start_time

One Answer

So I found a better solution with less code. All I had to do was use the ms_simplify function from the rmapshaper package after using the gSimplify function. The shapes load super fast now.

library(sp)
library(rgeos)
library(readr)
library(raster)
library(leaflet)
library(rmapshaper)

AUS <- getData("GADM", country = "AUS", level = 1)
CAN <- getData("GADM", country = "CAN", level = 1)
USA <- getData("GADM", country = "USA", level = 1)
GBR <- getData("GADM", country = "GBR", level = 1)

shape <- 
  rbind(AUS, CAN, USA, GBR)
shape <- 
  subset(shape, NAME_1 %in% unique(final$stateName))

# From 195 mb to 1.1 mb
# This is so much faster!
shapesSimple <-
  gSimplify(shape, tol=0.1, topologyPreserve=TRUE) %>% 
  SpatialPolygonsDataFrame(., data = shape@data) %>% 
  ms_simplify()

Answered by dlopez on December 7, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP