/// <summary>
        /// 转换坐标点根据经纬度
        /// </summary>
        /// <param name="lat">纬度后面一位必须带N or S</param>
        /// <param name="lon">经度后面一位必须带E or W</param>
        /// <returns></returns>
        public static PointCoordinate GetPointCoordinate(string lat, string lon)
        {
            PointCoordinate p = new PointCoordinate();

            if (lat.Substring(lat.Length - 1, 1) == "N")
            {
                lat        = lat.Substring(0, lat.Length - 1);
                p.Latitide = double.Parse(lat) / 10000;
            }
            else
            {
                lat        = lat.Substring(0, lat.Length - 1);
                p.Latitide = 0 - double.Parse(lat) / 10000;
            }


            if (lon.Substring(lon.Length - 1, 1) == "E")
            {
                lon         = lon.Substring(0, lon.Length - 1);
                p.Longitude = double.Parse(lon) / 10000;
            }
            else
            {
                lon         = lon.Substring(0, lon.Length - 1);
                p.Longitude = 0 - double.Parse(lon) / 10000;
            }

            return(p);
        }
        /// <summary>
        /// 根据已经点、方位和角度,计算另一点坐标。
        /// </summary>
        /// <param name="angle">航线角(磁方向,弧度单位)</param>
        /// <param name="distance">距离(公里)</param>
        /// <param name="point">参考点</param>
        /// <returns></returns>
        public static PointCoordinate CalcuateCoordinate(PointCoordinate point, double angle,
                                                         double distance)
        {
            PointCoordinate p = new PointCoordinate();
            double          R = 6371.0; // earth's mean radius in km
            double          d = distance / R;

            double lat1 = GreatCircleArgorithm.ConvertToARC(GreatCircleArgorithm.ConvertToDeg(point.Latitide));
            double lon1 = GreatCircleArgorithm.ConvertToARC(GreatCircleArgorithm.ConvertToDeg(point.Longitude));

            double brng = GreatCircleArgorithm.ConvertToDeg(angle) * Math.PI / 180;   //将度转换为弧度

            double lat2 = lat1 + d * Math.Cos(brng);
            double dLat = lat2 - lat1;
            double dPhi = Math.Log(Math.Tan(lat2 / 2 + Math.PI / 4) / Math.Tan(lat1 / 2 + Math.PI / 4));
            double q    = (Math.Abs(dLat) > 0.000000001) ? dLat / dPhi : Math.Cos(lat1);
            double dlon = d * Math.Sin(brng) / q;

            if (Math.Abs(lat2) > Math.PI / 2)
            {
                lat2 = lat2 > 0 ? Math.PI - lat2 : -Math.PI - lat2;
            }

            double lon2 = (lon1 + dlon + Math.PI) % (2 * Math.PI) - Math.PI;

            p.Latitide  = GreatCircleArgorithm.ConvertToDMS(GreatCircleArgorithm.ConvertToDegree(lat2));
            p.Longitude = GreatCircleArgorithm.ConvertToDMS(GreatCircleArgorithm.ConvertToDegree(lon2));

            return(p);
        }
        /// <summary>
        /// 从某已知点和距离、方位角算另一点坐标
        /// </summary>
        /// <param name="point">已知点</param>
        /// <param name="angle">方位角</param>
        /// <param name="distance">距离(公里)</param>
        /// <returns></returns>
        public static PointCoordinate CalcuateCoordinate(PointCoordinate point, double angle, double distance)
        {
            double lat1 = ConvertToARC(ConvertToDeg(point.Latitide));
            double lon1 = ConvertToARC(ConvertToDeg(point.Longitude));
            double brng = ConvertToARC(ConvertToDeg(angle));
            double lat2 = Math.Asin(Math.Sin(lat1) * Math.Cos(distance / R) +
                                    Math.Cos(lat1) * Math.Sin(distance / R) * Math.Cos(brng));

            double lon2 = lon1 + Math.Atan2(Math.Sin(brng) * Math.Sin(distance / R) * Math.Cos(lat1),
                                            Math.Cos(distance / R) - Math.Sin(lat1) * Math.Sin(lat2));

            lon2 = (lon2 + Math.PI) % (2 * Math.PI) - Math.PI;   //;normalise to -180...+180

            PointCoordinate p = new PointCoordinate();

            p.Longitude = ConvertToDMS(ConvertToDegree(lon2));
            p.Latitide  = ConvertToDMS(ConvertToDegree(lat2));
            return(p);

            /*
             *  var R = 6371; // earth's mean radius in km
             * var lat1 = this.lat.toRad(), lon1 = this.lon.toRad();
             * brng = brng.toRad();
             *
             * var lat2 = Math.asin( Math.sin(lat1)*Math.cos(d/R) +
             *          Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng) );
             * var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1),
             *                 Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2));
             * lon2 = (lon2+Math.PI)%(2*Math.PI) - Math.PI;  // normalise to -180...+180
             *
             * if (isNaN(lat2) || isNaN(lon2)) return null;
             * return new LatLon(lat2.toDeg(), lon2.toDeg());
             *
             * */
        }
        /// <summary>
        /// 计算两点间角度
        /// </summary>
        /// <param name="firstPoint"></param>
        /// <param name="endPoint"></param>
        /// <returns></returns>
        public static double CalculateAngle(PointCoordinate firstPoint, PointCoordinate endPoint)
        {
            double lat2 = ConvertToARC(ConvertToDeg(endPoint.Latitide));
            double lat1 = ConvertToARC(ConvertToDeg(firstPoint.Latitide));
            double lon2 = ConvertToARC(ConvertToDeg(endPoint.Longitude));
            double lon1 = ConvertToARC(ConvertToDeg(firstPoint.Longitude));

            double dLon = lon2 - lon1;
            double y    = Math.Sin(dLon) * Math.Cos(lat2);
            double x    = Math.Cos(lat1) * Math.Sin(lat2) -
                          Math.Sin(lat1) * Math.Cos(lat2) * Math.Cos(dLon);

            double angle = Math.Atan2(y, x);

            angle = (angle + Math.PI * 2) % (Math.PI * 2);
            return(ConvertToDMS(ConvertToDegree(angle)));

            /*
             *
             * lat1 = lat1.toRad(); lat2 = lat2.toRad();
             * var dLon = (lon2-lon1).toRad();
             *
             * var y = Math.sin(dLon) * Math.cos(lat2);
             * var x = Math.cos(lat1)*Math.sin(lat2) -
             * Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
             * return Math.atan2(y, x).toBrng();
             */
        }
        /// <summary>
        /// 计算两点距离
        /// </summary>
        /// <param name="firstPoint"></param>
        /// <param name="endPoint"></param>
        /// <returns></returns>
        public static double CalculateDistance(PointCoordinate firstPoint, PointCoordinate endPoint)
        {
            double lat2 = ConvertToARC(ConvertToDeg(endPoint.Latitide));
            double lat1 = ConvertToARC(ConvertToDeg(firstPoint.Latitide));
            double lon2 = ConvertToARC(ConvertToDeg(endPoint.Longitude));
            double lon1 = ConvertToARC(ConvertToDeg(firstPoint.Longitude));

            double dLat = lat2 - lat1;
            double dLon = lon2 - lon1;

            double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(lat1) * Math.Cos(lat2) *
                       Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
            double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));

            return(R * c);



            /*
             *   var R = 6371; // earth's mean radius in km
             * var dLat = (lat2-lat1).toRad();
             * var dLon = (lon2-lon1).toRad();
             * lat1 = lat1.toRad(), lat2 = lat2.toRad();
             *
             * var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
             * Math.cos(lat1) * Math.cos(lat2) *
             * Math.sin(dLon/2) * Math.sin(dLon/2);
             * var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
             * var d = R * c;
             * return d;
             * }
             * */
        }
        /// <summary>
        /// 计算两点的角度。
        /// </summary>
        /// <param name="firstPoint"></param>
        /// <param name="endPoint"></param>
        /// <returns>返回60进制的度分秒角度 </returns>
        public static double CalculateAngle(PointCoordinate firstPoint, PointCoordinate endPoint)
        {
            double lat2 = GreatCircleArgorithm.ConvertToDeg(endPoint.Latitide);
            double lon2 = GreatCircleArgorithm.ConvertToDeg(endPoint.Longitude);
            double lat1 = GreatCircleArgorithm.ConvertToDeg(firstPoint.Latitide);
            double lon1 = GreatCircleArgorithm.ConvertToDeg(firstPoint.Longitude);

            double dLon = GreatCircleArgorithm.ConvertToARC((lon2 - lon1));
            double dPhi = Math.Log(Math.Tan(GreatCircleArgorithm.ConvertToARC(lat2) / 2 + Math.PI / 4) / Math.Tan(GreatCircleArgorithm.ConvertToARC(lat1) / 2 + Math.PI / 4));

            if (Math.Abs(dLon) > Math.PI)
            {
                dLon = dLon > 0 ? -(2 * Math.PI - dLon) : (2 * Math.PI + dLon);
            }

            double angle = Math.Atan2(dLon, dPhi);

            return(GreatCircleArgorithm.ConvertToDMS((GreatCircleArgorithm.ConvertToDegree(angle) + 360) % 360));
        }
        /// <summary>
        /// 计算两点间距离。
        /// see http://williams.best.vwh.net/avform.htm#Rhumb
        /// </summary>
        /// <param name="firstPoint"></param>
        /// <param name="endPoint"></param>
        /// <returns></returns>
        public static double CalculateDistance(PointCoordinate firstPoint, PointCoordinate endPoint)
        {
            double R    = 6371;
            double lat2 = GreatCircleArgorithm.ConvertToDeg(endPoint.Latitide);
            double lon2 = GreatCircleArgorithm.ConvertToDeg(endPoint.Longitude);
            double lat1 = GreatCircleArgorithm.ConvertToDeg(firstPoint.Latitide);
            double lon1 = GreatCircleArgorithm.ConvertToDeg(firstPoint.Longitude);

            double dLat = GreatCircleArgorithm.ConvertToARC(lat2 - lat1);
            double dLon = Math.Abs(GreatCircleArgorithm.ConvertToARC(lon2 - lon1));

            double dPhi = Math.Log(Math.Tan(GreatCircleArgorithm.ConvertToARC(lat2) / 2 + Math.PI / 4) / Math.Tan(GreatCircleArgorithm.ConvertToARC(lat1) / 2 + Math.PI / 4));
            double q    = (Math.Abs(dLat) > 0.00000001) ? dLat / dPhi : Math.Cos(GreatCircleArgorithm.ConvertToARC(lat1));

            if (dLon > Math.PI)
            {
                dLon = 2 * Math.PI - dLon;
            }

            double d = Math.Sqrt(dLat * dLat + q * q * dLon * dLon);

            return(d * R);
        }
        /// <summary>
        /// 根据两点计算坐标。
        /// 已经两点坐标,已知未知点到2点的方位角
        /// </summary>
        /// <param name="point1">第一点坐标</param>
        /// <param name="point2">第二点坐标</param>
        ///<param name="angle1">到第一点的方位角</param>
        /// <param name="angle2">到第二点的方位角</param>
        /// <returns>坐标</returns>
        public static PointCoordinate CalcuateCoordinate(PointCoordinate point1, double angle1, PointCoordinate point2, double angle2)
        {
            PointCoordinate p = new PointCoordinate();

            //这个算法东经是负,西经是正,需要转换
            double lat1 = ConvertToARC(ConvertToDeg(point1.Latitide));
            double lon1 = ConvertToARC(ConvertToDeg(-point1.Longitude));
            double lat2 = ConvertToARC(ConvertToDeg(point2.Latitide));
            double lon2 = ConvertToARC(ConvertToDeg(-point2.Longitude));

            PointCoordinate tempPoint1 = CalcuateCoordinate(point1, angle1, 20000);   //第一点方向上的临时点
            PointCoordinate tempPoint2 = CalcuateCoordinate(point2, angle2, 20000);   //第二点方向上的临时点

            angle1 = ConvertToARC(ConvertToDeg(angle1));
            angle2 = ConvertToARC(ConvertToDeg(angle2));

            double d = Math.PI / 2;

            double lat1_1 = Math.Asin(sin(lat1) * cos(d) + cos(lat1) * sin(d) * cos(angle1));

            double lon1_1 = Math.Atan2(sin(angle1) * sin(d) * cos(lat1), cos(d) - sin(lat1) * sin(lat1_1));

            lon1_1 = Modlon(lon1 - lon1_1);

            double lat2_1 = Math.Asin(sin(lat2) * cos(d) + cos(lat2) * sin(d) * cos(angle2));
            double lon2_1 = Math.Atan2(sin(angle2) * sin(d) * cos(lat2), cos(d) - sin(lat2) * sin(lat2_1));

            lon2_1 = Modlon(lon2 - lon2_1);



            double a1 = sin(lat1 - lat1_1) * sin((lon1 + lon1_1) / 2) * cos((lon1 - lon1_1) / 2)
                        - sin(lat1 + lat1_1) * cos((lon1 + lon1_1) / 2) * sin((lon1 - lon1_1) / 2);

            double b1 = sin(lat1 - lat1_1) * cos((lon1 + lon1_1) / 2) * cos((lon1 - lon1_1) / 2) +
                        sin(lat1 + lat1_1) * sin((lon1 + lon1_1) / 2) * sin((lon1 - lon1_1) / 2);

            double c1 = cos(lat1) * cos(lat1_1) * sin(lon1 - lon1_1);

            double a2 = sin(lat2 - lat2_1) * sin((lon2 + lon2_1) / 2) * cos((lon2 - lon2_1) / 2)
                        - sin(lat2 + lat2_1) * cos((lon2 + lon2_1) / 2) * sin((lon2 - lon2_1) / 2);

            double b2 = sin(lat2 - lat2_1) * cos((lon2 + lon2_1) / 2) * cos((lon2 - lon2_1) / 2) +
                        sin(lat2 + lat2_1) * sin((lon2 + lon2_1) / 2) * sin((lon2 - lon2_1) / 2);

            double c2 = cos(lat2) * cos(lat2_1) * sin(lon2 - lon2_1);


            double A = b1 * c2 - c1 * b2;  //v1(2) * v2(3) - v1(3) * v2(2)
            double B = c1 * a2 - a1 * c2;  //v1(3) * v2(1) - v1(1) * v2(3)
            double C = a1 * b2 - b1 * a2;  //v1(1) * v2(2) - v1(2) * v2(1))

            double Lat01 = Math.Atan2(C, Math.Sqrt(A * A + B * B));
            double Lon01 = Math.Atan2(-B, A);

            PointCoordinate r1 = new PointCoordinate();

            r1.Latitide  = ConvertToDMS(ConvertToDegree(Lat01));
            r1.Longitude = -ConvertToDMS(ConvertToDegree(Lon01));


            PointCoordinate r2 = new PointCoordinate();

            r2.Latitide  = ConvertToDMS(ConvertToDegree(-Lat01));
            r2.Longitude = -ConvertToDMS(ConvertToDegree(Modlon(Lon01 + Math.PI)));

            //有两点,只用最近的点。
            double ta = CalculateDistance(r1, point1);
            //double  ta1 = CalculateAngle(r2, point1);

            //mqg于20110831增加,应该用计算距离的方法
            double ta1 = CalculateDistance(r2, point1);

            if (ta > ta1)
            {
                return(r2);
            }
            else
            {
                return(r1);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="point1"></param>
        /// <param name="point2"></param>
        /// <param name="distance">到Point1的距离</param>
        /// <param name="angle">到Point2的角度</param>
        /// <returns></returns>
        public static List <PointCoordinate> CalcuateCoordinate(PointCoordinate point1, PointCoordinate point2,
                                                                double distance, double angle)
        {
            //根据算法描述,Point1为D点,Point2为A点,未知点为B点

            List <PointCoordinate> points = new List <PointCoordinate>();



            double b     = CalculateDistance(point1, point2) / R; //先计算出两点距离
            double crs12 = CalculateAngle(point2, point1);        //求出两点的方位角

            double crs_AB = ConvertToARC(ConvertToDeg(angle));


            double crs_AD = ConvertToARC(ConvertToDeg(crs12));

            //A点的夹角
            double A = (crs_AD - crs_AB + Math.PI) % (Math.PI * 2) - Math.PI;

            double r = Math.Sqrt((Math.Cos(b) * Math.Cos(b) + Math.Sin(b) * Math.Sin(b) * Math.Cos(A) * Math.Cos(A)));
            double p = Math.Atan2(Math.Sin(b) * Math.Cos(A), Math.Cos(b));
            double d = distance / R;

            if (Math.Cos(d) * Math.Cos(d) > r * r)
            {
                // points.Add(CalcuateCoordinate(point2, angle, p * R));
                throw new Exception("要计算的点不存在");
            }
            else
            {
                double dp = p + Math.Acos(Math.Cos(d) / r);
                if (dp > 0)
                {
                    points.Add(CalcuateCoordinate(point2, angle, dp * R));
                }
                dp = p - Math.Acos(Math.Cos(d) / r);
                if (dp > 0)
                {
                    points.Add(CalcuateCoordinate(point2, angle, dp * R));
                }
            }

            //foreach (PointCoordinate pp in points)
            //{
            //    double kkk = CalculateDistance(pp, point1);
            //    double aaa = CalculateAngle(point2, pp);
            //}

            if (points.Count == 0)
            {
                throw new Exception("要计算的点不存在!");
            }

            return(points);

            /*
             *
             * Let points A and B define a great circle route and D be a third point. Find the points on the great circle through A and B that lie a distance d from D, if they exist.
             *
             * A = crs_AD - crs_AB
             *
             * ( crs_AB and crs_AD are the initial GC bearings from A to B and D, respectively. Compute using Course between points)
             *
             * b = dist_AD
             *
             * (dist_AD is the distance from A to D. Compute using Distance between points)
             *
             * r=(cos(b)^2+sin(b)^2*cos(A)^2)^(1/2)
             *
             * (acos(r) is the XTD)
             *
             * p=atan2(sin(b)*cos(A),cos(b))
             *
             * (p is the ATD)
             *
             * IF (cos(d)^2 > r^2) THEN
             *    No points exist
             * ELSE
             *    Two points exist
             *   dp = p +- acos(cos(d)/r)
             * ENDIF
             *
             * dp are the distances of the desired points from A along AB. Their lat/lons can be computed using Lat/lon given radial and distance
             */
        }