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.