Search code examples
rshinyleafletrasterr-leaflet

leaflet needs projection for displaying raster


I am trying to create a shiny app that displays raster over a world map. The user will interact with the inputs and the app will generate a raster as well as histogram. The code below generates the histogram but not the map and I wanted help in sorting this out. Here's the data and my progress so far. The error I get is as shown input projection is NA

enter image description here

    library(shiny)
    library(tmap)
    library(tmaptools)
    library(raster)
    library(leaflet)
    library(dplyr)

    coords <- structure(list(cell.lon = c(80, 78.25, 78.75, 72.75, 73, 78.5, 
              72.75, 79.5, 79.25, 78.25), cell.lat = c(15.25, 14.25, 12.75, 
              26.75, 22, 23.5, 25, 22.25, 15.25, 24)), class = c("tbl_df", 
             "tbl", "data.frame"), row.names = c(NA, -10L))

    dat.df <- expand.grid(cell.lon = coords$cell.lon,
                          seasonID = c('winter', 'summer'),
                          business = c('train', 'bus', 'taxi'), 
                          variable = c('modP', 'modT'),
                          YearRef = 2001:2003)

    dat.df1 <- coords %>% dplyr::left_join(dat.df) %>% dplyr::mutate(value = rnorm(n()))


    ui <- fluidPage(

        titlePanel('My shiny'),
        sidebarLayout(position = 'left',
                      sidebarPanel(
                      selectInput(inputId = 'seasonRef', label = 'Select season', choices = c('winter','summer'), selected = 'summer'),
                      selectInput(inputId = 'businessRef', label = 'Select business',
                              choices = c('train','bus','taxi'), selected = 'train'),
                      radioButtons(inputId = 'var', label = NULL, 
                                   choiceNames = c('modP','modT'),
                                   choiceValues = c('modP','modT'),
                                   width = '400px', selected = 'modP'),
                      sliderInput('yearRef','Select Year',min=2001,max=2003,value=1)
                  ),

                  mainPanel(
                    tabsetPanel(
                    tabPanel('Map',leafletOutput("map")),
                    tabPanel('Histogram', plotOutput(outputId = 'hist'))
                ))))


    server <- function(input, output) {

      tempI <- reactive({

        temp <- dat.df1 %>% dplyr::filter(business == input$businessRef & 
                                          seasonID == input$seasonRef & 
                                          YearRef == input$yearRef & 
                                          variable == input$var)
       temp.raster <- rasterFromXYZ(temp[, c('cell.lon','cell.lat','value')])
        })

      output$map <- renderLeaflet({

        leaflet() %>% addTiles() %>% addRasterImage(tempI()) 
        })

        output$hist <- renderPlot({
        hist(tempI())
        })
      }

      shinyApp(ui, server)

Solution

  • As a quick fix, and as your data is in longitude latitude projection you can try to add this to your rasterFromXYZ call:

    rasterFromXYZ(temp[, c('cell.lon','cell.lat','value')], crs = crs('+proj=longlat +datum=WGS84'))
    

    This way your raster will have a proj info available for leaflet to use.

    If you are not using longlat projection, you must adapt the crs call to the one you are using.

    Hope this will help you!