Getting driving distance between two points (lat, lon) using R and Google Map API

前端 未结 5 579
失恋的感觉
失恋的感觉 2021-01-30 18:29

I am trying to get the driving distance between two points with lat/lon given. I can manually put them into google map and get the driving distance but I want to do all this pr

相关标签:
5条回答
  • 2021-01-30 19:05

    You need RCurl or an equivalent here.

    library(XML)
    library(bitops)
    library(RCurl)
    latlon2ft <- function(origin,destination){
      xml.url <- paste0('http://maps.googleapis.com/maps/api/distancematrix/xml?origins=',origin,'&destinations=',destination,'&mode=driving&sensor=false')
      xmlfile <- xmlParse(getURL(xml.url))
      dist <- xmlValue(xmlChildren(xpathApply(xmlfile,"//distance")[[1]])$value)
      distance <- as.numeric(sub(" km","",dist))
      ft <- distance*3.28084 # FROM METER TO FEET
      return(ft)
    }
    
    latlon2ft(origin='37.193489,-121.07395',destination='37.151616,-121.046586')
    

    Result:

    [1] 17224.41
    
    0 讨论(0)
  • 2021-01-30 19:10

    I needed to calculate driving distances for a bunch of addresses, so I wrote a short function for it and put it in a likewise small packet. You can find it in my GitHub repo: https://github.com/JanMultmeier/GeoData/blob/master/GeoDataPackage/R/GetDist.R

    This should get it to run:

    require(devtools)
    install_github("JanMultmeier/GeoData/GeoDataPackage")
    library(GeoData)
    getDist(from="1 Infinity Loop, Cupertino, CA 95014", to="1600 Amphitheatre Pkwy, Mountain View, CA 94043",modus="driving",get="distance")
    

    It should return 14.8 km.

    Barryhunter has already hinted at the usage restriction by Google, which ties the use of this API to displaying the results on a Google map.

    Hope that still helps some people who stumble across this post (like me)...

    0 讨论(0)
  • 2021-01-30 19:11

    I authored the gmapsdistance package to do just that. It is available on CRAN. You can use the function in the following way:

    results = gmapsdistance(origin = "38.1621328+24.0029257",
                            destination = "37.9908372+23.7383394",
                            mode = "walking") results
    # $Time
    # [1] 30025
    # 
    # $Distance
    # [1] 39507
    # 
    # $Status
    # [1] "OK"
    

    You can also include vectors of origins and destinations, and get the resulting distance matrix. It supports also directions, and has a bunch of options:

    results = gmapsdistance(origin = c("Washington+DC", "New+York+NY", "Seattle+WA", "Miami+FL"), 
                            destination = c("Los+Angeles+CA", "Austin+TX", "Chicago+IL", "Philadelphia+PA"), 
                            mode = "bicycling", 
                            departure = 1514742000)
    results
    # $Time
    #              or Time.Los+Angeles+CA Time.Austin+TX Time.Chicago+IL Time.Philadelphia+PA
    # 1 Washington+DC              856621         535146          247765                54430
    # 2   New+York+NY              917486         596011          308630                32215
    # 3    Seattle+WA              374692         678959          674989               956702
    # 4      Miami+FL              829039         416667          452035               411283
    # 
    # $Distance
    #              or Distance.Los+Angeles+CA Distance.Austin+TX Distance.Chicago+IL Distance.Philadelphia+PA
    # 1 Washington+DC                 4567470            2838519             1303067                   266508
    # 2   New+York+NY                 4855086            3126136             1590684                   160917
    # 3    Seattle+WA                 1982354            3562970             3588297                  5051951
    # 4      Miami+FL                 4559205            2279966             2381610                  2169382
    # 
    # $Status
    #              or status.Los+Angeles+CA status.Austin+TX status.Chicago+IL status.Philadelphia+PA
    # 1 Washington+DC                    OK               OK                OK                     OK
    # 2   New+York+NY                    OK               OK                OK                     OK
    # 3    Seattle+WA                    OK               OK                OK                     OK
    # 4      Miami+FL                    OK               OK                OK                     OK
    
    0 讨论(0)
  • 2021-01-30 19:14

    I've written the googleway package to do this using Google Maps API

    In particular, the google_directions() function will give you driving distances, directions, routes, legs, steps etc. And the google_distance() function will give you a distance matrix for all the origins/destinations

    You need a Google API key to use their API

    library(googleway)
    
    ## your valid API key
    key <- "your_api_key_here"
    
    directions <- google_directions(origin = c(37.193489,-121.07395),
                                    destination = c(37.151616,-121.046586),
                                    key = key, 
                                    simplify = T)
    
    directions$routes$legs
    # [[1]]
    # distance.text distance.value duration.text duration.value duration_in_traffic.text duration_in_traffic.value                 end_address
    # 1        5.2 km           5250        3 mins            161                   3 mins                       156 I-5, Gustine, CA 95322, USA
    # end_location.lat end_location.lng               start_address start_location.lat start_location.lng
    # 1         37.15162        -121.0466 I-5, Gustine, CA 95322, USA           37.19349           -121.074
    # steps
    # 1 5.2 km, 5250, 3 mins, 161, 37.1516163, -121.0465852, Head <b>southeast</b> on <b>I-5 S</b>, ij_bFfg~aVpBgA`DkB~FeDbIwEpEgCtaAsj@nAs@lDqBxIaF~FgDlHcEjC{AdFuCrBkAhC{A|A{@|A}@bAk@rBkArBkA|A{@`DiB|A}@vDwBdAm@dAm@rBkA|A{@zA{@~J{FpC_B~A}@tBkAjHeEvGuDlMmHtBkAVO, 37.1934864, -121.0739565, DRIVING
    #   traffic_speed_entry via_waypoint
    #   1                NULL         NULL
    
    
    
    google_distance(origins = list(c(37.193489,-121.07395)),
                    destinations = list(c(37.151616,-121.046586)),
                    key = key, 
                    simplify = T,
                    units = "imperial")
    
    # $destination_addresses
    # [1] "I-5, Gustine, CA 95322, USA"
    # 
    # $origin_addresses
    # [1] "I-5, Gustine, CA 95322, USA"
    # 
    # $rows
    # elements
    # 1 3.3 mi, 5250, 3 mins, 161, 3 mins, 157, OK
    # 
    # $status
    # [1] "OK"
    

    Given the google_directions() function returns a polyline (the line you get on Google Maps when you search for a route), we can plot it on a Google Map

    key <- 'your_map_api_key'
    
    df_route <- decode_pl(directions$routes$overview_polyline$points)
    
    google_map(data = df_route, key = key, height = 800, search_box = T) %>%
        add_markers()
    ## or you can use `add_polyline()` to view the entire line
    

    0 讨论(0)
  • 2021-01-30 19:22

    At time of writing, Renjin (a Java-based R interpreter) does not have a lot of packages to help solve this problem. Here is an implementation that does not depend on extra packages.

    # Computes the distance between two locations in meters. This uses an online
    # map API and therefore an Internet connection is required for an accurate
    # result. If no connection is found, this will use the Haversine formula
    # to provide a rough estimate for the distance.
    #
    # @param src The source latitude and longitude.
    # @param dst The destination latitude and longitude.
    # @param mode Driving, cycling, walking, etc.
    distance <- function( lat1, lon1, lat2, lon2, mode = 'driving' ) {
      lat1 = as.numeric( lat1 )
      lon1 = as.numeric( lon1 )
      lat2 = as.numeric( lat2 )
      lon2 = as.numeric( lon2 )
    
      # Create the URL to use to get the distance data.
      url = paste0(
        'https://maps.googleapis.com/maps/api/distancematrix/xml?',
        'origins=', lat1,
        ',', lon1,
        '&destinations=', lat2,
        ',', lon2,
        '&mode=', mode,
        '&sensor=false'
      )
    
      tryCatch({
        # Download the XML document with distance information.
        xml = readLines( url )
    
        # The <value> element immediately follows the distance element.
        value = xml[ grep( "<distance>", xml ) + 1 ]
    
        # Obtain the distance in meters.
        meters = sub( ".*>(.*?)<.*", "\\1", value )
    
        # Return the distance.
        as.numeric( meters )
      },
      warning = function( w ) {
        haversine( lat1, lon1, lat2, lon2 )
      },
      error = function( e ) {
        haversine( lat1, lon1, lat2, lon2 )
      })
    }
    
    # Computes distance using Haversine formula.
    #
    # Returns the result in meters.
    haversine <- function( lat1, lon1, lat2, lon2, radius = 6371 ) {
      # Convert decimal degrees to radians
      lon1 = lon1 * pi / 180
      lon2 = lon2 * pi / 180
      lat1 = lat1 * pi / 180
      lat2 = lat2 * pi / 180
    
      # Haversine formula
      dlon = lon2 - lon1
      dlat = lat2 - lat1
      a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
      c = 2 * atan2(sqrt(a), sqrt(1-a))
    
      return( radius * c * 1000 )
    }
    

    Output:

    distance( '44.5646', '-123.2620', '41.2861', '-124.0902' )
    [1] 495892
    distance( 44.5646, -123.2620, 41.2861, -124.0902, mode='walking' )
    [1] 487715
    

    Conversion from meters to feet is an exercise for the reader.

    0 讨论(0)
提交回复
热议问题