Search code examples
rshinyr-leaflet

Changed from readOGR to read_sf and shiny leaflet popups broke


UPDATE: Added code fixes and comments below and my popup is working...

Shiny beginner here and I've got a slow shiny leaflet app, so I've been using profvis to find the bottlenecks. Using readOGR to load in shapefile data is the major issue. So I've made one change--using read_sf--and things are much, much faster. All of my points and polygons are showing up fine, however my popups don't work now and I'm at a loss as to what could be going on.

Expected result: changing from readOGR to read_sf wouldn't make any difference in populating the popup with data.

Result: the labels are working fine, but the pop-ups aren't showing up at all.

Here's a stripped down version of the app.

ui <- fluidPage(
  
  fluidRow(
 
    
    column(3,
           "",
           
           tags$head(
             tags$style(type='text/css', 
                        ".nav-tabs {font-size: 10px} ")),
            tabsetPanel(id='lefttabsetPanel',selected='placestab',
                       
                       tabPanel(value="placestab",title='PLACES',
                                tags$iframe(name="myiframe2",seamless="seamless",src="http://45.56.98.26:8080/exist/rest/db/madrid/xml/tds-placeography.xml",style='height:95vh; width:25vw')
                       )
   ))
   ,
    column(9,
           "",
          
    
  tabsetPanel(id='my_tabsetPanel',
              tabPanel('Global Map',
                      
                       withSpinner(leafletOutput(outputId="mymap",height = "95vh"),color="#cd0000",type = 5)
              )
              
  )
)
  )
)
server <- function(input,output, session){


# Core wrapping function
  wrap.it <- function(x, len)
  { 
    sapply(x, function(y) paste(strwrap(y, len), 
                                collapse = "\n"), 
           USE.NAMES = FALSE)
  }

 
### MAP 1
  output$mymap <- renderLeaflet({
    m <- leaflet() %>% 
      addMapPane("toplayer", zIndex=420) %>% addMapPane("layer2",zIndex=410)%>%
      setView(lng=-3.6898447, lat=40.4142174, zoom=3 ) %>%
addTiles(options = providerTileOptions(noWrap = TRUE), group="Open") %>% 
      
    addCircleMarkers(data = placeography,options = pathOptions(pane = "toplayer"),label=placeography$placename, fillColor="white",stroke = 2, weight=3, color="black",fillOpacity = 1,opacity=1,radius =3,group = "Puntos de interés",

# THIS IS WHAT'S BREAKING WITH read_sf

                     popup = mapply(function(x, y) {
                       HTML(sprintf("<div class='leaflet-popup-scrolled' style='font-size:10px;max-width:200px;max-height:150px; '><b><a href='http://45.56.98.26:8080/exist/rest/db/madrid/xml/tds-placeography.xml#%s' target='myiframe2'>%s</a></b></div>", htmlEscape(x), y))},
                       placeography$placeref,placeography$placename,  SIMPLIFY = F))%>%
      
      addLayersControl(baseGroups = c("Open"), overlayGroups = c("Puntos de interés"),position = c("topright"),options = layersControlOptions(collapsed = FALSE))
    
  })
  }
library(shiny)
library(leaflet)
library(rgdal)
library(htmltools)
library(tigris)
library(data.table) 
library(rmapshaper)
library(shinycssloaders)
library(sf)



#POPUPS WORKED FINE WITH READOGR
#placeography <- readOGR("shapefiles/places_points.shp")

#POPUPS NOT WORKING WITH READ_SF
#placeography <- read_sf("shapefiles/places_points.shp",quiet=TRUE)

#MOST POPUPS WORKING WITH THIS READ_SF
placeography <- read_sf("shapefiles/places_points.shp",quiet=TRUE, as_tibble = FALSE,stringsAsFactors=TRUE)

The shapefiles (places_points) are here: http://45.56.98.26/shapefiles/

UPDATE: I was able to halfway solve this problem (and it works for the example above) by "using stringsAsFactors = TRUE":

placeography <- read_sf("shapefiles/places_points.shp",quiet=TRUE,as_tibble = FALSE,stringsAsFactors = TRUE)

Unfortunately, one of my labels (not included in the example above--see below) also uses a geojoin--it required an extra step to fix:

placeographyareas<-read_sf("shapefiles/places_areas.shp",quiet=TRUE,as_tibble = FALSE,stringsAsFactors = FALSE)

histpeople<- read.csv("http://45.56.98.26/tds-data/readingmadrid-people-places-hist.csv",header=TRUE,stringsAsFactors = FALSE)

placeographyareashistpeople<-  geo_join(placeographyareas,histpeople,"placeref","placeref", how = "left")

#FIX: CONVERT TO FACTOR AFTER JOIN
placeographyareashistpeople$placeref <- as.factor(placeographyareashistpeople$placeref)

I'm getting this warning on the geojoin:

Warning: Column placeref joining factor and character vector, coercing into character vector

And my popup doesn't show up. Changing "stringsAsFactors=TRUE" for histpeople doesn't work, either. Still hoping to better understand the differences between sf_read and readOGR, so I can troubleshoot this issue better.


Solution

  • Just in case anyone else ever encounters this sort of problem when switching from readOGR to read_sf.... I bumbled into a solution to this popup issue through the process of elimination and updated the question above with comments to explain where I made the changes.

    For most of my popups, just adding "stringsAsFactors = TRUE" to read_sf sorted out the issue (the default for read_sf is the opposite of readOGR). In the case of my more complex popup that was the product of a further geojoin, I needed to change the placeref column back to a factor after the join:

    as.factor(placeographyareashistpeople$placeref).

    See above for working code.