Is there a workaround to get travel time between points (long-lat) that are not covered by googlemaps (using gmapsdistance)?

I need to calculate the travel time (for example, by car) between the raster centroids (coordinates of the long lat) and the control point. However, unfortunately, many of the raster centroids are not within the scope of googlemaps, and I was wondering if there was a workaround that would give me the fastest way to the reference point (for example, combining walking on the street and then getting to the checkpoint) , and if so, how effective am I doing this?

The problem is that I get bias when I just look for the next point located, take the distance to this point as the distance on foot, and then the distance between them, going from here to the control point, because the closest point may be more than one on the fastest route .

I tried to do this using the gmapsdistance function. Here is an example:

library(gmapsdistance)

#While this can be located and works well

> gmapsdistance(origin = "5.600451+-0.202553",
+               destination = "5.591622+-0.187677",
+               mode = "walking")
$Time
[1] 2101

$Distance
[1] 2667

$Status
[1] "OK"

#Changing the origin to other points often does not work as the points cannot be located and results in an NA-output

> gmapsdistance(origin = "7.9254948+-0.6283887",
+               destination = "5.591622+-0.187677",
+               mode = "walking")
$Time
[1] NA

$Distance
[1] NA

$Status
[1] "ROUTE_NOT_FOUND"

Many thanks!

+4
source share
1 answer

One way I can decide is to get a road shape file in Ghana and perform geospatial operations to find the nearest road. From there, you can use the Google API to get the distance to the track.

The steps in this decision are

  • Download road shape file
  • Find a straight line between our origin and destination
  • , .
  • Google Directions

, ,

library(sf)        ## geospatial operations
library(googleway) ## plotting and google API

:

googleway - , API Google


## Setting API keys I'll be using, one for the maps and one for directions
set_key("my_map_key"), api = "map")
set_key("my_other_api_key")

## Ghana roads
ghanaRoads <- sf::st_read("~/Downloads/gha_roads_dcw/GHA_rds_1m_dcw.shp")

## origin piont
df <- data.frame(lat = 7.9254948, lon = -0.6283887)

## destination point
dest <- data.frame(lat = 5.591622, lon = -0.187677)


google_map() %>%
    add_markers(data = df) %>%
    add_markers(data = dest) %>%
    add_polylines(ghanaRoads)

enter image description here

, , . , , , .

## convert origin into an 'sf' object
sf_origin <- sf::st_sf(geometry = sf::st_sfc(sf::st_point(x = c(-0.6283887, 7.9254948))))

## create a line between the origin and destination
m <- matrix(c(-0.6283887, 7.9254948, -0.187677, 5.591622), ncol = 2, byrow = T)
sf_line <- sf::st_sf(geometry = sf::st_sfc(sf::st_linestring(x = m)))

## The coordinate reference system needs to match between the two for 
## spatial operations
sf::st_crs(sf_line) <- sf::st_crs(ghanaRoads)
sf::st_crs(sf_origin) <- sf::st_crs(ghanaRoads)

## find all the intersecting points
sf_intersections <- sf::st_intersection(ghanaRoads, sf_line)

google_map() %>%
    add_markers(data = df) %>%
    add_markers(data = dest) %>%
    add_polylines(data = ghanaRoads) %>%
    add_markers(data = sf_intersections)

enter image description here

.


sf - sf::st_distance, lwgeom, , ,


data.table, , . , .

library(data.table)

coords <- matrix(unlist(sf_intersections$geometry), ncol = 2, byrow = T)

## Taking a fucntion I wrote for this answer
## /questions/1004686/how-to-efficiently-calculate-distance-between-pair-of-coordinates-using-datatable/3437948#3437948
dt.haversine <- function(lat_from, lon_from, lat_to, lon_to, r = 6378137){
    radians <- pi/180
    lat_to <- lat_to * radians
    lat_from <- lat_from * radians
    lon_to <- lon_to * radians
    lon_from <- lon_from * radians
    dLat <- (lat_to - lat_from)
    dLon <- (lon_to - lon_from)
    a <- (sin(dLat/2)^2) + (cos(lat_from) * cos(lat_to)) * (sin(dLon/2)^2)
    return(2 * atan2(sqrt(a), sqrt(1 - a)) * r)
}

dt <- as.data.table(coords)
dt[, `:=`(origin_lon = df$lon, origin_lat = df$lat)]
dt[, distance := dt.haversine(origin_lat, origin_lon, V1, V2)]
## min distance
sf_nearest <- dt[order(-distance)][1, .(lon = V1, lat = V2)]
sf_nearest <- sf::st_point(c(sf_nearest$lon, sf_nearest$lat))
sf_nearest <- sf::st_sf(geometry = sf::st_sfc(sf_nearest))
sf_nearest$colour <- "green"

google_map() %>%
    add_markers(data = df) %>%
    add_markers(data = dest) %>%
    add_markers(data = sf_nearest, colour = "colour")

enter image description here

orig <- sf_nearest$geometry[[1]]
orig <- as.numeric(orig)
df_orig <- data.frame(lat = orig[2], lon = orig[1])

google_map() %>%
    add_markers(df_orig)

res <- google_directions(origin = df_orig, 
            destination = dest)

## all the api results are now stored in the 'res' object.
direction_legs(res)$distance
# text  value
# 1 397 km 396829

## you can look at the route through the polygoin
df_route <- data.frame(polyline = direction_polyline(res))

google_map() %>%
    add_markers(data = df_orig) %>%
    add_markers(data = dest) %>%
    add_polylines(data = df_route, polyline = "polyline")

enter image description here

dt[order(-distance)] ,

dt[order(-distance)][1, distance]
# [1] 1329904

. , 4 /, .


, - .

sf_buffer <- sf::st_buffer(sf_origin, dist = 0.5)
sf::st_crs(sf_buffer) <- sf::st_crs(ghanaRoads)

google_map() %>%
  add_polylines(ghanaRoads) %>%
  add_polygons(sf_buffer)

enter image description here

,

sf_intersection <- sf::st_intersection(sf_buffer, ghanaRoads)

google_map() %>%
  add_markers(data = df) %>%
  add_polylines(sf_intersection)

enter image description here

sf_intersection .

+2

Source: https://habr.com/ru/post/1696214/


All Articles