コード例 #1
0
        private static CrsdistResult Crsdist(double lat1, double lon1, double lat2, double lon2)
        { // radian args
            /* compute course and Distance (spherical) */
            double crs12, crs21;
            double argacos;

            if ((lat1 + lat2 == 0.0) && (MathEx.Abs(lon1 - lon2) == MathEx.PI) && (MathEx.Abs(lat1) != (MathEx.PI / 180) * 90.0))
            {
                throw new ArgumentException("Course between antipodal points is undefined");
            }

            double d = MathEx.Acos(MathEx.Sin(lat1) * MathEx.Sin(lat2) + MathEx.Cos(lat1) * MathEx.Cos(lat2) * MathEx.Cos(lon1 - lon2));

            if ((d == 0.0) || (lat1 == -(MathEx.PI / 180) * 90.0))
            {
                crs12 = 2 * MathEx.PI;
            }
            else if (lat1 == (MathEx.PI / 180) * 90.0)
            {
                crs12 = MathEx.PI;
            }
            else
            {
                argacos = (MathEx.Sin(lat2) - MathEx.Sin(lat1) * MathEx.Cos(d)) / (MathEx.Sin(d) * MathEx.Cos(lat1));
                if (MathEx.Sin(lon2 - lon1) < 0)
                {
                    crs12 = Acosf(argacos);
                }
                else
                {
                    crs12 = 2 * MathEx.PI - Acosf(argacos);
                }
            }
            if ((d == 0.0) || (lat2 == -(MathEx.PI / 180) * 90.0))
            {
                crs21 = 0.0;
            }
            else if (lat2 == (MathEx.PI / 180) * 90.0)
            {
                crs21 = MathEx.PI;
            }
            else
            {
                argacos = (MathEx.Sin(lat1) - MathEx.Sin(lat2) * MathEx.Cos(d)) / (MathEx.Sin(d) * MathEx.Cos(lat2));
                if (MathEx.Sin(lon1 - lon2) < 0)
                {
                    crs21 = Acosf(argacos);
                }
                else
                {
                    crs21 = 2 * MathEx.PI - Acosf(argacos);
                }
            }

            CrsdistResult outValue = new CrsdistResult {
                _d = d, _crs12 = crs12, _crs21 = crs21
            };

            return(outValue);
        }
コード例 #2
0
        private CrsdistResult ComputeFormCD(GeoLatLng pt1, GeoLatLng pt2)
        {
            double        d, crs12, crs21;
            CrsdistResult outValue = new CrsdistResult();
            double        lat1     = pt1.LatRadians();
            double        lat2     = pt2.LatRadians();
            double        lon1     = -pt1.LngRadians();
            double        lon2     = -pt2.LngRadians();
            double        dc       = _currentUnit == UNIT_NM ? 1 : 1.852;

            if (_currentEarthMode == EARTH_MODEL_SPHERE)
            {
                // spherical code// compute crs and Distance
                CrsdistResult cd = Crsdist(lat1, lon1, lat2, lon2);
                crs12 = cd._crs12 * (180 / MathEx.PI);
                crs21 = cd._crs21 * (180 / MathEx.PI);
                d     = cd._d * (180 / MathEx.PI) * 60 * dc; // go to physical units
            }
            else
            {
                // elliptic code // ellipse uses East negative
                CrsdistResult cde = CrsdistEll(lat1, -lon1, lat2, -lon2, _currentEarthMode);
                crs12 = cde._crs12 * (180 / MathEx.PI);
                crs21 = cde._crs21 * (180 / MathEx.PI);
                d     = cde._d * dc; // go to physical units
            }
            outValue._crs12 = crs12;
            outValue._crs21 = crs21;
            outValue._d     = d;
            return(outValue);
        }
コード例 #3
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 18JUN2009  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Calculate the Distance between two point in great circle.
         * @param pt1  the first location.
         * @param pt2  the second location.
         * @return the Distance and course between the 2 point.
         */
        internal GeoLatLng CalculateDistanceAndCourse(GeoLatLng pt1, GeoLatLng pt2)
        {
            CrsdistResult ret  = ComputeFormCD(pt1, pt2);
            GeoLatLng     ret1 = new GeoLatLng(ret._crs12, ret._d);

            return(ret1);
        }
コード例 #4
0
        private CrsdistResult ComputeFormCD(GeoLatLng pt1, GeoLatLng pt2)
        {
            double d, crs12, crs21;
            CrsdistResult outValue = new CrsdistResult();
            double lat1 = pt1.LatRadians();
            double lat2 = pt2.LatRadians();
            double lon1 = -pt1.LngRadians();
            double lon2 = -pt2.LngRadians();
            double dc = _currentUnit == UNIT_NM ? 1 : 1.852;

            if (_currentEarthMode == EARTH_MODEL_SPHERE)
            {
                // spherical code// compute crs and Distance
                CrsdistResult cd = Crsdist(lat1, lon1, lat2, lon2);
                crs12 = cd._crs12 * (180 / MathEx.PI);
                crs21 = cd._crs21 * (180 / MathEx.PI);
                d = cd._d * (180 / MathEx.PI) * 60 * dc; // go to physical units
            }
            else
            {
                // elliptic code // ellipse uses East negative
                CrsdistResult cde = CrsdistEll(lat1, -lon1, lat2, -lon2, _currentEarthMode);
                crs12 = cde._crs12 * (180 / MathEx.PI);
                crs21 = cde._crs21 * (180 / MathEx.PI);
                d = cde._d * dc; // go to physical units
            }
            outValue._crs12 = crs12;
            outValue._crs21 = crs21;
            outValue._d = d;
            return outValue;
        }
コード例 #5
0
        private static CrsdistResult CrsdistEll(double glat1, double glon1, double glat2, double glon2, int ellipse)
        {
            // glat1 initial geodetic latitude in radians N positive
            // glon1 initial geodetic longitude in radians E positive
            // glat2 final geodetic latitude in radians N positive
            // glon2 final geodetic longitude in radians E positive
            double a = EarthModel[ellipse][0];
            double f = 1 / EarthModel[ellipse][1];
            //alert("a="+a+" f="+f)
            double sx = 0, cx = 0, sy = 0, cy = 0, y = 0;
            double c2A = 0, cz = 0, e = 0, c;
            const double eps = 0.00000000005;
            double iter = 1;
            const double maxiter = 100;
            CrsdistResult outValue = new CrsdistResult();
            if ((glat1 + glat2 == 0.0) && (MathEx.Abs(glon1 - glon2) == MathEx.PI))
            {
                glat1 = glat1 + 0.00001; // allow algorithm to complete

            }
            if (glat1 == glat2 && (glon1 == glon2 || MathEx.Abs(MathEx.Abs(glon1 - glon2) - 2 * MathEx.PI) < eps))
            {

                outValue._d = 0;
                outValue._crs12 = 0;
                outValue._crs21 = MathEx.PI;
                return outValue;
            }
            double r = 1 - f;
            double tu1 = r * MathEx.Tan(glat1);
            double tu2 = r * MathEx.Tan(glat2);
            double cu1 = 1.0 / MathEx.Sqrt(1.0 + tu1 * tu1);
            double su1 = cu1 * tu1;
            double cu2 = 1.0 / MathEx.Sqrt(1.0 + tu2 * tu2);
            double s1 = cu1 * cu2;
            double b1 = s1 * tu2;
            double f1 = b1 * tu1;
            double x = glon2 - glon1;
            double d = x + 1;
            while ((MathEx.Abs(d - x) > eps) && (iter < maxiter))
            {
                iter = iter + 1;
                sx = MathEx.Sin(x);
                cx = MathEx.Cos(x);
                tu1 = cu2 * sx;
                tu2 = b1 - su1 * cu2 * cx;
                sy = MathEx.Sqrt(tu1 * tu1 + tu2 * tu2);
                cy = s1 * cx + f1;
                y = Atan2(sy, cy);
                double sa = s1 * sx / sy;
                c2A = 1 - sa * sa;
                cz = f1 + f1;
                if (c2A > 0.0)
                {
                    cz = cy - cz / c2A;
                }
                e = cz * cz * 2.0 - 1.0;
                c = ((-3.0 * c2A + 4.0) * f + 4.0) * c2A * f / 16.0;
                d = x;
                x = ((e * cy * c + cz) * sy * c + y) * sa;
                x = (1.0 - c) * x * f + glon2 - glon1;
            }
            double faz = Modcrs(Atan2(tu1, tu2));
            double baz = Modcrs(Atan2(cu1 * sx, b1 * cx - su1 * cu2) + MathEx.PI);
            x = MathEx.Sqrt((1 / (r * r) - 1) * c2A + 1);
            x += 1;
            x = (x - 2.0) / x;
            c = 1.0 - x;
            c = (x * x / 4.0 + 1.0) / c;
            d = (0.375 * x * x - 1.0) * x;
            x = e * cy;
            double s = ((((sy * sy * 4.0 - 3.0) * (1.0 - e - e) * cz * d / 6.0 - x) * d / 4.0 + cz) * sy * d + y) * c * a * r;

            outValue._d = s;
            outValue._crs12 = faz;
            outValue._crs21 = baz;
            if (MathEx.Abs(iter - maxiter) < eps)
            {
                throw new ArgumentException("Algorithm did not converge");
            }
            return outValue;
        }
コード例 #6
0
        private static CrsdistResult Crsdist(double lat1, double lon1, double lat2, double lon2)
        {
            // radian args
            /* compute course and Distance (spherical) */
            double crs12, crs21;
            double argacos;
            if ((lat1 + lat2 == 0.0) && (MathEx.Abs(lon1 - lon2) == MathEx.PI) && (MathEx.Abs(lat1) != (MathEx.PI / 180) * 90.0))
            {
                throw new ArgumentException("Course between antipodal points is undefined");
            }

            double d = MathEx.Acos(MathEx.Sin(lat1) * MathEx.Sin(lat2) + MathEx.Cos(lat1) * MathEx.Cos(lat2) * MathEx.Cos(lon1 - lon2));

            if ((d == 0.0) || (lat1 == -(MathEx.PI / 180) * 90.0))
            {
                crs12 = 2 * MathEx.PI;
            }
            else if (lat1 == (MathEx.PI / 180) * 90.0)
            {
                crs12 = MathEx.PI;
            }
            else
            {
                argacos = (MathEx.Sin(lat2) - MathEx.Sin(lat1) * MathEx.Cos(d)) / (MathEx.Sin(d) * MathEx.Cos(lat1));
                if (MathEx.Sin(lon2 - lon1) < 0)
                {
                    crs12 = Acosf(argacos);
                }
                else
                {
                    crs12 = 2 * MathEx.PI - Acosf(argacos);
                }
            }
            if ((d == 0.0) || (lat2 == -(MathEx.PI / 180) * 90.0))
            {
                crs21 = 0.0;
            }
            else if (lat2 == (MathEx.PI / 180) * 90.0)
            {
                crs21 = MathEx.PI;
            }
            else
            {
                argacos = (MathEx.Sin(lat1) - MathEx.Sin(lat2) * MathEx.Cos(d)) / (MathEx.Sin(d) * MathEx.Cos(lat2));
                if (MathEx.Sin(lon1 - lon2) < 0)
                {
                    crs21 = Acosf(argacos);
                }
                else
                {
                    crs21 = 2 * MathEx.PI - Acosf(argacos);
                }
            }

            CrsdistResult outValue = new CrsdistResult {_d = d, _crs12 = crs12, _crs21 = crs21};
            return outValue;
        }
コード例 #7
0
        private static CrsdistResult CrsdistEll(double glat1, double glon1, double glat2, double glon2, int ellipse)
        {
            // glat1 initial geodetic latitude in radians N positive
            // glon1 initial geodetic longitude in radians E positive
            // glat2 final geodetic latitude in radians N positive
            // glon2 final geodetic longitude in radians E positive
            double a = EarthModel[ellipse][0];
            double f = 1 / EarthModel[ellipse][1];
            //alert("a="+a+" f="+f)
            double        sx = 0, cx = 0, sy = 0, cy = 0, y = 0;
            double        c2A = 0, cz = 0, e = 0, c;
            const double  eps      = 0.00000000005;
            double        iter     = 1;
            const double  maxiter  = 100;
            CrsdistResult outValue = new CrsdistResult();

            if ((glat1 + glat2 == 0.0) && (MathEx.Abs(glon1 - glon2) == MathEx.PI))
            {
                glat1 = glat1 + 0.00001; // allow algorithm to complete
            }
            if (glat1 == glat2 && (glon1 == glon2 || MathEx.Abs(MathEx.Abs(glon1 - glon2) - 2 * MathEx.PI) < eps))
            {
                outValue._d     = 0;
                outValue._crs12 = 0;
                outValue._crs21 = MathEx.PI;
                return(outValue);
            }
            double r   = 1 - f;
            double tu1 = r * MathEx.Tan(glat1);
            double tu2 = r * MathEx.Tan(glat2);
            double cu1 = 1.0 / MathEx.Sqrt(1.0 + tu1 * tu1);
            double su1 = cu1 * tu1;
            double cu2 = 1.0 / MathEx.Sqrt(1.0 + tu2 * tu2);
            double s1  = cu1 * cu2;
            double b1  = s1 * tu2;
            double f1  = b1 * tu1;
            double x   = glon2 - glon1;
            double d   = x + 1;

            while ((MathEx.Abs(d - x) > eps) && (iter < maxiter))
            {
                iter = iter + 1;
                sx   = MathEx.Sin(x);
                cx   = MathEx.Cos(x);
                tu1  = cu2 * sx;
                tu2  = b1 - su1 * cu2 * cx;
                sy   = MathEx.Sqrt(tu1 * tu1 + tu2 * tu2);
                cy   = s1 * cx + f1;
                y    = Atan2(sy, cy);
                double sa = s1 * sx / sy;
                c2A = 1 - sa * sa;
                cz  = f1 + f1;
                if (c2A > 0.0)
                {
                    cz = cy - cz / c2A;
                }
                e = cz * cz * 2.0 - 1.0;
                c = ((-3.0 * c2A + 4.0) * f + 4.0) * c2A * f / 16.0;
                d = x;
                x = ((e * cy * c + cz) * sy * c + y) * sa;
                x = (1.0 - c) * x * f + glon2 - glon1;
            }
            double faz = Modcrs(Atan2(tu1, tu2));
            double baz = Modcrs(Atan2(cu1 * sx, b1 * cx - su1 * cu2) + MathEx.PI);

            x  = MathEx.Sqrt((1 / (r * r) - 1) * c2A + 1);
            x += 1;
            x  = (x - 2.0) / x;
            c  = 1.0 - x;
            c  = (x * x / 4.0 + 1.0) / c;
            d  = (0.375 * x * x - 1.0) * x;
            x  = e * cy;
            double s = ((((sy * sy * 4.0 - 3.0) * (1.0 - e - e) * cz * d / 6.0 - x) * d / 4.0 + cz) * sy * d + y) * c * a * r;

            outValue._d     = s;
            outValue._crs12 = faz;
            outValue._crs21 = baz;
            if (MathEx.Abs(iter - maxiter) < eps)
            {
                throw new ArgumentException("Algorithm did not converge");
            }
            return(outValue);
        }
コード例 #8
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 18JUN2009  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Calculate the Distance between two point in great circle.
         * @param pt1  the first location.
         * @param pt2  the second location.
         * @return the Distance between the two points.
         */
        public double CalculateDistance(GeoLatLng pt1, GeoLatLng pt2)
        {
            CrsdistResult ret = ComputeFormCD(pt1, pt2);

            return(ret._d);
        }