查找距离指定地点最近的城市

时间:2012-11-07 12:12:37

标签: c# gps coordinates latitude-longitude

我正在努力寻找离给定地点最近的城市。我已经存储了一些我想要使用的城市的位置。我有我的位置,但我不知道如何找到离我所在地最近的城市?

Cities
New York - Lat 40.714353; Long -74.005973
Washington - Lat 38.895112; Long -77.036366
....more cities

My location
Philadephia - Lat 39.952335; Long -75.163789

那么我应该如何比较坐标以找到最近的城市?我正在用C#编程,但只知道algorythm的解决方案对我来说是有用的:) 谢谢你的帮助

5 个答案:

答案 0 :(得分:5)

你应该用你的高中知识来解决这个问题,你的算法是:

nearest = sqrt((lat2 - lat1)^ 2 +(Long2-Long1)^ 2) 现在这可以给你空中距离。

因此,当您对值数组执行此操作时,可以使用asort函数来比较哪一个最接近您。

答案 1 :(得分:3)

严格来说,您需要使用Haversine formula

然而,虽然你可能只是在远北或远南点略微出局,你可能会假装墨卡托投影对距离是准确的,而忽略了地球的曲率。如果您要拥有大量城市,尤其如此,因为误差更大,更远的点来自目标点。因此,您只需使用毕达哥拉斯:

relDist = √((xLat - yLat) × (xLat - yLat) + (xLng - yLng) × (xLng - yLng))

但是既然你只关心(并且只得到)相对排序,你可以跳过平方根位,这是最重的一步:

relDist = (xLat - yLat) × (xLat - yLat) + (xLng - yLng) × (xLng - yLng)

除了本身更快,它也可以在整数上合理地执行,如果你将坐标存储为实际坐标的倍数(例如存储纽约(40.664167,-73.938611)作为对(406642, -739386)。如果你想按照接近给定点的顺序快速排序大量的地方,这可能是一个很大的提升。

如果你真的关心地​​球是圆形的那么精确,那么以下实施的是Haversine:

private const double radiusE = 6378135; // Equatorial radius
private const double radiusP = 6356750; // Polar radius
private const double radianConv = 180 / Math.PI;
public static double GetDistanceBetweenPoints(double lat1, double long1, double lat2, double long2)
{
  double dLat = (lat2 - lat1) / radianConv;
  double dLong = (long2 - long1) / radianConv;
  double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(lat2) * Math.Sin(dLong/2) * Math.Sin(dLong/2);
  return Math.Sqrt((Math.Pow(radiusE * radiusP * Math.Cos(lat1 / radianConv), 2)) / (Math.Pow(radiusE * Math.Cos(lat1 / radianConv), 2) + Math.Pow(radiusP * Math.Sin(lat1 / radianConv), 2))) * (2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)));
}

答案 2 :(得分:0)

两点(x1,y1)和(x2,y2)之间的距离是

d = sqrt((x1 - x2) ^ 2 + (y1 - y2) ^ 2)

所以在c#中我们会有:

public City FindNearestCity(double currentLatitude, double currentLogitude, List<City> cities)
{
    Dictionary<City, double> distances = new Dictionary<City, double>();
    foreach (City city in cities)
    {
        double distance = Math.Sqrt(Math.Pow(city.latitude - currentLatitude, 2)  + Math.Pow(city.Longitude - currentLogitude, 2));
        distances.Add(city, distance);
    }
    double minimumDistance = distances.Min(distance => distance.Value);
    return distances.First(distance => distance.Value == minimumDistance).Key;
}

答案 3 :(得分:0)

访问here 你可以使用Brute force和div-and-conquer算法找到两个c#函数,找到二维给定点中最接近的两个点。

答案 4 :(得分:0)

尽管缺少的部分很少,但乔恩的回答非常鼓舞人心。

  • lat1应该在
    double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(lat1/ RadianConv) * Math.Cos(lat2/ RadianConv) * Math.Sin(dLong / 2) * Math.Sin(dLong / 2);
  • 最后一条语句中的模拟半径有时为2000ish,应该接近RadiusE或RadiusP,所以我改用平均半径。
    return 6371* (2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)));