我想计算两个地理点的距离。这些点以经度和纬度给出。
坐标为:
第1点:36.578581,-118.291994
第2点:36.23998,-116.83171
这是一个比较结果的网站:
http://www.movable-type.co.uk/scripts/latlong.html
这里是我从这个链接中使用的代码: Calculate distance between two points in google maps V3
const double PIx = Math.PI;
const double RADIO = 6378.16;
/// <summary>
/// Convert degrees to Radians
/// </summary>
/// <param name="x">Degrees</param>
/// <returns>The equivalent in radians</returns>
public static double Radians(double x)
{
return x * PIx / 180;
}
/// <summary>
/// Calculate the distance between two places.
/// </summary>
/// <param name="lon1"></param>
/// <param name="lat1"></param>
/// <param name="lon2"></param>
/// <param name="lat2"></param>
/// <returns></returns>
public static double DistanceBetweenPlaces(double lon1, double lat1, double lon2, double lat2)
{
double R = 6371; // km
double dLat = Radians(lat2 - lat1);
double dLon = Radians(lon2 - lon1);
lat1 = Radians(lat1);
lat2 = Radians(lat2);
double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Sin(dLon / 2) * Math.Sin(dLon / 2) * Math.Cos(lat1) * Math.Cos(lat2);
double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
double d = R * c;
return d;
}
Console.WriteLine(DistanceAlgorithm.DistanceBetweenPlaces(36.578581, -118.291994, 36.23998, -116.83171));
问题是我得到了两个不同的结果。
我的结果:163,307公里
网站结果:136公里
任何建议???
TORTI
答案 0 :(得分:22)
你的公式几乎是正确的,但你必须交换经度和纬度的参数
Console.WriteLine(DistanceAlgorithm.DistanceBetweenPlaces(-118.291994, 36.578581, -116.83171, 36.23998)); // = 136 km
我正在使用简化公式:
// cos(d) = sin(φА)·sin(φB) + cos(φА)·cos(φB)·cos(λА − λB),
// where φА, φB are latitudes and λА, λB are longitudes
// Distance = d * R
public static double DistanceBetweenPlaces(double lon1, double lat1, double lon2, double lat2)
{
double R = 6371; // km
double sLat1 = Math.Sin(Radians(lat1));
double sLat2 = Math.Sin(Radians(lat2));
double cLat1 = Math.Cos(Radians(lat1));
double cLat2 = Math.Cos(Radians(lat2));
double cLon = Math.Cos(Radians(lon1) - Radians(lon2));
double cosD = sLat1*sLat2 + cLat1*cLat2*cLon;
double d = Math.Acos(cosD);
double dist = R * d;
return dist;
}
测试:
(赤道距离):经度0,100;纬度= 0,0; DistanceBetweenPlaces(0,0,100,0)= 11119.5 km
(北极距离):经度0,100;纬度= 90,90; DistanceBetweenPlaces(0,90,100,90)= 0 km
经度:-118.291994,-116.83171;纬度:36.578581,36.23998 = 135.6 km
经度:36.578581,36.23998;纬度:-118.291994,-116.83171 = 163.2 km
祝你好运
P.S。在web site用于结果比较,对于每个点,第一个文本框是纬度,第二个 - 经度
答案 1 :(得分:20)
当您使用框架4.0时,我会建议GeoCoordinate
类。
// using System.Device.Location;
GeoCoordinate c1 = new GeoCoordinate(36.578581, -118.291994);
GeoCoordinate c2 = new GeoCoordinate(36.23998, -116.83171);
double distanceInKm = c1.GetDistanceTo(c2) / 1000;
// Your result is: 136,111419742602
您必须添加对System.Device.dll的引用。
答案 2 :(得分:2)
在我几年前发表的文章中(链接:http://www.codeproject.com/Articles/469500/Edumatter-School-Math-Calculators-and-Equation-Sol)我已经描述了3个有用的Functions
来计算2个地理点之间的距离(换句话说,大圆(顺时针)距离在2个地理点之间的地球上),在准确性/性能方面有所不同:
// Haversine formula to calculate great-circle distance between two points on Earth
private const double _radiusEarthMiles = 3959;
private const double _radiusEarthKM = 6371;
private const double _m2km = 1.60934;
private const double _toRad = Math.PI / 180;
/// <summary>
/// Haversine formula to calculate
/// great-circle (orthodromic) distance on Earth
/// High Accuracy, Medium speed
/// </summary>
/// <param name="Lat1">double: 1st point Latitude</param>
/// <param name="Lon1">double: 1st point Longitude</param>
/// <param name="Lat2">double: 2nd point Latitude</param>
/// <param name="Lon2">double: 2nd point Longitude</param>
/// <returns>double: distance in miles</returns>
public static double DistanceMilesHaversine(double Lat1,
double Lon1,
double Lat2,
double Lon2)
{
try
{
double _radLat1 = Lat1 * _toRad;
double _radLat2 = Lat2 * _toRad;
double _dLatHalf = (_radLat2 - _radLat1) / 2;
double _dLonHalf = Math.PI * (Lon2 - Lon1) / 360;
// intermediate result
double _a = Math.Sin(_dLatHalf);
_a *= _a;
// intermediate result
double _b = Math.Sin(_dLonHalf);
_b *= _b * Math.Cos(_radLat1) * Math.Cos(_radLat2);
// central angle, aka arc segment angular distance
double _centralAngle = 2 * Math.Atan2(Math.Sqrt(_a + _b), Math.Sqrt(1 - _a - _b));
// great-circle (orthodromic) distance on Earth between 2 points
return _radiusEarthMiles * _centralAngle;
}
catch { throw; }
}
// Spherical law of cosines formula to calculate great-circle distance between two points on Earth
/// <summary>
/// Spherical Law of Cosines formula to calculate
/// great-circle (orthodromic) distance on Earth;
/// High Accuracy, Medium speed
/// http://en.wikipedia.org/wiki/Spherical_law_of_cosines
/// </summary>
/// <param name="Lat1">double: 1st point Latitude</param>
/// <param name="Lon1">double: 1st point Longitude</param>
/// <param name="Lat2">double: 2nd point Latitude</param>
/// <param name="Lon2">double: 2nd point Longitude</param>
/// <returns>double: distance in miles</returns>
public static double DistanceMilesSLC( double Lat1,
double Lon1,
double Lat2,
double Lon2)
{
try
{
double _radLat1 = Lat1 * _toRad;
double _radLat2 = Lat2 * _toRad;
double _radLon1 = Lon1 * _toRad;
double _radLon2 = Lon2 * _toRad;
// central angle, aka arc segment angular distance
double _centralAngle = Math.Acos(Math.Sin(_radLat1) * Math.Sin(_radLat2) +
Math.Cos(_radLat1) * Math.Cos(_radLat2) * Math.Cos(_radLon2 - _radLon1));
// great-circle (orthodromic) distance on Earth between 2 points
return _radiusEarthMiles * _centralAngle;
}
catch { throw; }
}
// Great-circle distance calculation using Spherical Earth projection formula**
/// <summary>
/// Spherical Earth projection to a plane formula (using Pythagorean Theorem)
/// to calculate great-circle (orthodromic) distance on Earth.
/// http://en.wikipedia.org/wiki/Geographical_distance
/// central angle =
/// Sqrt((_radLat2 - _radLat1)^2 + (Cos((_radLat1 + _radLat2)/2) * (Lon2 - Lon1))^2)
/// Medium Accuracy, Fast,
/// relative error less than 0.1% in search area smaller than 250 miles
/// </summary>
/// <param name="Lat1">double: 1st point Latitude</param>
/// <param name="Lon1">double: 1st point Longitude</param>
/// <param name="Lat2">double: 2nd point Latitude</param>
/// <param name="Lon2">double: 2nd point Longitude</param>
/// <returns>double: distance in miles</returns>
public static double DistanceMilesSEP(double Lat1,
double Lon1,
double Lat2,
double Lon2)
{
try
{
double _radLat1 = Lat1 * _toRad;
double _radLat2 = Lat2 * _toRad;
double _dLat = (_radLat2 - _radLat1);
double _dLon = (Lon2 - Lon1) * _toRad;
double _a = (_dLon) * Math.Cos((_radLat1 + _radLat2) / 2);
// central angle, aka arc segment angular distance
double _centralAngle = Math.Sqrt(_a * _a + _dLat * _dLat);
// great-circle (orthodromic) distance on Earth between 2 points
return _radiusEarthMiles * _centralAngle;
}
catch { throw; }
}
函数以英里为单位返回结果;找到以km为单位的距离乘以1.60934的结果(见private const double _m2km = 1.60934
)。
相关样本:找到距离point1(36.578581,-118.291994)和point2(36.23998,-116.83171)三个上述函数产生以下结果(km):
136.00206654936932
136.00206654937023
136.00374497149613
和计算器(链接:http://www.movable-type.co.uk/scripts/latlong.html)给出了结果:136.0
希望这可能会有所帮助。最好的问候,
答案 3 :(得分:1)
我使用Wikipedia中的公式并将其放在lambda函数中:
Func<double, double, double, double, double> CalcDistance = (lat1, lon1, lat2, lon2) =>
{
Func<double, double> Radians = (angle) =>
{
return angle * (180.0 / Math.PI);
};
const double radius = 6371;
double delataSigma = Math.Acos(Math.Sin(Radians(lat1)) * Math.Sin(Radians(lat2)) +
Math.Cos(Radians(lat1)) * Math.Cos(Radians(lat2)) * Math.Cos(Math.Abs(Radians(lon2) - Radians(lon1))));
double distance = radius * delataSigma;
return distance;
};
答案 4 :(得分:0)
尝试这个...我以前使用过这是应用程序 - 它非常准确。请原谅我没有给予最初发表这篇文章的聪明人的应有的信任,我将它从java转换为C#:
namespace Sample.Geography
{
using System;
public class GeodesicDistance
{
private static double DegsToRadians(double degrees)
{
return (0.017453292519943295 * degrees);
}
public static double? GetDistance(double lat1, double lon1, double lat2, double lon2)
{
long num = 0x615299L;
double num2 = 6356752.3142;
double num3 = 0.0033528106647474805;
double num4 = DegsToRadians(lon2 - lon1);
double a = Math.Atan((1 - num3) * Math.Tan(DegsToRadians(lat1)));
double num6 = Math.Atan((1 - num3) * Math.Tan(DegsToRadians(lat2)));
double num7 = Math.Sin(a);
double num8 = Math.Sin(num6);
double num9 = Math.Cos(a);
double num10 = Math.Cos(num6);
double num11 = num4;
double num12 = 6.2831853071795862;
int num13 = 20;
double y = 0;
double x = 0;
double num18 = 0;
double num20 = 0;
double num22 = 0;
while ((Math.Abs((double) (num11 - num12)) > 1E-12) && (--num13 > 0))
{
double num14 = Math.Sin(num11);
double num15 = Math.Cos(num11);
y = Math.Sqrt(((num10 * num14) * (num10 * num14)) + (((num9 * num8) - ((num7 * num10) * num15)) * ((num9 * num8) - ((num7 * num10) * num15))));
if (y == 0)
{
return 0;
}
x = (num7 * num8) + ((num9 * num10) * num15);
num18 = Math.Atan2(y, x);
double num19 = ((num9 * num10) * num14) / y;
num20 = 1 - (num19 * num19);
if (num20 == 0)
{
num22 = 0;
}
else
{
num22 = x - (((2 * num7) * num8) / num20);
}
double num21 = ((num3 / 16) * num20) * (4 + (num3 * (4 - (3 * num20))));
num12 = num11;
num11 = num4 + ((((1 - num21) * num3) * num19) * (num18 + ((num21 * y) * (num22 + ((num21 * x) * (-1 + ((2 * num22) * num22)))))));
}
if (num13 == 0)
{
return null;
}
double num23 = (num20 * ((num * num) - (num2 * num2))) / (num2 * num2);
double num24 = 1 + ((num23 / 16384) * (4096 + (num23 * (-768 + (num23 * (320 - (175 * num23)))))));
double num25 = (num23 / 1024) * (256 + (num23 * (-128 + (num23 * (74 - (47 * num23))))));
double num26 = (num25 * y) * (num22 + ((num25 / 4) * ((x * (-1 + ((2 * num22) * num22))) - ((((num25 / 6) * num22) * (-3 + ((4 * y) * y))) * (-3 + ((4 * num22) * num22))))));
return new double?((num2 * num24) * (num18 - num26));
}
}
}
答案 5 :(得分:0)
我只是尝试在GeoDataSource上编码,它运行得非常好: http://www.geodatasource.com/developers/c-sharp
答案 6 :(得分:0)
我认为您正在交换纬度和经度值。尝试更正这些错误或更改参数顺序。