/// <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()))))); }
/// <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)); }
/// <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))); }
/// <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)))); }