Today I want to share with you with two functions related with GPS. The first of them calculates the distance between two points. The distance is given in meters.
/// <summary>
/// Calculates the distance between two points.
/// </summary>
/// <param name="firstCoordinate">The first coordinate.</param>
/// <param name="secondCoordinate">The second coordinate.</param>
/// <returns>Distance between points in meters</returns>
private static double CalculateDistance(GeoCoordinate firstCoordinate, GeoCoordinate secondCoordinate)
{
double R = 6371.0; // km
double lon1 = DegToRad(firstCoordinate.Longitude);
double lat1 = DegToRad(firstCoordinate.Latitude);
double lon2 = DegToRad(secondCoordinate.Longitude);
double lat2 = DegToRad(secondCoordinate.Latitude);
double dLat = lat2 - lat1;
double dLon = lon2 - lon1;
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));
return R * c * 1000;
}
While the second function is used to find the coordinates of a point, which is located in the middle of the two given points.
/// <summary>
/// Calculates the middle point coordinate.
/// </summary>
/// <param name="firstCoordinate">The first coordinate.</param>
/// <param name="secondCoordinate">The second coordinate.</param>
/// <returns>Middle point coordinate</returns>
private GeoCoordinate CalculateMidPoint(GeoCoordinate firstCoordinate, GeoCoordinate secondCoordinate)
{
double lon1 = DegToRad(firstCoordinate.Longitude);
double lat1 = DegToRad(firstCoordinate.Latitude);
double lon2 = DegToRad(secondCoordinate.Longitude);
double lat2 = DegToRad(secondCoordinate.Latitude);
double deltaLong = lon2 - lon1;
double Bx = Math.Cos(lat2) * Math.Cos(deltaLong);
double By = Math.Cos(lat2) * Math.Sin(deltaLong);
double lat3 = RadToDeg(Math.Atan2(Math.Sin(lat1) + Math.Sin(lat2), Math.Sqrt((Math.Cos(lat1) + Bx) * (Math.Cos(lat1) + Bx) + By * By)));
double lon3 = RadToDeg(lon1 + Math.Atan2(By, Math.Cos(lat1) + Bx));
return new GeoCoordinate(lat3, lon3);
}
Both functions use two auxiliary methods, which convert degrees to radians and vice versa.
/// <summary>
/// Converts radians to degrees
/// </summary>
/// <param name="radians">The radians.</param>
/// <returns>The degrees.</returns>
private static double RadToDeg(double radians)
{
return radians * (180 / Math.PI);
}
/// <summary>
/// Converts degrees to radians
/// </summary>
/// <param name="degrees">The degrees.</param>
/// <returns>The radians</returns>
private static double DegToRad(double degrees)
{
return degrees * (Math.PI / 180);
}
I hope, someone will find that functions useful.


Ładna publikacja,
Moja propozycja aby zwiększyć dokładności, zdefiniować średnicę planety co do metra np. dla WGS84 było by jak poniżej:
#define EARTH_MAJOR_AXIS_WGS84 (double) 6378137.0
Thanks, that was useful.