dot42 を使用してサンプル プロジェクトを作成し、この C# コードを取得してライブラリ内に配置しました。
var gcd = GetGreatCircleDistanceKm(52.0, -1.90, 21.0, 39.0); // returns NaN should be ~4915
public double GetGreatCircleDistanceKm(double startLat, double startLong, double endLat, double endLong)
{
var earthRadius = Constants.EarthRadiusKm;
var φ1 = DegreesToRadians(startLat);
var φ2 = DegreesToRadians(endLat);
var Δφ = DegreesToRadians(endLat - startLat);
var Δλ = DegreesToRadians(endLong - startLong);
var a = Math.Sin(Δφ / 2) * Math.Sin(Δφ / 2) + Math.Cos(φ1) * Math.Cos(φ2) * Math.Sin(Δλ / 2) * Math.Sin(Δλ / 2);
var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
return earthRadius * c;
}
public static double DegreesToRadians(double angle)
{
return Math.PI * angle / 180.0;
}
ただし、問題はc
常に返さNaN
れるため、関数が返されることNaN
です。これと同じ方法は、通常の .net プロジェクトでうまく機能します。
haversine
私は何かを間違って入力したのではないかと考えて、同じ式の多くのバージョンを試しましたが、いいえ、すべて returnNaN
です。
数式のソース: http://www.movable-type.co.uk/scripts/latlong.html
解決策は(奇妙なことに)行うことでした:
var a1 = Δφ/2;
var a = Math.Sin(a1) * Math.Sin(a1) + Math.Cos(φ1) * Math.Cos(φ2) * Math.Sin(Δλ / 2) * Math.Sin(Δλ / 2);
それがどのように機能するのかわかりませんが、機能します。誰かが光を当てることができればお願いします。
完全修正版:
/// <summary>
/// Gets the shortest possible distance between two points on earth
/// </summary>
/// <param name="startLat"></param>
/// <param name="startLong"></param>
/// <param name="endLat"></param>
/// <param name="endLong"></param>
/// <returns></returns>
public double GetGreatCircleDistanceKm(double startLat, double startLong, double endLat, double endLong)
{
var startLatRad = DegreesToRadians(startLat);
var endLatRad = DegreesToRadians(endLat);
var latDiffRad = DegreesToRadians(endLat - startLat);
var longDiffRad = DegreesToRadians(endLong - startLong);
var halfLatDiff = latDiffRad/2;
var a = Math.Sin(halfLatDiff) * Math.Sin(halfLatDiff) + Math.Cos(startLatRad) * Math.Cos(endLatRad) * Math.Sin(longDiffRad / 2) * Math.Sin(longDiffRad / 2);
var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
return Constants.EarthRadiusKm * c;
}