Interactive map with location information

Sateesh Nallamothu
March 30th 2017

Application details

The interactive location application does the following.

  • It uses google's geocode service along with leaflets
  • The input can be any place, city, postal code, landmark, address, airport etc. anywhere in the world.
  • The application will dynamically zoom to the place.
  • All markers will be retained until they are cleared
  • Clicking the marker will popup additional information.
  • Rstudio link: https://sknallamothu.shinyapps.io/ddp-shiny

Server Calculations

R functions leaflet(), leafletProxy() and geocode() are the main functions used.

library(ggmap)
std_addr<-function(addr){ 
  geo_reply = geocode(addr, output='all', messaging=TRUE, override_limit=TRUE)
  answer <- data.frame(lat=NA, long=NA, accuracy=NA, formatted_address=NA, address_type=NA, status=NA,
                       zoom=NA,provider='openStreetMap',geomAcc=NA)
  answer$status <- geo_reply$status

  if (geo_reply$status != "OK"){
    return(answer)
  }
  #otherwise, extract what we need from the Google server reply into a dataframe:
  answer$lat <- geo_reply$results[[1]]$geometry$location$lat
  answer$long <- geo_reply$results[[1]]$geometry$location$lng
  answer$geomAcc <-  geo_reply$results[[1]]$geometry$location_type
  if (length(geo_reply$results[[1]]$types) > 0){
    answer$accuracy <- geo_reply$results[[1]]$types[[1]]
  }
  answer$address_type <- paste(geo_reply$results[[1]]$types, collapse=',')
  answer$formatted_address <- geo_reply$results[[1]]$formatted_address
  ## assgin zoom levels based on the location accuracy. 
  zoomdata<-data.frame(accuracy=c('street_address','route','postal_code','locality','sublocality',
                                  'political','administrative_area_level_3','administrative_area_level_2',
                                  'administrative_area_level_1','country','continent','premise','subpremise',
                                  'establishment','park','airport','amusement_park','neighborhood'),
                       zoomlvl=c(18,16,15,13,14,17,12,11,9,5,4,18,18,18,18,18,18,17))
  answer$zoom<-zoomdata$zoomlvl[match(answer$accuracy,zoomdata$accuracy)]
  if (is.na(answer$zoom)) {
    answer$zoom <- 7  ## default zoom
  }
  # assign provider based on the accuracy/zoom level
  if (answer$zoom %in% c(5,4,6)) {
     answer$provider <- 'Esri.WorldGrayCanvas'
  }
  return(answer)
}

Leaflet plot

Sample output of the function.

std_addr("Millennium Park")
       lat      long      accuracy
1 41.88255 -87.62255 establishment
                                           formatted_address
1 Millennium Park, 201 E Randolph St, Chicago, IL 60602, USA
                          address_type status zoom      provider
1 establishment,park,point_of_interest     OK   18 openStreetMap
      geomAcc
1 APPROXIMATE

The leaflet and leafletProxy functions will display the map along with zooming to the marker.

library(leaflet)
library(ggplot2)
library(dplyr)
library(maps)
point<-std_addr('Skylon Tower')
popText<-paste(sep="<br/>",point$formatted_address,
                   paste('Location Type:',point$accuracy,point$geomAcc,sep=' '),
                   'Lat/Long:',paste(sep='/',point$lat,point$long))
    lbl<-point$formatted_address
point%>%leaflet() %>% setView(lat=point$lat,lng=point$long,zoom=point$zoom) %>%
          addMarkers(popup=popText,label=lbl)

Conclusion and Next steps

We can improve this application by adding additional features such as displaying more text about the location and by adding more input controls. The shiny application ui.r and sever.r can be found in

https://github.com/Sateeshnallamothu/ddp-shiny