地址之间的距离

8
有没有办法通过Google地图计算两个地址之间的距离?如何实现?

3
欢迎来到StackOverflow!为了提供帮助,您需要提供更多详细信息。您处理的是什么类型的数据?您已经尝试了什么(具体来说,您编写了什么样的代码)?请提供更多细节。 - Andrew Whitaker
1
对于任何寻找高效解决方案的人,我建议使用Haversine公式来计算两个已知纬度和经度的位置之间的距离。以下解决方案使用Google Directions API a)在某些情况下将无法返回正确答案,因为驾驶距离可能与实际距离不同,并且b)调用Directions API可能需要一秒钟左右。此外,c)由于Maps更改了其定价政策,这可能会花费实际资金。 - stuartd
5个回答

18

如果您只有两个地址,请先尝试通过GEOCODING获取经纬度,然后有多种方法可以获取它们之间的距离。

或者

如果您不需要地理编码并想要一个计算机科学解决方案,请使用此方法:

public int getDistance(string origin, string destination)
{
    System.Threading.Thread.Sleep(1000);
    int distance = 0;
    //string from = origin.Text;
    //string to = destination.Text;
    string url = "http://maps.googleapis.com/maps/api/directions/json?origin=" + origin + "&destination=" + destination + "&sensor=false";
    string requesturl = url;
    //string requesturl = @"http://maps.googleapis.com/maps/api/directions/json?origin=" + from + "&alternatives=false&units=imperial&destination=" + to + "&sensor=false";
    string content = fileGetContents(requesturl);
    JObject o = JObject.Parse(content);
    try
    {
        distance = (int)o.SelectToken("routes[0].legs[0].distance.value");
        return distance;
    }
    catch
    {
        return distance;
    }
    return distance;
    //ResultingDistance.Text = distance;
}

    protected string fileGetContents(string fileName)
    {
        string sContents = string.Empty;
        string me = string.Empty;
        try
        {
            if (fileName.ToLower().IndexOf("http:") > -1)
            {
                System.Net.WebClient wc = new System.Net.WebClient();
                byte[] response = wc.DownloadData(fileName);
                sContents = System.Text.Encoding.ASCII.GetString(response);

            }
            else
            {
                System.IO.StreamReader sr = new System.IO.StreamReader(fileName);
                sContents = sr.ReadToEnd();
                sr.Close();
            }
        }
        catch { sContents = "unable to connect to server "; }
        return sContents;
    }

或者

如果您不想使用谷歌,并且只需要飞行距离,请尝试以下方法:

public decimal calcDistance(decimal latA, decimal longA, decimal latB, decimal longB)
{

    double theDistance = (Math.Sin(DegreesToRadians(latA)) *
            Math.Sin(DegreesToRadians(latB)) +
            Math.Cos(DegreesToRadians(latA)) *
            Math.Cos(DegreesToRadians(latB)) *
            Math.Cos(DegreesToRadians(longA - longB)));

    return Convert.ToDecimal((RadiansToDegrees(Math.Acos(theDistance)))) * 69.09M * 1.6093M;
}

NB:自2018年6月11日起,由于Google已禁用对Maps API的无密钥访问,此方法将不再适用。如果您希望使用此方法,则必须注册其云平台并启用计费。


我在哪里获取JObject解析器? - user1901860
文件获取函数是什么? - user1901860
我在这里下载了JSon linq: http://james.newtonking.com/pages/json-net.aspx - user1901860
@sajanyamaha 我已经使用了你的代码,非常好用,但是如果我输入不存在的地址它仍然会计算距离,而且如果我在谷歌地图上查询该地址,则显示'找不到该地址',请问如何处理这种情况。感谢你的代码。 - mark
请注意,此代码将不再起作用,因为现在您需要一个 API 密钥。 - ScottishTapWater
这里的Sleep(1000)是干什么用的? - Hasher

2

我已经修复了上面答案中的代码,使其能够与谷歌密钥一起使用。

  1. 获取谷歌地图的API密钥
  2. 安装Nuget包:Newtonsoft.Json

3.

 public int getDistance(string origin, string destination)
    {
        System.Threading.Thread.Sleep(1000);
        int distance = 0;
        string key = "YOUR KEY";

        string url = "https://maps.googleapis.com/maps/api/directions/json?origin=" + origin + "&destination=" + destination + "&key=" + key;
        url = url.Replace(" ", "+");          
        string content = fileGetContents(url);      
        JObject o = JObject.Parse(content);
        try
        {
            distance = (int)o.SelectToken("routes[0].legs[0].distance.value");
            return distance;
        }
        catch
        {
            return distance;
        }
    }

    protected string fileGetContents(string fileName)
    {
        string sContents = string.Empty;
        string me = string.Empty;
        try
        {
            if (fileName.ToLower().IndexOf("https:") > -1)
            {
                System.Net.WebClient wc = new System.Net.WebClient();
                byte[] response = wc.DownloadData(fileName);
                sContents = System.Text.Encoding.ASCII.GetString(response);

            }
            else
            {
                System.IO.StreamReader sr = new System.IO.StreamReader(fileName);
                sContents = sr.ReadToEnd();
                sr.Close();
            }
        }
        catch { sContents = "unable to connect to server "; }
        return sContents;
    }

它起作用了,谢谢!我可以问一下这里的 Sleep(1000) 是用来做什么的吗? - Hasher

2
您可以使用Google Directions API来完成此操作,将起点/终点位置作为地址字符串或坐标传递给API,Google会为您完成所有的工作。
路线由基于您指定的途经点数量的各种legs组成。在您的情况下(0个途经点),您应该只有一个leg,这个leg应该有一个估计距离属性。

0

我做了这个:但它返回一个空字符串。 url = "http://maps.googleapis.com/maps/api/directions/json?origin=3320, rue de verdun, verdun&destination=379, 19e avenue, La Guadeloupe, G0M 1G0&sensor=false"

public string fileGetContents(string url)
    {
        string text = "";
        var webRequest = HttpWebRequest.Create(url);
        IAsyncResult asyncResult = null; 
        asyncResult = webRequest.BeginGetResponse(
            state => 
            { 
                var response = webRequest.EndGetResponse(asyncResult); 
                using (var sr = new StreamReader(response.GetResponseStream()))
                {
                    text = sr.ReadToEnd();
                } 
            }, null
            );
        return text;
    }

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接