Ejemplo n.º 1
0
 /// <summary>
 /// Get unique depth points from sequence.
 /// </summary>
 /// <param name="inputDepthPoints">Input sequence of <see cref="IDepthPointSource"/></param>
 /// <returns>Sequence of unique <see cref="IDepthPointSource"/></returns>
 public static IEnumerable <IDepthPointSource> GetUniqueDepthPoints(this IEnumerable <IDepthPointSource> inputDepthPoints)
 {
     return(inputDepthPoints
            .GroupBy(point => point.Point)
            .Select(depthPointSourceGroup =>
                    new CsvLogEntry(depthPointSourceGroup.Key,
                                    LinearDimension.FromMeters(depthPointSourceGroup.Average(pnt => pnt.Depth.GetMeters())))));
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns the distance between two <see cref="SonarLogAPI.Primitives.CoordinatePoint" /> on the flat.
        /// </summary>
        /// <param name="lat1">First point <see cref="SonarLogAPI.Primitives.Latitude" /> degrees double value.</param>
        /// <param name="long1">First point <see cref="SonarLogAPI.Primitives.Longitude" /> degrees double value.</param>
        /// <param name="lat2">Second point <see cref="SonarLogAPI.Primitives.Latitude" /> degrees double value.</param>
        /// <param name="long2">Second point <see cref="SonarLogAPI.Primitives.Longitude" /> degrees double value.</param>
        /// <param name="altitude">Point altitude above surface(meters). Zero by default.</param>
        /// <returns>Distance between points</returns>
        public static LinearDimension GetDistanceBetweenPointsOnTheFlat(double lat1, double long1, double lat2, double long2, double altitude = 0)
        {
            double deltaLatRad = (lat2 - lat1) * _d2R;
            double deltaLonRad = (long2 - long1) * _d2R;
            double deltaY      = deltaLatRad * (_earthWgs84MeanRadius + altitude);
            double deltaX      = deltaLonRad * (_earthWgs84MeanRadius + altitude);

            double distanceMeters = Math.Sqrt(Math.Pow(deltaX, 2d) + Math.Pow(deltaY, 2d));

            return(LinearDimension.FromMeters(distanceMeters));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns the distance between two <see cref="SonarLogAPI.Primitives.CoordinatePoint" /> at sphere with WGS84 Mean Radius with Haversine formula.
        /// </summary>
        /// <param name="lat1">First point <see cref="SonarLogAPI.Primitives.Latitude" /> degrees double value.</param>
        /// <param name="long1">First point <see cref="SonarLogAPI.Primitives.Longitude" /> degrees double value.</param>
        /// <param name="lat2">Second point <see cref="SonarLogAPI.Primitives.Latitude" /> degrees double value.</param>
        /// <param name="long2">Second point <see cref="SonarLogAPI.Primitives.Longitude" /> degrees double value.</param>
        /// <param name="altitude">Point altitude above surface(meters). Zero by default.</param>
        /// <returns>Distance between points</returns>
        /// <seealso cref="http://en.wikipedia.org/wiki/Great-circle_distance"/>
        public static LinearDimension GetDistanceBetweenPointsWithHaversine(double lat1, double long1, double lat2, double long2, double altitude = 0)
        {
            //with antipode points modification
            //https://wikimedia.org/api/rest_v1/media/math/render/svg/c3159d773b79d31c3f5ff176a6262fabd20cdbc9
            //converts all degrees to radians
            double lat1Rad      = lat1 * _d2R;
            double lat2Rad      = lat2 * _d2R;
            double longDeltaRad = (long2 - long1) * _d2R;

            double y          = Math.Sqrt(Math.Pow(Math.Cos(lat2Rad) * Math.Sin(longDeltaRad), 2d) + Math.Pow(Math.Cos(lat1Rad) * Math.Sin(lat2Rad) - Math.Sin(lat1Rad) * Math.Cos(lat2Rad) * Math.Cos(longDeltaRad), 2d));
            double x          = Math.Sin(lat1Rad) * Math.Sin(lat2Rad) + Math.Cos(lat1Rad) * Math.Cos(lat2Rad) * Math.Cos(longDeltaRad);
            double deltaSigma = Math.Atan2(y, x);

            return(LinearDimension.FromMeters(deltaSigma * (_earthWgs84MeanRadius + altitude)));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns the distance between two <see cref="CoordinatePoint" /> on an ellipsoid. Inverse Geodesics problem.
        /// </summary>
        /// <param name="lat1">First point <see cref="Primitives.Latitude" /> degrees double value.</param>
        /// <param name="long1">First point <see cref="Primitives.Longitude" /> degrees double value.</param>
        /// <param name="lat2">Second point <see cref="Primitives.Latitude" /> degrees double value.</param>
        /// <param name="long2">Second point <see cref="Primitives.Longitude" /> degrees double value.</param>
        /// <param name="altitude">Point altitude above surface(meters). Zero by default.</param>
        /// <returns>Distance between points.</returns>
        /// <seealso cref="http://www.geogr.msu.ru/cafedra/karta/docs/GOK/gok_lecture_4.pdf"/>
        /// <remarks>This method can return two azimuths to points.</remarks>
        public static LinearDimension GetDistanceBetweenPointsOnAnEllipsoid(double lat1, double long1, double lat2, double long2, double altitude = 0)
        {
            //degree(pow) reduction formula
            double SinPow2(double angleRadians) => (1 - Math.Cos(2 * angleRadians)) / 2;

            double deltaLatitudeRadians   = (lat2 - lat1) * _d2R;
            double deltaLongitudeRadians  = (long2 - long1) * _d2R;
            double middleLongitudeRadians = (lat2 + lat1) * _d2R / 2;
            double meridional             = GetMeridionalForLatitude(Latitude.FromRadians(middleLongitudeRadians));
            double primeVertical          = GetPrimeVerticalForLatitude(Latitude.FromRadians(middleLongitudeRadians));
            double q = deltaLatitudeRadians * meridional *
                       (1 - (2 * Math.Pow(deltaLongitudeRadians, 2d) + Math.Pow(deltaLongitudeRadians, 2d) * SinPow2(meridional)) / 24);
            double p = deltaLongitudeRadians * primeVertical * Math.Cos(middleLongitudeRadians) *
                       (1 + (Math.Pow(deltaLatitudeRadians, 2d) - Math.Pow(deltaLongitudeRadians, 2d) * SinPow2(middleLongitudeRadians)) / 24);

            return(LinearDimension.FromMeters(Math.Sqrt(Math.Pow(q, 2d) + Math.Pow(p, 2d))));
        }
Ejemplo n.º 5
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.º 6
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)));
        }
Ejemplo n.º 7
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));
        }