Search code examples
rshinyr-leafletr-mapview

Place non-geographic mapview object into Shiny app


Basically my question is how to place either a PNG or a mapview object into a shiny app to enable placement of markers over it.

enter image description here

I have 15 non-geographic floorplan mapview objects like PNG above that were converted to mapview objects using the code below with the assistance of another SO user question here:

library(raster)
library(png)
library(mapview)

ohs<-data.frame(OHS_no=c(1001:1010), x=runif(10, 0, 1), y = runif(10, 0, 0.8), AGE = c(4, 15, 15, 43, 5, 50, 67, 77, 77, 28))
web_img <- "https://i.sstatic.net/8aSe9.png"

png <- readPNG(readBin(web_img, "raw", 1e6))

rst_blue <- raster(png[, , 1])
rst_green <- raster(png[, , 2])
rst_red <- raster(png[, , 3])

img <- brick(rst_red, rst_green, rst_blue)

m <- viewRGB(img)
abs(cbind(rnorm(40), rnorm(40)))
m@map %>% addMarkers(lng = ohs$x, lat = ohs$y)

I am trying to create a Shiny app to put it all together but am stuck at the renderLeaflet command and am not sure how to place my m@map object within the app. Basically the below functionality with the map object as the leaflet.

library(shiny)
library(leaflet)
ohs<-data.frame(OHS_no=c(1001:1010), x=runif(10, 0, 1), y = runif(10, 0, 0.8))
r_colors <- rgb(t(col2rgb(colors()) / 255))
names(r_colors) <- colors()

ui <- fluidPage(
 leafletOutput("mymap"),
 p(),

)

server <- function(input, output, session) {



  output$mymap <- renderLeaflet({
   leaflet() %>%
      addProviderTiles("Stamen.TonerLite",
                       options = providerTileOptions(noWrap = TRUE)
      ) %>%
      addMarkers(lng = ohs$x, lat = ohs$y)
  })
}

shinyApp(ui, server)

Solution

  • This works for me:

    library(shiny)
    library(mapview)
    library(png)
    library(raster)
    
    ohs<-data.frame(OHS_no=c(1001:1010), x=runif(10, 0, 1), y = runif(10, 0, 0.8))
    r_colors <- rgb(t(col2rgb(colors()) / 255))
    names(r_colors) <- colors()
    
    ui <- fluidPage(
      leafletOutput("mymap"),
      p()
    
    )
    
    server <- function(input, output, session) {
      web_img <- "https://i.sstatic.net/8aSe9.png"
    
      png <- readPNG(readBin(web_img, "raw", 1e6))
    
      rst_blue <- raster(png[, , 1])
      rst_green <- raster(png[, , 2])
      rst_red <- raster(png[, , 3])
    
      img <- brick(rst_red, rst_green, rst_blue)
    
      m <- viewRGB(img)
    
      output$mymap <- renderLeaflet({
        m@map %>%
          addMarkers(lng = ohs$x, lat = ohs$y)
      })
    }
    
    shinyApp(ui, server)
    

    Simply replace leaflet() with m@map (which is a leaflet widget object). Given that the raster is not georeferenced, it does not make sense to add provider tiles.