0

The application I created allows me to import a polygon shapefile into my Leaflet map. However, I would like to set up a point shapefile import on the same button. I tried several attempts, especially with "addCircles". One or the other works, but not both at the same time. How could I go about it? Here is my code:

ui.R

shinyUI(
      dashboardPage(

    #bandeau principal
    dashboardHeader(title ="Sen2extract"),

    #menu a gauche
    sidebar <- dashboardSidebar(
      sidebarMenu(
          #Les differents widgets du menu
        menuItem("Carte", tabName= "carte", icon = icon("globe")),
          fileInput(inputId = "shp", label = "Importer un shape :", multiple = TRUE, accept = c('.shp', '.dbf','.sbn', '.sbx', '.shx', '.prj')),
          actionButton(inputId ="reset", label = "", icon = icon("trash-alt")),
          selectInput(inputId ="dataset", label ="Choisir un indice :", choices = c("NDVI", "NDWI GAO", "NDWI MCF", "MNDWI")),
          br(),
          dateRangeInput(inputId ="dates", label = "Selectionner les dates :", start = "2019-01-01"),
          submitButton("Rechercher", icon("cog", lib = "glyphicon")),
          downloadButton("downloadData", label = "Exporter en CSV"),
          br(),br(),
        menuItem("A propos", tabName = "about", icon = icon("list-alt")),
        menuItem("FAQ", tabName = "faq", icon = icon("question-sign",lib= "glyphicon"))
      )
    ),

    #contenu de l'application
    dashboardBody(
      tabItems(
        tabItem(tabName ="carte",leafletOutput(outputId = "map", width="100%",height = "1100")),
        tabItem(tabName ="about",h1("Bienvenue sur l'application sen2extract !"),
                p("Cet outils permet l'extraction de series temporelles des indices spectraux sur differents sites d'etudes.")),
        tabItem(tabName ="faq", h1("F.A.Q"), h3("Mon shape ne s'importe pas, comment faire ?"),
                p("Referez-vous aux indications de l'onglet Description"),
                h3("L'extraction de ma serie temporelle est anormalement longue, est-ce normal ?"),
                p("Il est possible que l'extraction prenne du temps. Cela va dependre du nombre de polygones en entree, ainsi que de la plage temporelle configuree"))
      )
    )
  )
)

server.R :

library(shiny)
library(shinydashboard)
library(leaflet)
library(rgdal)
library(utf8)
library(sf)
library(rgeos)
library(sp)

shinyServer(function(input, output, session){


  # create reactive upload file function to store data
  uploadShpfile <- reactive({
    if (!is.null(input$shp)) {
      shpDF <- input$shp
      pwd <- getwd()
      updir <- dirname(shpDF$datapath[1])
      setwd(updir)
      for (i in 1:nrow(shpDF)) {
        file.rename(shpDF$datapath[i], shpDF$name[i])
      }
      shpName <- shpDF$name[grep(x = shpDF$name, pattern = "*.shp")]
      shpPath <- paste(updir, shpName, sep = "/")
      setwd(pwd)
      shpFile <- readOGR(shpPath)
      shpFile <- spTransform(shpFile,CRS("+proj=longlat +datum=NAD83 +no_defs +ellps=GRS80 +towgs84=0,0,0"))
    }
  })

  output$map <- renderLeaflet({

    leaflet() %>%
      addProviderTiles("Esri.WorldImagery", group = "Esri World Imagery", options = providerTileOptions(minZoom = 2, maxZoom = 17)) %>%
      addTiles(group = "OSM", options = providerTileOptions(minZoom = 2, maxZoom = 17)) %>%
      addMiniMap(toggleDisplay = T) %>%
      setView(lng = 97.963,lat = 20.380, zoom = 6 ) %>%
      addLayersControl(baseGroups = c("Esri World Imagery", "OSM"))
  })

  observeEvent(input$shp, {
    if (!is.null(uploadShpfile())) {
      cent <- gCentroid(spgeom = uploadShpfile(), byid = FALSE)
      leafletProxy("map") %>%
        addCircleMarkers(data = uploadShpfile()) 
        addPolygons(data = uploadShpfile()) %>%
        setView(lat = slot(cent, "coords")[[2]], lng = slot(cent, "coords")[[1]], zoom = 7)
    }
  })
})
  • The server.R you posted is never going to work not least because there's no pipe between the addCircleMarkers and addPolygons lines. – Spacedman May 23 at 15:49
  • With a pipe, i have this error message : Warning: Error in polygonData.default: Don't know how to get path data from object of class SpatialPointsDataFrame. I tried to import your code below, but it doesn't work too. I'm a R rookie – Grits May 24 at 5:28
0

You need to test the geometry type of your uploaded shapefile and then use a different add method depending on it.

You are reading in sp class spatial objects with readOGR, so use inherits with the spatial class to see if it is polygons, lines, points or something else.

Here's a non-tested outline

 data = uploadShpfile()
 map = leafletProxy("map")
 if(inherits(data, "SpatialPoints")){
   map = map %>% addCircleMarkers(data)
 }
 if(inherits(data, "SpatialPolygons")){
   map = map %>% addPolygons(data)
 }

 map = map  %>%
        setView(lat = slot(cent, "coords")[[2]], lng = slot(cent, "coords")[[1]], zoom = 7)
 map

Now I'm not sure if that works inside a shiny observeEvent expression (because I'm never sure when things get evaluated here) but that shows the logic - test the object's geometry type, do one thing or the other in your leaflet map construction, breaking it down into parts rather than sticking it into one pipe expression.

This code would probably be clearer without any pipe expressions at this point.

  • With a observeEvent, i received this error message when i try to upload a shapefile : Warning: Error in derivePolygons: addPolygons must be called with both lng and lat, or with neither. – Grits May 23 at 7:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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