7

I have a large shapefile. For a better perfomance I try to load data with st_read() from sf package. The official documentation states that it should be very easy to integrate the shapefile into Leaflet/Shiny. Nevertheless, it does not work.

Error message: missing value where TRUE/FALSE needed

It works with rgdal, but the performance is not that good. Link

I hope that someone can help me out.

small TestData

library(shiny)
library(leaflet)
library(sf)

shapefile <- st_read("pathToshape")

shinyApp(
  ui <-fluidRow(
    column(8,leafletOutput("map", height="600px"))
  ),

server <- function(input, output, session) {
  output$map <- renderLeaflet({
    leaflet() %>% 
      addTiles() %>% 
      setView(lng=16.357795000076294, lat=48.194883921677935, zoom = 15) %>%
      addPolylines(data=shapefile, layerId = shapefile$id, group = shapefile$zeitver, color="red", weight=3,opacity=1)
  })
})
2
  • You haven't actually explained what your performance problem is. Does it take forever to start? Is the web browser slow and clunky? How "large" is your shapefile, and in what dimension - lots of features, lots of attributes, lots of detail? Maybe you can generalise your features?
    – Spacedman
    Commented Sep 1, 2017 at 6:40
  • The shapefile ist about 5mb. It takes about 8sec to read into a variable..that's too long. (I have simplified the shapefile as far as possible. For example: number of columns..simplify geometry is not an option yet) I have therefore read that one can read with st_read () shapefiles twice as fast. But as you explained, you can't handle sf objects within Leaflet(). The perfomance in leaflet is actually quite good. Commented Sep 1, 2017 at 7:07

2 Answers 2

8

Your test data is a dead link now, but I had a similar issue trying to plot sf linestrings and polygons in leaflet. The full error was

Error in if (length(nms) != n || any(nms == "")) stop("'options' must be a fully named list, or have no names (NULL)") : 
missing value where TRUE/FALSE needed

I was able to successfully plot my geometries by dropping the Z dimension from the line and polygon with st_zm. Here is an example:

library(sf)
library(leaflet)

# create sf linestring with XYZM dimensions 
badLine <- st_sfc(st_linestring(matrix(1:32, 8)), st_linestring(matrix(1:8, 2)))

# check metadata for badLine
> head(badLine)

Geometry set for 2 features 
    geometry type:  LINESTRING
    dimension:      XYZM
    bbox:           xmin: 1 ymin: 3 xmax: 8 ymax: 16
    epsg (SRID):    NA
    proj4string:    NA
    LINESTRING ZM (1 9 17 25, 2 10 18 26, 3 11 19 2...
    LINESTRING ZM (1 3 5 7, 2 4 6 8)

# attempt map; will fail
> leaflet() %>%
+   addTiles() %>%
+   addPolygons(data = badLine)

Error in if (length(nms) != n || any(nms == "")) stop("'options' must be a fully named list, or have no names (NULL)") : 
  missing value where TRUE/FALSE needed

# try again!

# drop Z and M dimensions from badLine
goodLine <- st_zm(badLine, drop = T, what = "ZM")

# map; will plot successfully!
leaflet() %>%
  addTiles() %>%
  addPolygons(data = goodLine)
1

Loading the data with st_read creates sf objects, very different things from loading with readOGR or shapefile or readShapePoly, which produce sp objects. addPolylines currently only supports sp objects.

Even if it did support sf objects it probably wouldn't speed your application up much, since leaflet needs everything in geoJSON format. You may have hit a scaling limit of the shiny-leaflet system and need to rethink your application.

1
  • Thank you for your explanation! And what about using mapview() inside renderLeaflet() for sf objects? It will probably have no influence on the speed..am I right? Commented Sep 1, 2017 at 5:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.