Ejemplo n.º 1
0
        /// <summary>
        /// Get <see cref="CoordinatePoint" /> at distance and direction on an ellipsoid.
        /// </summary>
        /// <param name="basePoint">Source <see cref="CoordinatePoint"/>.</param>
        /// <param name="distance">Distance to a new point, meters.</param>
        /// <param name="azimuth">Azimuth to a new point, radians.</param>
        /// <param name="backAzimuth">Azimuth from a new point to base point, radians.</param>
        /// <returns><see cref="CoordinatePoint" /> at specified distance and direction from the base point.</returns>
        public static CoordinatePoint GetCoordinatePointAtDistanceAndDirectionOnAnEllipsoid(CoordinatePoint basePoint, LinearDimension distance, double azimuth, out double backAzimuth)
        {
            double deltaLatitude;
            double deltaLongitude;
            double deltaAzimuth;
            double newDeltaLatitude  = 0;
            double newDeltaLongitude = 0;
            double newDeltaAzimuth   = 0;

            do
            {
                deltaLatitude  = newDeltaLatitude;
                deltaLongitude = newDeltaLongitude;
                deltaAzimuth   = newDeltaAzimuth;

                double iterationLatitude = basePoint.Latitude.ToRadians() + deltaLatitude / 2;
                double iterationAzimuth  = azimuth + deltaAzimuth / 2;

                double beta  = distance.GetMeters() * Math.Cos(iterationAzimuth) / GetMeridionalForLatitude(Latitude.FromRadians(iterationLatitude));
                double sigma = distance.GetMeters() * Math.Sin(iterationAzimuth) / (GetPrimeVerticalForLatitude(Latitude.FromRadians(iterationLatitude)) * Math.Cos(iterationLatitude));
                double alpha = deltaLongitude * Math.Sin(iterationLatitude);

                newDeltaLatitude  = beta * (1 + (2 * Math.Pow(sigma, 2d) + Math.Pow(alpha, 2d)) / 24);
                newDeltaLongitude = sigma * (1 + (Math.Pow(alpha, 2d) - Math.Pow(beta, 2d)) / 24);
                newDeltaAzimuth   = alpha * (1 + (3 * Math.Pow(beta, 2d) + 2 * Math.Pow(sigma, 2d) - 2 * Math.Pow(alpha, 2d)) / 24);
            }while (Math.Abs(newDeltaLatitude - deltaLatitude) > 0.0000001d || Math.Abs(deltaLongitude - newDeltaLongitude) > 0.0000001d);

            backAzimuth = azimuth + newDeltaAzimuth + Math.PI;
            return(new CoordinatePoint(Latitude.FromRadians(basePoint.Latitude.ToRadians() + newDeltaLatitude),
                                       Longitude.FromRadians(basePoint.Longitude.ToRadians() + newDeltaLongitude)));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Get <see cref="CoordinatePoint" /> at distance and direction on the flat.
        /// </summary>
        /// <param name="basePoint">Source <see cref="CoordinatePoint"/></param>
        /// <param name="distance">Distance to a new point.</param>
        /// <param name="azimuth">Direction from one point to another in radians.</param>
        /// <returns><see cref="CoordinatePoint"/> at specified distance and direction from the given point.</returns>
        public static CoordinatePoint GetCoordinatePointAtDistanceAndDirectionOnTheFlat(CoordinatePoint basePoint, LinearDimension distance, double azimuth)
        {
            var deltaLatitudeGrad  = distance.GetMeters() * Math.Cos(azimuth) / (_earthWgs84MeanRadius * _d2R);
            var deltaLongitudeGrad = distance.GetMeters() * Math.Sin(azimuth) / (_earthWgs84MeanRadius * _d2R);

            return(new CoordinatePoint(basePoint.Latitude.ToDegrees() + deltaLatitudeGrad, basePoint.Longitude.ToDegrees() + deltaLongitudeGrad));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Get <see cref="CoordinatePoint" /> at distance and direction on sphere with Haversine.
        /// </summary>
        /// <param name="basePoint">Source <see cref="CoordinatePoint"/>.</param>
        /// <param name="distance">Distance to a new point, meters.</param>
        /// <param name="azimuth">Azimuth to a new point, radians.</param>
        /// <param name="backAzimuth">Azimuth from a new point to base point, radians.</param>
        /// <returns><see cref="CoordinatePoint" /> at specified distance and direction from the base point.</returns>
        /// <seealso cref="http://www.movable-type.co.uk/scripts/latlong.html"/>
        public static CoordinatePoint GetCoordinatePointAtDistanceAndDirectionWithHaversine(CoordinatePoint basePoint, LinearDimension distance, double azimuth, out double backAzimuth)
        {
            var startLatitudeRadians = basePoint.Latitude.ToRadians();
            var dR = distance.GetMeters() / _earthWgs84MeanRadius;

            var finishLatitudeRadians = Math.Asin(Math.Sin(startLatitudeRadians) * Math.Cos(dR) +
                                                  Math.Cos(startLatitudeRadians) * Math.Sin(dR) * Math.Cos(azimuth));
            var finishLongitudeRadians = basePoint.Longitude.ToRadians() +
                                         Math.Atan2(Math.Sin(azimuth) * Math.Sin(dR) * Math.Cos(startLatitudeRadians), Math.Cos(dR) - Math.Sin(startLatitudeRadians) * Math.Sin(finishLatitudeRadians));

            var y = Math.Sin(finishLongitudeRadians - basePoint.Longitude.ToRadians()) * Math.Cos(finishLatitudeRadians);
            var x = Math.Cos(startLatitudeRadians) * Math.Sin(finishLatitudeRadians) -
                    Math.Sin(startLatitudeRadians) * Math.Cos(finishLatitudeRadians) * Math.Cos(finishLongitudeRadians - basePoint.Longitude.ToRadians());

            backAzimuth = Math.Atan2(y, x) + Math.PI;

            return(new CoordinatePoint(Latitude.FromRadians(finishLatitudeRadians), Longitude.FromRadians(finishLongitudeRadians)));
        }