1

In R, if i draw a shape on a map using leaflet, it will create a circle with a radius I specify.

data <- data.frame(location = "George Bush International Airport",
                   lat = 29.990665933195277,
                   long = -95.33663249561174,
                   radius =48280.3 )

#map it
leaflet(data, height = 1000, width = 1000) %>%
  addTiles() %>% addCircles(data = data, lng = ~data$long, lat = ~data$lat, weight = 1,
    radius = ~data$radius) %>% 
  leaflet.extras::addSearchOSM(options = searchOptions(collapsed = FALSE))

enter image description here

Instead of the shape being a simple circle with a radius I specify, is it possible to draw a shape that represents 30 miles driving in any direction? Like this image below (screen shot taken from smappen.com but i have to pay to use it and export everything) enter image description here

Id be open to doing this anywhere for free, not just R.

  • Those polygons are usually referred to as isodistances. Are you looking for a free service that would generate those for you or a way to generate those yourself? For the latter, do you already have road network data? Are we talking about just few polygons for pre-defined locations or will there be hundreds or thousands of such requests per day? What about the delay, is 1s / 10s / 30s wait time acceptable? – margusl Jul 13 '23 at 10:13
  • Very similar to this question, and its answers might help you: https://stackoverflow.com/questions/51047722/find-locations-with-the-same-travel-time-to-a-destination-heatmap-contours-base/51094785#51094785 – Nicolás Velasquez Jul 13 '23 at 16:31
  • @margusl I am open to any application that will do it. I like R, and i map in it with leaflet frequently, but i dont really care. It just needs to be shareable. I only have 3-5 areas i need to create once, and im not worried about the delay at all. – Jacob Nordstrom Jul 13 '23 at 17:11

2 Answers2

2

Those shapes are usually referred to as isodistances. osrm package provides easy to use interface for OSRM routing service and comes with osrmIsodistance() function that returns sf object (a dataframe with support for geometries) with a multipolygon. sf is well-supported by Leaflet , so we can just add it as a polygon layer. For convenience, we'll also store source locations in sf object.

By default osrm uses an OSRM demo server which is not really suitable for heavy traffic and high request rate ( usage policy ), though it should be fine for generating a limited set of isodistance polygons.

library(dplyr)
library(sf)
library(osrm)
library(leaflet)
library(tictoc)

# store locations in sf object
points_sf <- tibble(location = "George Bush International Airport",
                    lat = 29.990665933195277, 
                    long = -95.33663249561174,
                    radius = 48280.3 ) %>% 
  st_as_sf(coords = c("long", "lat"), crs = "WGS84")
points_sf
#> Simple feature collection with 1 feature and 2 fields
#> Geometry type: POINT
#> Dimension:     XY
#> Bounding box:  xmin: -95.33663 ymin: 29.99067 xmax: -95.33663 ymax: 29.99067
#> Geodetic CRS:  WGS 84
#> # A tibble: 1 × 3
#>   location                          radius             geometry
#> * <chr>                              <dbl>          <POINT [°]>
#> 1 George Bush International Airport 48280. (-95.33663 29.99067)

## 30-mile / 48km isodistance polyon
# loc: takes only a single location or first location from dataframe / sf
# breaks: vector of isodistance areas, i.e. c(10000, 25000, 50000) to generate 3 polygons
# res: number of points for one side of square grid, default is (much faster) 30
# tic-toc for timing
tic("osrmIsodistance")
isodist_sf <- osrmIsodistance(loc    = points_sf[1,],
                              breaks = points_sf$radius[1],
                              res    = 100)
toc()
#> osrmIsodistance: 162.23 sec elapsed

resulting sf object:
isodist_sf
#> Simple feature collection with 1 feature and 3 fields
#> Geometry type: MULTIPOLYGON
#> Dimension:     XY
#> Bounding box:  xmin: -95.73746 ymin: 29.62006 xmax: -94.87008 ymax: 30.32588
#> Geodetic CRS:  WGS 84
#>   id isomin  isomax                       geometry
#> 1  1      0 48280.3 MULTIPOLYGON (((-95.1592 30...

# leaflet supports sf object, no need to specify lng/lat for markers, polygons
leaflet() %>%
  addTiles() %>% 
  addPolygons(data = isodist_sf, weight = 1, group = "Isodistance") %>% 
  addMarkers(data = points_sf, label = ~ location, group = "Locations") %>% 
  addLayersControl(overlayGroups = c("Isodistance", "Locations"), 
                   options = layersControlOptions(collapsed = TRUE))

Created on 2023-07-13 with reprex v2.0.2

margusl
  • 7,804
  • 2
  • 16
  • 20
1

googleway::google_directions or google_distance should do it (with a bit of wrangling). See the vignette: http://symbolixau.github.io/googleway/articles/googleway-vignette.html

Alex J
  • 111
  • 3