jueves, 10 de marzo de 2011

Libreria basica de calculos con geocoordenadas

En algunas ocasiones es util realizar cálculos como distancias, puntos medios, latitud máxima, punto de destino, o el bearing.


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;
        }

    }
}


Transacciones Fiori

  /UI2/CACHE Register service for UI2 cache use /UI2/CACHE_DEL Delete cache entries /UI2/CHIP Chip Registration /UI2/CUST Customizing of UI ...