在c#winform应用程序中,我有一个纬度/经度列表。我可以在sql server(2005)查询中计算,但我不知道我是否可以在c#中执行此操作。
SELECT LAT, LONG, ( 3959 * acos( cos( radians(37) ) * cos( radians( LAT ) ) * cos( radians( LONG ) - radians(-122) ) + sin( radians(37) ) * sin( radians( LAT ) ) ) ) AS distance
FROM Table ORDER BY distance
在sql server中使用此查询我可以订购纬度和经度列表。 但是,在此列表的c#I< lat / long中:
var latLon = new List<LatLonClass>();
使用此列表,如何在列表中执行相同的查询? 谢谢!
答案 0 :(得分:3)
只需查看System.Device.Location
命名空间。
var coord1 = new GeoCoordinate(lat1, lon1);
var coord2 = new GeoCoordinate(lat2, lon2);
var dist = coord1.GetDistanceTo(coord2);
了解更多信息:https://msdn.microsoft.com/en-us/library/system.device.location.geocoordinate(v=vs.110).aspx
现在,计算坐标列表到单个点的距离
List<GeoCoordinate> coordinates = ......;
GeoCoordinate point = ......;
var distances = coordinates.Select(c => c.GetDistanceTo(point))
.OrderBy()
.ToList();
答案 1 :(得分:2)
以下是来自Haversine公式的片段(https://www.stormconsultancy.co.uk/blog/development/code-snippets/the-haversine-formula-in-c-and-sql/
)。看起来它有你需要的东西。
public double HaversineDistance(LatLng pos1, LatLng pos2, DistanceUnit unit)
{
double R = (unit == DistanceUnit.Miles) ? 3960 : 6371;
var lat = (pos2.Latitude - pos1.Latitude).ToRadians();
var lng = (pos2.Longitude - pos1.Longitude).ToRadians();
var h1 = Math.Sin(lat / 2) * Math.Sin(lat / 2) +
Math.Cos(pos1.Latitude.ToRadians()) * Math.Cos(pos2.Latitude.ToRadians()) *
Math.Sin(lng / 2) * Math.Sin(lng / 2);
var h2 = 2 * Math.Asin(Math.Min(1, Math.Sqrt(h1)));
return R * h2;
}
答案 2 :(得分:0)
这取决于您需要的准确结果。我们的地球不是球体,它是椭圆体(可以说半径在6378137m和6356752m之间)。这就是为什么要获得准确的结果,你需要在非常高的水平上知道数学。如果您需要的精度高于0.3%,我建议您使用Charles Karney的GeographicLib - http://geographiclib.sourceforge.net/html/NET/
如果使用@Mark代码,0.3%级别的精度就足够了。