/// <summary>
        /// Let first point latitude be la1,
        /// longitude as lo1,
        /// d be distance,
        /// R as radius of Earth,
        /// Ad be the angular distance i.e d/R and
        /// θ be the bearing,
        /// Here is the formula to find the second point, when first point, bearing and distance is known:
        /// latitude of second point = la2 = asin(sin la1 * cos Ad + cos la1 * sin Ad * cos θ), and
        /// longitude  of second point = lo2 = lo1 + atan2(sin θ * sin Ad * cos la1, cos Ad – sin la1 * sin la2)
        /// </summary>
        /// <param name="oldLatitude"></param>
        /// <param name="oldLongitude"></param>
        /// <param name="bearing"></param>
        /// <param name="distance"></param>
        /// <returns>New set of latitude and longitude points</returns>
        public static (double, double) CalculateNewSetOfPoints(
            double oldLatitude, double oldLongitude,
            double bearing, double distance)
        {
            oldLatitude  = HaversineFormula.ConvertDegreesToRadians(oldLatitude);
            oldLongitude = HaversineFormula.ConvertDegreesToRadians(oldLongitude);
            double Ad           = distance / R;
            double newLatitude  = Math.Asin(Math.Sin(oldLatitude) * Math.Cos(Ad) + Math.Cos(oldLatitude) * Math.Sin(Ad) * Math.Cos(bearing));
            double newLongitude = oldLongitude + Math.Atan2(Math.Sin(bearing) * Math.Sin(Ad) * Math.Cos(oldLatitude), Math.Cos(Ad) - Math.Sin(oldLatitude) * Math.Sin(newLatitude));

            return(Math.Round(HaversineFormula.ConvertRadiansToDegrees(newLatitude), 8), Math.Round(HaversineFormula.ConvertRadiansToDegrees(newLongitude), 8));
        }
        /// <summary>
        /// a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)
        /// c = 2 ⋅ atan2( √a, √(1−a) )
        /// d = R ⋅ c
        /// where   φ is latitude, λ is longitude, R is earth’s radius
        /// note that angles need to be in radians to pass to trig functions!
        /// </summary>
        /// <param name="firstLatitude"></param>
        /// <param name="firstLongitude"></param>
        /// <param name="secondLatitude"></param>
        /// <param name="secondLongidute"></param>
        /// <returns>Distance between chosen points</returns>
        public static double CalculateDistanceBetweenTwoPoints(
            double firstLatitude, double firstLongitude,
            double secondLatitude, double secondLongidute)
        {
            firstLatitude   = HaversineFormula.ConvertDegreesToRadians(firstLatitude);
            firstLongitude  = HaversineFormula.ConvertDegreesToRadians(firstLongitude);
            secondLatitude  = HaversineFormula.ConvertDegreesToRadians(secondLatitude);
            secondLongidute = HaversineFormula.ConvertDegreesToRadians(secondLongidute);
            double a = 0.5 - Math.Cos(secondLatitude - firstLatitude) / 2 + Math.Cos(firstLatitude) * Math.Cos(secondLatitude) * (1 - Math.Cos(secondLongidute - firstLongitude)) / 2;

            // ili 2*R*Math.atan2(sqrt(a), sqrt(1-a));
            return(2 * R * Math.Asin(Math.Sqrt(a)));
        }
        /// <summary>
        /// Bearing: The horizontal angle at a given point, measured clockwise from magnetic north or true north to a second point.
        /// Let ‘R’ be the radius of Earth,
        /// ‘L’ be the longitude,
        /// ‘θ’ be latitude,
        /// ‘β‘ be Bearing.
        /// Bearing from point A to B, can be calculated as,
        /// β = atan2(X, Y),
        /// where, X and Y are two quantities and can be calculated as:
        /// X = cos θb* sin ∆L
        /// Y = cos θa* sin θb – sin θa * cos θb * cos ∆L
        /// </summary>
        /// <param name="firstLatitude"></param>
        /// <param name="firstLongitude"></param>
        /// <param name="secondLatitude"></param>
        /// <param name="secondLongidute"></param>
        /// <returns>Bearing from first to second point</returns>
        public static double Bearing(
            double firstLatitude, double firstLongitude,
            double secondLatitude, double secondLongidute)
        {
            firstLatitude   = HaversineFormula.ConvertDegreesToRadians(firstLatitude);
            firstLongitude  = HaversineFormula.ConvertDegreesToRadians(firstLongitude);
            secondLatitude  = HaversineFormula.ConvertDegreesToRadians(secondLatitude);
            secondLongidute = HaversineFormula.ConvertDegreesToRadians(secondLongidute);
            double firstPoint  = Math.Cos(secondLatitude) * Math.Sin(secondLongidute - firstLongitude);
            double secondPoint = (Math.Cos(firstLatitude) * Math.Sin(secondLatitude)) - (Math.Sin(firstLatitude) * Math.Cos(secondLatitude) * Math.Cos(secondLongidute - firstLongitude));

            return(Math.Atan2(firstPoint, secondPoint));
        }
        public static IEnumerable <(double, double)> MoveAtRoute(
            double firstLatitude, double firstLongitude,
            double secondLatitude, double secondLongidute,
            double stepLengthToMove, double precisionOfStep)
        {
            firstLatitude   = HaversineFormula.ConvertDegreesToRadians(firstLatitude);
            firstLongitude  = HaversineFormula.ConvertDegreesToRadians(firstLongitude);
            secondLatitude  = HaversineFormula.ConvertDegreesToRadians(secondLatitude);
            secondLongidute = HaversineFormula.ConvertDegreesToRadians(secondLongidute);

            IList <(double, double)> newLatLng = new List <(double, double)>();

            while (HaversineFormula.CalculateDistanceBetweenTwoPoints(
                       firstLatitude, firstLongitude,
                       secondLatitude, secondLongidute) > precisionOfStep)
            {
                double bearing = HaversineFormula.Bearing(firstLatitude, firstLongitude,
                                                          secondLatitude, secondLongidute);
                newLatLng.Add(HaversineFormula.CalculateNewSetOfPoints(firstLatitude, firstLongitude, bearing, precisionOfStep));
            }
            return(newLatLng);
        }