2013-05-31 72 views
14

Tôi đang cố gắng lấy khoảng cách lái xe giữa hai điểm với lat/lon đã cho. Tôi có thể tự đặt chúng vào bản đồ google và nhận khoảng cách lái xe nhưng tôi muốn làm tất cả điều này theo chương trình.Nhận khoảng cách lái xe giữa hai điểm (lat, lon) bằng cách sử dụng R và Google Map API

Tôi đoán JavaScript là ngôn ngữ cần thực hiện. Nhưng, tôi không biết JavaScript và tôi khá quen thuộc bằng cách sử dụng R. Tôi muốn làm điều đó trong R vì tôi đang làm tất cả các phân tích dữ liệu trong R.

Tôi đang tìm khoảng cách dọc theo con đường không bay lượn khoảng cách. Sau vài giờ cố gắng, tôi đã viết chức năng sau trong R (Thisthis one đã giúp). Bạn có cách nào tốt hơn để có được khoảng cách trong chức năng này hay bất cứ thứ gì rất đơn giản?

library(XML) 
latlon2ft <- function(origin,destination) 
{ 

xml.url <- paste0('http://maps.googleapis.com/maps/api/distancematrix/xml?origins=',origin,'&destinations=',destination,'&mode=driving&sensor=false') 

xmlfile <- xmlTreeParse(xml.url) 
xmltop = xmlRoot(xmlfile) 
distance <- xmltop[['row']][[1]][5][1][['distance']][['value']][[1]] 
distance <- as.numeric(unclass(distance)[['value']]) 
ft <- distance*3.28084 # FROM METER TO FEET 
return(ft) 
} 

latlon2ft(origin='37.193489,-121.07395',destination='37.151616,-121.046586') 

KẾT QUẢ = 17224,41

+1

Bạn đã đọc hộp Màu hồng ở đây: https://developers.google.com/maps/documentation/distancematrix/#Limits? – barryhunter

+0

Ouch! Bạn có cách nào khác chấp nhận được những gì tôi cần không? –

Trả lời

7

Bạn cần RCurl hoặc tương đương ở đây.

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') 

Kết quả:

[1] 17224.41 
+1

Lưu ý rằng, giống như Google Maps, điều này sẽ mất khá nhiều bất kỳ hình thức địa chỉ nào bạn có thể ném vào nó: Mã zip, địa chỉ đầy đủ, địa chỉ một phần ... Giải pháp của bạn đã làm cho ngày của tôi, Thomas, cảm ơn! Bây giờ tôi chỉ cần tinh chỉnh nó để tôi có thể nhận được nó để mang lại thời gian trong giờ. –

+0

Bạn có tối đa yêu cầu hàng ngày của mình không? – Thomas

+0

Vâng tôi đã làm, tôi vừa phát hiện ra điều đó và xóa bình luận của tôi sau đó. Tôi sẽ chỉ làm lại mã của mình để giảm thiểu truy vấn. ;) –

3

tôi cần phải tính toán được khoảng cách cho một loạt các địa chỉ, vì vậy tôi đã viết một hàm viết tắt của nó và đặt nó trong một gói tương tự như vậy nhỏ. Bạn có thể tìm thấy nó trong repo GitHub của tôi: https://github.com/JanMultmeier/GeoData/blob/master/GeoDataPackage/R/GetDist.R

này nên làm cho nó chạy:

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") 

Nó phải trả lại 14,8 km.

Barryhunter đã gợi ý về giới hạn sử dụng của Google, điều này buộc phải sử dụng API này để hiển thị kết quả trên bản đồ Google.

Hy vọng rằng sẽ vẫn giúp một số người vấp ngã trên bài đăng này (như tôi) ...

3

Tôi là tác giả của gói gmapsdistance để làm việc đó. Nó có sẵn trên CRAN. Bạn có thể sử dụng chức năng theo cách sau:

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

Bạn cũng có thể bao gồm véc-tơ nguồn gốc và đích đến và nhận ma trận khoảng cách kết quả. Nó hỗ trợ cũng hướng, và có một loạt các lựa chọn:

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 
1

Tôi đã viết các gói googleway để làm điều này sử dụng API của Google Maps

Đặc biệt, google_directions() chức năng sẽ cung cấp cho bạn khoảng cách lái xe, hướng , tuyến đường, chân, các bước, v.v. Và google_distance() chức năng sẽ cung cấp cho bạn một ma trận khoảng cách cho tất cả các nguồn gốc/khu

Bạn cần một chìa khóa Google API để sử dụng API của họ

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`[email protected]@lDqBxIaF~FgDlHcEjC{AdFuCrBkAhC{A|A{@|A}@[email protected]|A{@`DiB|A}@[email protected]@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" 

Với google_directions() hàm trả về một polyline (đường bạn nhận được trên Google Maps khi bạn tìm kiếm một con đường), chúng ta có thể vẽ nó trên một 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 

enter image description here

0

Tại thời điểm viết bài, Renjin (một trình thông dịch R dựa trên Java) không có nhiều gói để giúp giải quyết vấn đề này. Đây là một thực hiện mà không phụ thuộc vào các gói thêm.

# 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 

chuyển đổi từ mét thành bộ là một bài tập cho người đọc.

Các vấn đề liên quan