在Excel / Google表格中使用纬度和经度计算道路距离

时间:2018-09-03 12:51:35

标签: excel vba excel-vba latitude-longitude

我正在寻找2个地址之间的道路距离。我有邮政编码以及每个地址的纬度和经度。

我把它布置在一个网格中(请参阅下图),因为我需要500个地址,但我想不出更好的方法。

see image attached

我的问题是我无法使用Haversine公式,因为它是用于里程数的声明,因此必须是道路距离。

我是编码方面的菜鸟,并且一直在慢慢地自学,但是我需要一种方法,它可以查找每个集合并填充相关/对应的框。

我知道google API的内容,但不太确定它是如何工作的,或者我将如何在脚本中实现类似的东西。

2 个答案:

答案 0 :(得分:4)

Google Distance Matrix API为出发地和目的地矩阵提供旅行,距离和时间。该API根据Google Maps API计算的起点和终点之间的推荐路线返回信息,该信息由包含每对点的持续时间和距离值的行组成。

Google Maps的API集用于每天允许多次免费通话,但它们最近更改了结算结构,因此您需要设置一个结算帐户。这是Distance Matrix API的新价格(除非您设法获得免费试用)。基本上,每调用1000次API就会获得5到10美元。

关于如何通过网络浏览器或以编程方式调用API的几个特定示例here


使用Excel工作表公式创建链接

这将生成指向Google Maps中每个行程的行车路线页面(包括距离)的链接,并会加快流程(如果您至少具有Excel的基本知识)。

  1. 将您的坐标集输入到Excel工作表中,每行两个AD单元中的坐标集,从第2行开始,按顺序Origin Latitude, Origin Longitude, Destination Latitude, Destination Longitude。参见图片below

  2. 将此公式粘贴到单元格E2中:
    =HYPERLINK("https://www.google.ca/maps/dir/'" & A2 & "," &B2&"'/'" & C2 & "," &D2&"'/@"&AVERAGE(A2,C2)&","&AVERAGE(B2,D2) &",12z/")

  3. “向下填充”,或复制/粘贴公式,因此它位于所有具有坐标的行中。

  4. 点击每个链接以加载该行程的Google地图,并手动记下每个坐标集的行驶距离。
    (请注意,每次旅行可能会根据您选择的路线而有多种选择。)

点击图片放大。

浏览器中的结果:

通过良好的Internet连接,我估计每个人需要10到15秒的时间,因此您总共要花大约一个小时。

(我建议将其分解,而不是尝试一次全部完成。更好的是,付一个孩子,或生多个孩子,然后用它做游戏...)


使用Google Maps API的功能

我记得我藏有的功能 仍然可以免费使用...但是根据新的定价准则,如果仅适用于几次通话,我不会感到惊讶一天(出于“测试目的”)。

  1. 该位置在两个单元格(而不是四个)中采用起点和目的地位置,但是在输入位置时更加灵活。示例:

    img

  2. 在Excel中,将此代码粘贴到新的(标准)模块中。 Here's how.

Public Function GetDistance(start As String, dest As String)
'Returns Google Maps driving distance between two points in kilometres
    Dim url As String, html As String, regEx As Object, matches As Object
    url = "http://maps.googleapis.com/maps/api/distancematrix/json?" & _
        "origins=" & Replace(start, " ", "+") & "&destinations=" & _
        Replace(dest, " ", "+")
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", url, False
        .Send: html = StrConv(.responseBody, vbUnicode)
        Set regEx = CreateObject("VBScript.RegExp")
        regEx.Pattern = """value"".*?([0-9]+)": regEx.Global = False
        Set matches = regEx.Execute(html)
        If matches.Count > 0 Then
            GetDistance = CDbl(Replace(matches(0).SubMatches(0), ".", _
                Application.International(xlListSeparator))) / 1000
        Else: GetDistance = -1: End If 'there was a problem.
    End With
End Function
  1. 对于上图中的示例,您将在单元格C2中输入:

    =GetDistance(A2,B2)
    

...获得公里的行驶距离。


Haversine方法

为了完整起见,我将包括Haversine Method,它可以数学计算出“直线”距离(没有API调用)。

这不是 行驶距离。在我对城镇之间相对较直距离的测试中,此方法相差约15%,但这是合适的(并且更快)用于其他“非驾驶相关”目的。

Excel:

Public Function Distance(lat1 As Double, lon1 As Double, _
        lat2 As Double, lon2 As Double) As Double
'Excel: Returns kilometres distance in a straight line  Haversine)
    On Error GoTo dErr
    Dim dist As Double, theta As Double: theta = lon1 - lon2
    dist = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + _
        Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * _
        Math.Cos(deg2rad(theta))
    dist = rad2deg(WorksheetFunction.Acos(dist))
    Distance = dist * 60 * 1.1515 * 1.609344
    Exit Function
dErr:
    Distance2 = -1
End Function
Function deg2rad(ByVal deg As Double) As Double
    deg2rad = (deg * WorksheetFunction.Pi / 180#)
End Function
Function rad2deg(ByVal rad As Double) As Double
    rad2deg = rad / WorksheetFunction.Pi * 180#
End Function

MS Access:

由于缺少Excel的数学功能,访问权限略有不同,因此我不妨包括它:

Const pi = 3.14159265358979
Public Function Distance(lat1 As Double, lon1 As Double, lat2 As Double, lon2 As Double) As Double
'MS Access: Returns kilometres distance in a straight line  Haversine)
    Dim dist As Double, theta As Double: theta = lon1 - lon2
    dist = Sin(deg2rad(lat1)) * Sin(deg2rad(lat2)) + Cos(deg2rad(lat1)) * Cos(deg2rad(lat2)) * Cos(deg2rad(theta))
    Distance = rad2deg(ACos(dist)) * 60 * 1.1515 * 1.609344
End Function
Function ACos(N As Double) As Double: ACos = pi / 2 - ASin(N): End Function
Function deg2rad(ByVal deg As Double) As Double: deg2rad = (deg * pi / 180#): End Function
Function rad2deg(ByVal rad As Double) As Double: rad2deg = rad / pi * 180#: End Function
Public Function ASin(N As Double) As Double: ASin = 2 * Atn(N / (1 + Sqr(1 - (N * N)))): End Function

Law of Haversines

求解的球形三角形

答案 1 :(得分:-1)

我会用arcgis做到这一点: 你画了两点 您应该有一些道路shapefile,其中包含要计算要修剪的点的距离的道路,然后测量被修剪的polilyne