en seguida coloco una clase que realiza algunos de esos cálculos, en el futuro la seguiré extendiendo
using System;
using System.Net;
using System.Windows;
using System.Device.Location;
namespace F.Phone.Services.Location
{
public class Calculations
{
public const double EarthRadius = 6371;
/// <summary>
/// Return the midpoint between two points (geocoordinates)
/// </summary>
/// <param name="point1">GeoCoordinate1</param>
/// <param name="point2">GeoCoordinate2</param>
/// <returns></returns>
public static GeoCoordinate Midpoint(GeoCoordinate point1, GeoCoordinate point2) {
GeoCoordinate result = new GeoCoordinate();
double Bx = Math.Cos(point2.Latitude) * Math.Cos(point2.Longitude - point1.Longitude );
double By = Math.Cos(point2.Latitude) * Math.Sin(point2.Longitude - point1.Longitude);
double lat3 = Math.Atan2(Math.Sin(point1.Latitude ) + Math.Sin(point2.Latitude),
Math.Sqrt((Math.Cos(point1.Latitude) + Bx) * (Math.Cos(point1.Latitude) + Bx) + By * By));
double lon3 = point1.Longitude + Math.Atan2(By, Math.Cos(point1.Latitude) + Bx);
result.Altitude = point1.Altitude;
result.Latitude = lat3;
result.Longitude = lon3;
return result;
}
/// <summary>
/// Calculates the maximum latitude using by the bearing
/// </summary>
/// <param name="point"></param>
/// <param name="bearing"></param>
/// <returns></returns>
public static double MaxLatitude(GeoCoordinate point, double bearing)
{
return Math.Acos(Math.Abs (Math.Sin(bearing) * Math.Cos(point.Latitude )));
}
/// <summary>
/// Convert from Radians to degrees
/// </summary>
/// <param name="radians">Radians</param>
/// <returns></returns>
public static double ToDegrees(double radians) {
return radians * (180 / Math.PI );
}
/// <summary>
/// Convert Degrees to Radians
/// </summary>
/// <param name="degrees">Degrees</param>
/// <returns></returns>
public static double ToRadians(double degrees) {
return degrees * (Math.PI / 180);
}
/// <summary>
/// Returns the distance between two geocoordinates
/// </summary>
/// <param name="point1"></param>
/// <param name="point2"></param>
/// <returns></returns>
public static double GetDistance(GeoCoordinate point1, GeoCoordinate point2)
{
double result = 0;
double Lat = ToRadians (point2.Latitude - point1.Latitude) ;
double Lon = ToRadians (point2.Longitude - point1.Longitude) ;
double a = Math.Sin(Lat / 2) * Math.Sin(Lat / 2) +
Math.Cos(point1.Latitude * (Math.PI / 180)) * Math.Cos(point2.Latitude * (Math.PI / 180)) *
Math.Sin(Lon / 2) * Math.Sin(Lon / 2);
double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
result = EarthRadius * c;
return result;
}
/// <summary>
/// Bearing
/// </summary>
/// <param name="point1">Start Point </param>
/// <param name="point2">End Point</param>
/// <returns></returns>
public static double Bearing(GeoCoordinate point1, GeoCoordinate point2)
{
double result = 0;
double y = Math.Sin(point1.Longitude) * Math.Cos(point2.Latitude);
double x = Math.Cos(point1.Latitude) * Math.Sin(point2.Latitude) -
Math.Sin(point1.Latitude) * Math.Cos(point2.Latitude) * Math.Cos(point1.Longitude);
result = ToDegrees ( Math.Atan2(y, x));
return result;
}
/// <summary>
/// Calculates the destination point givin a start point, distance and bearing
/// </summary>
/// <param name="point">Start point</param>
/// <param name="distance">Distance</param>
/// <param name="bearing">Bearing</param>
/// <returns></returns>
public static GeoCoordinate Destination(GeoCoordinate point,double distance, double bearing) {
GeoCoordinate result = new GeoCoordinate();
double lat2 = point.Latitude + distance * Math.Cos(bearing);
double dPhi = Math.Log(Math.Tan(lat2 / 2 + Math.PI / 4) / Math.Tan(point.Latitude / 2 + Math.PI / 4));
double q = dPhi != 0 ? (lat2 - point.Latitude) / dPhi : Math.Cos(point.Latitude );
double dLon = distance * Math.Sin(bearing ) / q;
if (Math.Abs(lat2) > Math.PI / 2) lat2 = lat2 > 0 ? Math.PI - lat2 : -(Math.PI - lat2);
double lon2 = (point.Longitude + dLon + Math.PI) % (2 * Math.PI) - Math.PI;
result.Altitude = point.Altitude;
result.Latitude = lat2;
result.Longitude = lon2;
return result;
}
}
}