Search code examples
rleafletmappingshapefiletmap

Interactive R Map with Search Functionality


Trying to build a very basic interactive map in R. In general I would like to do the following:

Export a shapefile from ArcGIS -> Plot as interactive map in R -> Search shapefile based on attributes (e.g. Name)

I have been using tmap:

shapefile = st_read("C:/Projects/_SANDBOX/R/Shapefiles/XXX.shp")
map = tm_shape(shapefile)+tm_fill(col="blue",alpha=0.3) +tm_borders(col="black")
tmap_mode("view")
map

But I am stuck at the point of trying to add the search function. Would it be better/easier to do this sort of thing using leaflet in R? If so how would that look?

Any help is greatly appreciated. Thanks!


Solution

  • Like I said in my comment, I'm unaware of a built-in search function in leaflet or tmap, so my first thoughts were to utilise shiny as the searching component and map display.

    This is a pretty basic example, but allows you to select a country to zoom in on from a drop-down list. The selected country is coloured in red in the world map, and is shown in the initial frame/position of the map when opened, using the bbox argument of tm_shape(). The country is separated from the rest of the world using filter(), and saved as my_country; this is used to plot the selected country as the red layer, and also as the zoom position by retrieving it's coordinates using sf::st_bbox().

    library(shiny)
    library(tidyverse)
    library(tmap)
    library(spData)
    library(sf)
    tmap_mode('view')
    
    # Define UI for application that draws a histogram
    ui <- fluidPage(
    
        # Application title
        titlePanel('Search the world'),
    
        # Sidebar with a drop down boxz for country names
        sidebarLayout(
            sidebarPanel(
                selectInput(inputId = 'country',
                            label = 'Country to zoom in on:',
                            choices = world$name_long)
            ),
    
            # Show the map
            mainPanel(
               tmapOutput('map')
            )
        )
    )
    
    # Define server logic required to make the map
    server <- function(input, output) {
        
        # build the map
        output$map <- renderTmap({
    
            my_country <- world %>% 
                filter(
                    name_long == input$country
                )
            
            tm_shape(world, bbox = st_bbox(my_country))+
                tm_polygons()+
                tm_shape(my_country)+
                tm_polygons(col = 'red')
    
        })
        
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)
    

    enter image description here

    Of course you could modify the inputs and outputs as you please. I chose a drop down box because it means you won't misspell a country name; unlike something like Google Maps which might be able to handle misspelt place names, filter() requires the names match exactly.

    Although it's a drop down box, there seems to be some limited search functionality within it; if you delete the name in the box and start typing, matching country names will present themselves:

    enter image description here