计算两个纬度和经度地球坐标之间的距离

我正在计算两个地理坐标之间的距离。 我正在testing我的应用程序对其他3-4应用程序。 当我计算距离时,我的计算结果平均为3.3英里,而其他应用则为3.5英里。 这是我试图执行的计算的一个很大的区别。 有没有好的类库来计算距离? 我在C#中计算这样的:

public static double Calculate(double sLatitude,double sLongitude, double eLatitude, double eLongitude) { var radiansOverDegrees = (Math.PI / 180.0); var sLatitudeRadians = sLatitude * radiansOverDegrees; var sLongitudeRadians = sLongitude * radiansOverDegrees; var eLatitudeRadians = eLatitude * radiansOverDegrees; var eLongitudeRadians = eLongitude * radiansOverDegrees; var dLongitude = eLongitudeRadians - sLongitudeRadians; var dLatitude = eLatitudeRadians - sLatitudeRadians; var result1 = Math.Pow(Math.Sin(dLatitude / 2.0), 2.0) + Math.Cos(sLatitudeRadians) * Math.Cos(eLatitudeRadians) * Math.Pow(Math.Sin(dLongitude / 2.0), 2.0); // Using 3956 as the number of miles around the earth var result2 = 3956.0 * 2.0 * Math.Atan2(Math.Sqrt(result1), Math.Sqrt(1.0 - result1)); return result2; } 

我可能做错了什么? 我应该以公里计算,然后转换为英里?

GeoCoordinate类(.NET Framework 4及更高版本)已经具有GetDistanceTo方法。

 var sCoord = new GeoCoordinate(sLatitude, sLongitude); var eCoord = new GeoCoordinate(eLatitude, eLongitude); return sCoord.GetDistanceTo(eCoord); 

距离以米为单位。

你需要引用System.Device。

GetDistance是最好的解决scheme ,但在很多情况下,我们不能使用这种方法(例如通用应用程序)

  • algorithm的伪代码 计算 coorindates之间的距离

     public static double DistanceTo(double lat1, double lon1, double lat2, double lon2, char unit = 'K') { double rlat1 = Math.PI*lat1/180; double rlat2 = Math.PI*lat2/180; double theta = lon1 - lon2; double rtheta = Math.PI*theta/180; double dist = Math.Sin(rlat1)*Math.Sin(rlat2) + Math.Cos(rlat1)* Math.Cos(rlat2)*Math.Cos(rtheta); dist = Math.Acos(dist); dist = dist*180/Math.PI; dist = dist*60*1.1515; switch (unit) { case 'K': //Kilometers -> default return dist*1.609344; case 'N': //Nautical Miles return dist*0.8684; case 'M': //Miles return dist; } return dist; } 
  • 真正的世界C#实现 ,它使用扩展方法

    用法:

     var distance = new Coordinates(48.672309, 15.695585) .DistanceTo( new Coordinates(48.237867, 16.389477), UnitOfLength.Kilometers ); 

    执行:

     public class Coordinates { public double Latitude { get; private set; } public double Longitude { get; private set; } public Coordinates(double latitude, double longitude) { Latitude = latitude; Longitude = longitude; } } public static class CoordinatesDistanceExtensions { public static double DistanceTo(this Coordinates baseCoordinates, Coordinates targetCoordinates) { return DistanceTo(baseCoordinates, targetCoordinates, UnitOfLength.Kilometers); } public static double DistanceTo(this Coordinates baseCoordinates, Coordinates targetCoordinates, UnitOfLength unitOfLength) { var baseRad = Math.PI * baseCoordinates.Latitude / 180; var targetRad = Math.PI * targetCoordinates.Latitude/ 180; var theta = baseCoordinates.Longitude - targetCoordinates.Longitude; var thetaRad = Math.PI * theta / 180; double dist = Math.Sin(baseRad) * Math.Sin(targetRad) + Math.Cos(baseRad) * Math.Cos(targetRad) * Math.Cos(thetaRad); dist = Math.Acos(dist); dist = dist * 180 / Math.PI; dist = dist * 60 * 1.1515; return unitOfLength.ConvertFromMiles(dist); } } public class UnitOfLength { public static UnitOfLength Kilometers = new UnitOfLength(1.609344); public static UnitOfLength NauticalMiles = new UnitOfLength(0.8684); public static UnitOfLength Miles = new UnitOfLength(1); private readonly double _fromMilesFactor; private UnitOfLength(double fromMilesFactor) { _fromMilesFactor = fromMilesFactor; } public double ConvertFromMiles(double input) { return input*_fromMilesFactor; } } 

这里是JavaScript版本的男人和女人

 function distanceTo(lat1, lon1, lat2, lon2, unit) { var rlat1 = Math.PI * lat1/180 var rlat2 = Math.PI * lat2/180 var rlon1 = Math.PI * lon1/180 var rlon2 = Math.PI * lon2/180 var theta = lon1-lon2 var rtheta = Math.PI * theta/180 var dist = Math.sin(rlat1) * Math.sin(rlat2) + Math.cos(rlat1) * Math.cos(rlat2) * Math.cos(rtheta); dist = Math.acos(dist) dist = dist * 180/Math.PI dist = dist * 60 * 1.1515 if (unit=="K") { dist = dist * 1.609344 } if (unit=="N") { dist = dist * 0.8684 } return dist } 

地球平均半径= 6,371公里= 3958.76英里

而不是使用var我build议你使用double ,只是为了明确。

对于那些使用Xamarin并且无法访问GeoCoordinate类的用户,您可以使用Android Location类:

 public static double GetDistanceBetweenCoordinates (double lat1, double lng1, double lat2, double lng2) { var coords1 = new Location (""); coords1.Latitude = lat1; coords1.Longitude = lng1; var coords2 = new Location (""); coords2.Latitude = lat2; coords2.Longitude = lng2; return coords1.DistanceTo (coords2); } 

基于Elliot Wood的function,这个C函数正在工作…

 #define SIM_Degree_to_Radian(x) ((float)x * 0.017453292F) #define SIM_PI_VALUE (3.14159265359) float GPS_Distance(float lat1, float lon1, float lat2, float lon2) { float theta; float dist; theta = lon1 - lon2; lat1 = SIM_Degree_to_Radian(lat1); lat2 = SIM_Degree_to_Radian(lat2); theta = SIM_Degree_to_Radian(theta); dist = (sin(lat1) * sin(lat2)) + (cos(lat1) * cos(lat2) * cos(theta)); dist = acos(dist); // dist = dist * 180.0 / SIM_PI_VALUE; // dist = dist * 60.0 * 1.1515; // /* Convert to km */ // dist = dist * 1.609344; dist *= 6370.693486F; return (dist); } 

你可以把它改成两倍 。 它以km为单位返回值。

计算纬度和经度点之间的距离…

  double Lat1 = Convert.ToDouble(latitude); 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; 

尝试这个:

  public double getDistance(GeoCoordinate p1, GeoCoordinate p2) { double d = p1.Latitude * 0.017453292519943295; double num3 = p1.Longitude * 0.017453292519943295; double num4 = p2.Latitude * 0.017453292519943295; double num5 = p2.Longitude * 0.017453292519943295; double num6 = num5 - num3; double num7 = num4 - d; double num8 = Math.Pow(Math.Sin(num7 / 2.0), 2.0) + ((Math.Cos(d) * Math.Cos(num4)) * Math.Pow(Math.Sin(num6 / 2.0), 2.0)); double num9 = 2.0 * Math.Atan2(Math.Sqrt(num8), Math.Sqrt(1.0 - num8)); return (6376500.0 * num9); } 

你可以使用System.device.Location

 System.device.Location.GeoCoordinate gc = new System.device.Location.GeoCoordinate(){ Latitude = yourLatitudePt1, Longitude = yourLongitudePt1 }; System.device.Location.GeoCoordinate gc2 = new System.device.Location.GeoCoordinate(){ Latitude = yourLatitudePt2, Longitude = yourLongitudePt2 }; Double distance = gc2.getDistanceTo(gc); 

祝你好运