【问题标题】:How can I determine the distance between two sets of latitude/longitude coordinates?如何确定两组纬度/经度坐标之间的距离?
【发布时间】:2010-01-06 01:44:44
【问题描述】:

我正在尝试写一些东西来确定纬度/经度坐标集之间的距离。

我正在使用我在this site 上找到的以下代码:

public static double distance (double lat1, double lon1, double lat2, double lon2) { 
    double lat1 = Convert.ToDouble(latitude);
    double lon1 = Convert.ToDouble(longitude);
    double lat2 = Convert.ToDouble(destlat);
    double lon2 = Convert.ToDouble(destlon);

    double theta = toRadians(lon1-lon2); 
    lat1 = toRadians(lat1); 
    lon1 = toRadians(lon1); 
    lat2 = toRadians(lat2); 
    lon2 = toRadians(lon2); 

    double dist = sin(lat1)*sin(lat2) + cos(lat1)*cos(lat2)*cos(theta); 
    dist = toDegrees(acos(dist)) * 60 * 1.1515 * 1.609344 * 1000; 

    return dist; 
} 

我的问题是我遇到了编译错误“当前上下文中不存在名称'toRadians'/'cos'/'sin/'toDegrees'...”什么我做错了吗?

【问题讨论】:

  • 你为什么要在double上打电话给Convert.ToDouble
  • @SLaks:同意,刚刚注意到Convert.ToDouble
  • 如果您将找到此代码的链接提供给我们,我们会更容易为您提供帮助。
  • 好的,我将链接编辑到问题中。

标签: c# distance latitude-longitude


【解决方案1】:

您可能想要使用以下 C# 类:

public static class GeoCodeCalc
{
    public const double EarthRadiusInMiles = 3956.0;
    public const double EarthRadiusInKilometers = 6367.0;

    public static double ToRadian(double val) { return val * (Math.PI / 180); }
    public static double DiffRadian(double val1, double val2) { return ToRadian(val2) - ToRadian(val1); }

    public static double CalcDistance(double lat1, double lng1, double lat2, double lng2) 
    {
        return CalcDistance(lat1, lng1, lat2, lng2, GeoCodeCalcMeasurement.Miles);
    }

    public static double CalcDistance(double lat1, double lng1, double lat2, double lng2, GeoCodeCalcMeasurement m) 
    {
        double radius = GeoCodeCalc.EarthRadiusInMiles;

        if (m == GeoCodeCalcMeasurement.Kilometers) { radius = GeoCodeCalc.EarthRadiusInKilometers; }
        return radius * 2 * Math.Asin( Math.Min(1, Math.Sqrt( ( Math.Pow(Math.Sin((DiffRadian(lat1, lat2)) / 2.0), 2.0) + Math.Cos(ToRadian(lat1)) * Math.Cos(ToRadian(lat2)) * Math.Pow(Math.Sin((DiffRadian(lng1, lng2)) / 2.0), 2.0) ) ) ) );
    }
}

public enum GeoCodeCalcMeasurement : int
{
    Miles = 0,
    Kilometers = 1
}

用法:

// Calculate Distance in Miles
GeoCodeCalc.CalcDistance(47.8131545175277, -122.783203125, 42.0982224111897, -87.890625);

// Calculate Distance in Kilometers
GeoCodeCalc.CalcDistance(47.8131545175277, -122.783203125, 42.0982224111897, -87.890625, GeoCodeCalcMeasurement.Kilometers);

来源:Chris Pietschmann - Calculate Distance Between Geocodes in C# and JavaScript

【讨论】:

    【解决方案2】:

    您可以像这样编写toRadians 函数:

    double ToRadians(double degrees) { return degrees * Math.PI / 180; }
    

    您可以像这样编写toDegrees 函数:

    double ToDegrees(double radians) { return radians * 180 / Math.PI; }
    

    您应该将sincos 替换为Math.SinMath.Cos

    【讨论】:

    • 如果您经常调用此函数,如果您的代码运行缓慢,请为 PI / 180 和 180 / PI 创建两个常量。
    【解决方案3】:

    这看起来像 C#。

    首先你需要定义toRadianstoDegrees

    double toRadians(double degrees) {
        double sign = Math.Sign(degrees);
        while(Math.Abs(degrees) > 360) {
            degrees -= sign * 360;
        }
        return Math.PI * degrees / 180;
    }
    
    double toDegrees(double radians) {
        double sign = Math.Sign(radians);
        while(Math.Abs(radians) > 2 * Math.PI) {
            radians -= sign * 2 * Math.PI;
        }
        return 180 * radians / Math.PI;
    }
    

    然后,要使用三角函数,您需要使用Math.SinMath.Cos 等。

    double dist = Math.Sin(lat1) * Math.Sin(lat2)
                    + Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(theta);
    

    dist = toDegrees(Math.Acos(dist)) * 60 * 1.1515 * 1.609344 * 1000; 
    

    评论:

    public static double distance (double lat1, double lon1, double lat2, double lon2) { 
    double lat1 = Convert.ToDouble(latitude);
    double lon1 = Convert.ToDouble(longitude);
    double lat2 = Convert.ToDouble(destlat);
    double lon2 = Convert.ToDouble(destlon);
    

    这是什么? latitudelongitudedestlatdestlon 定义在哪里?此外,您似乎有 lat1lon1 lat2lon2 作为此方法的参数,因此您无法在此处定义具有相同名称的本地变量。

    double theta = toRadians(lon1-lon2); 
    lat1 = toRadians(lat1); 
    lon1 = toRadians(lon1); 
    lat2 = toRadians(lat2); 
    lon2 = toRadians(lon2); 
    

    这是一种糟糕的风格。如果lat1 表示以度为单位的纬度,则最好像这样计算lat1 的弧度等效值:

    double lat1Radians = toRadians(lat1);
    

    因此将上面的替换为:

    double theta = toRadians(lon1-lon2); 
    double lat1Radians = toRadians(lat1); 
    double lon1Radians = toRadians(lon1); 
    double lat2Radians = toRadians(lat2); 
    double lon2Radians = toRadians(lon2);
    

    最后:

    double dist = sin(lat1) * sin(lat2)
                    + cos(lat1) * cos(lat2) * cos(theta); 
    dist = toDegrees(acos(dist)) * 60 * 1.1515 * 1.609344 * 1000; 
    

    这也是不好的风格。第一个公式和第二个公式不可能都代表您要计算的距离。您应该将第一个公式的结果分配给具有更有意义名称的变量。作为最坏的情况,至少做到以下几点:

    double temp = Math.Sin(lat1) * Math.Sin(lat2)
                    + Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(theta);
    double dist = toDegrees(Math.Acos(dist)) * 60 * 1.1515 * 1.609344 * 1000; 
    
    return dist;
    

    【讨论】:

    • 您可能不需要将其限制为小于 2π。
    • 几乎绝对不需要执行换行 -- 纬度和经度往往有合适的范围 =)
    • @Jason,你可以通过 double deg = 180 * radians / Mapth.Pi; return (deg % 360) + (deg - Math.Truncate(deg)); 来度过这段时光
    • @SLaks 我相信他想做一个通用函数。
    • 现在我得到“System.Math”不包含“Pi”的定义
    【解决方案4】:

    我知道这个问题真的很老了,但如果其他人偶然发现这个问题,请使用System.Device 中的GeoCoordinate

    var distanceInMeters = new GeoCoordinate(lat1, lon1)
        .GetDistanceTo(new GeoCoordinate(lat2, lon2));
    

    【讨论】:

      【解决方案5】:

      正在计算经纬度点之间的距离...

      double Lat1 = Convert.ToDouble(纬度);

          double Long1 = Convert.ToDouble(longitude);
      
          double Lat2 = 30.678;
          double Long2 = 45.786;
          double circumference = 40000.0; // Earth's circumference at the equator in km
          double distance = 0.0;
          double latitude1Rad = DegreesToRadians(Lat1);
          double latititude2Rad = DegreesToRadians(Lat2);
          double longitude1Rad = DegreesToRadians(Long1);
          double longitude2Rad = DegreesToRadians(Long2);
          double logitudeDiff = Math.Abs(longitude1Rad - longitude2Rad);
          if (logitudeDiff > Math.PI)
          {
              logitudeDiff = 2.0 * Math.PI - logitudeDiff;
          }
          double angleCalculation =
              Math.Acos(
                Math.Sin(latititude2Rad) * Math.Sin(latitude1Rad) +
                Math.Cos(latititude2Rad) * Math.Cos(latitude1Rad) * Math.Cos(logitudeDiff));
          distance = circumference * angleCalculation / (2.0 * Math.PI);
          return distance;
      

      【讨论】:

        【解决方案6】:

        您需要稍微修改一下这段代码。

        正如 SLaks 所说,您需要定义自己的 toRadians() 方法,因为 .NET 没有本机版本。

        您还需要将对 cos() 和 sin() 的调用更改为:Math.Cos() 和 Math.Sin()

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-09-16
          • 1970-01-01
          • 2011-09-05
          • 2018-04-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-16
          • 2015-11-05
          相关资源
          最近更新 更多