Example #1
0
        /// <summary>
        /// Equality test which is really a proximity.
        /// </summary>
        public bool Equals(CGeoLatLong Other)
        {
            bool bLatClose;
            bool bLongClose;

            if (m_dLat == 0)
            {
                bLatClose = Other.GetLat() == 0;
            }
            else
            {
                bLatClose = Math.Abs((Other.GetLat() - m_dLat) / m_dLat)
                            < Constants.conEqualityTolerance;
            }
            if (!bLatClose)
            {
                return(false);                  // Get out early if we can.
            }
            if (m_dLong == 0)
            {
                bLongClose = Other.GetLong() == 0;
            }
            else
            {
                bLongClose = Math.Abs((Other.GetLong() - m_dLong) / m_dLong)
                             < Constants.conEqualityTolerance;
            }
            return(bLongClose);
        }
Example #2
0
        /// <summary>
        /// Rotation.
        /// </summary>
        public void Rotate(CGeoLatLong Other)
        {
            m_dLat  += Other.GetLat();
            m_dLong += Other.GetLong();

            if (m_dLat < -Constants.conHALFPI)
            {
                m_dLat = Constants.conPI + m_dLat;
            }

            if (m_dLat > Constants.conHALFPI)
            {
                m_dLat = -Constants.conPI + m_dLat;
            }

            if (m_dLong < -Constants.conPI)
            {
                m_dLong = Constants.conTWOPI + m_dLong;
            }

            if (m_dLong > Constants.conPI)
            {
                m_dLong = -Constants.conTWOPI + m_dLong;
            }
        }
Example #3
0
        /// <summary>
        /// Set using a heading and a range from an origin. Range in metres.
        /// </summary>
        public void Set(double dHeading, double dRange, CGeoLatLong Origin)
        {
            // alpha is the angular Distance travelled round the earths surface
            double alpha     = dRange / Constants.conEARTH_RADIUS_METRES;
            double sin_alpha = Math.Sin(alpha);
            double cos_alpha = Math.Cos(alpha);

            double latO  = Origin.GetLat();
            double longO = Origin.GetLong();

            double sin_Olat = Math.Sin(latO);
            double cos_Olat = Math.Cos(latO);

            m_dLat = Math.Asin(sin_Olat * cos_alpha + cos_Olat * sin_alpha * Math.Cos(dHeading));

            m_dLong = longO + Math.Atan2(Math.Sin(dHeading) * sin_alpha * cos_Olat, cos_alpha - sin_Olat * Math.Sin(m_dLat));

            while (m_dLong > Constants.conPI)
            {
                m_dLong -= Constants.conTWOPI;
            }
            while (m_dLong < -Constants.conPI)
            {
                m_dLong += Constants.conTWOPI;
            }
        }
Example #4
0
        /// <summary>
        /// Project the given lat long to x, y using the input parameters to store the result and retaining
        /// the lat long in the class passed.
        /// </summary>
        public override void Project(CGeoLatLong rLatLong, double dx, double dy)
        {
            dy = rLatLong.GetLat();
            dx = rLatLong.GetLong();

            Project(dy, dx);
        }
Example #5
0
 /// <summary>
 /// Assigment.
 /// </summary>
 public CGeoLatLong Set(CGeoLatLong Other)
 {
     // Simple assignment
     m_dLat  = Other.GetLat();
     m_dLong = Other.GetLong();
     // Return reference to this
     return(this);
 }
Example #6
0
        /// <summary>
        /// Finds the range from one position to another based on sperical earth and
        /// great circles. Range is in metres. Error between this and WSG84 slant range is
        /// less than 1% at ranges up to 2000km. (Spherical Law of Math.Cosines).
        /// </summary>
        public double Range(CGeoLatLong Other)
        {
            double latO  = Other.GetLat();
            double longO = Other.GetLong();

            if (m_dLat == latO && m_dLong == longO)
            {
                return(0);
            }

            double A = Math.Sin(m_dLat) * Math.Sin(latO) +
                       Math.Cos(m_dLat) * Math.Cos(latO) * Math.Cos(m_dLong - longO);

            return(Math.Acos(A) * Constants.conEARTH_RADIUS_METRES);
        }
Example #7
0
 /// <summary>
 /// Copy constructor.
 /// </summary>
 public CGeoLatLong(CGeoLatLong Other)
 {
     // simple assignment
     m_dLat  = Other.GetLat();
     m_dLong = Other.GetLong();
 }
Example #8
0
        /// <summary>
        /// Calculates the Range and heading to another location in degrees.
        /// </summary>
        public void RangeAndHeading(CGeoLatLong Other,
                                    out double dRangeMetres, out double hdng)
        {
            double latO  = Other.GetLat();
            double longO = Other.GetLong();

            if (m_dLat == latO && m_dLong == longO)
            {
                dRangeMetres = 0;
                hdng         = 0;
                return;
            }

            double sin_lat   = Math.Sin(m_dLat);
            double sin_latO  = Math.Sin(latO);
            double cos_lat   = Math.Cos(m_dLat);
            double cos_latO  = Math.Cos(latO);
            double cos_alpha = sin_latO * sin_lat + cos_latO * cos_lat * Math.Cos(longO - m_dLong);
            double alpha     = Math.Acos(cos_alpha);

            dRangeMetres = alpha * Constants.conEARTH_RADIUS_METRES;


            //check to see if they are on the same line of longitude
            if (m_dLong == longO)
            {
                // No need to check if the locations are the same as done already.
                if (m_dLat > latO)
                {
                    hdng = Constants.conPI;
                    return;
                }
                else
                {
                    hdng = 0;            //may as well return 0 as any other
                    return;
                }
            }

            if ((Math.Abs(m_dLat) == -Constants.conHALFPI) | (Math.Abs(latO) == Constants.conHALFPI))
            {
                //check to see if the first is at the south pole or the second is at the north pole
                if ((m_dLat == -Constants.conHALFPI) | (latO == Constants.conHALFPI))
                {
                    hdng = 0;
                    return;
                }

                //check to see if the first is at the north pole or the second is at the south
                if ((m_dLat == Constants.conHALFPI) | (latO == -Constants.conHALFPI))
                {
                    hdng = Constants.conPI;
                    return;
                }
            }

            if (longO > m_dLong)
            {
                hdng = Math.Acos((sin_latO - sin_lat * cos_alpha) / (cos_lat * Math.Sin(alpha)));
                if ((longO - m_dLong) > Constants.conPI)
                {
                    // gone from e.g. e179 to w179
                    hdng = Constants.conTWOPI - hdng;
                }
            }
            else
            {
                hdng = Constants.conTWOPI - Math.Acos((sin_latO - sin_lat * cos_alpha) / (cos_lat * Math.Sin(alpha)));
                if ((m_dLong - longO) > Constants.conPI)
                {
                    // gone from e.g. w179 to e179
                    hdng = Constants.conTWOPI - hdng;
                }
            }

            if (hdng == Constants.conTWOPI)
            {
                hdng = 0;
            }
        }
Example #9
0
        /// <summary>
        /// Calculates the heading to another location in degrees.
        /// </summary>
        double Heading(CGeoLatLong Other)
        {
            double latO  = Other.GetLat();
            double longO = Other.GetLong();

            //check to see if they are on the same line of longitude
            if (m_dLong == longO)
            {
                // first check to see if the locations are the same
                if (m_dLat == latO)
                {
                    return(0);            //may as well return 0 as any other
                }
                if (m_dLat > latO)
                {
                    return(180);
                }
                else
                {
                    return(0);
                }
            }

            if ((Math.Abs(m_dLat) == -Constants.conHALFPI) | (Math.Abs(latO) == Constants.conHALFPI))
            {
                //check to see if the first is at the south pole or the second is at the north pole
                if ((m_dLat == -Constants.conHALFPI) | (latO == Constants.conHALFPI))
                {
                    return(0);
                }

                //check to see if the first is at the north pole or the second is at the south
                if ((m_dLat == Constants.conHALFPI) | (latO == -Constants.conHALFPI))
                {
                    return(180);
                }
            }

            double sin_lat   = Math.Sin(m_dLat);
            double sin_latO  = Math.Sin(latO);
            double cos_lat   = Math.Cos(m_dLat);
            double cos_latO  = Math.Cos(latO);
            double cos_alpha = sin_latO * sin_lat + cos_latO * cos_lat * Math.Cos(longO - m_dLong);
            double alpha     = Math.Acos(cos_alpha);

            double hdng;

            if (longO > m_dLong)
            {
                hdng = Math.Acos((sin_latO - sin_lat * cos_alpha) / (cos_lat * Math.Sin(alpha)));
                if ((longO - m_dLong) > Constants.conPI)
                {
                    // gone from e.g. e179 to w179
                    hdng = Constants.conTWOPI - hdng;
                }
            }
            else
            {
                hdng = Constants.conTWOPI - Math.Acos((sin_latO - sin_lat * cos_alpha) / (cos_lat * Math.Sin(alpha)));
                if ((m_dLong - longO) > Constants.conPI)
                {
                    // gone from e.g. w179 to e179
                    hdng = Constants.conTWOPI - hdng;
                }
            }

            if (hdng == Constants.conTWOPI)
            {
                return(0);
            }

            return(hdng);
        }
        /// <summary>
        /// Calculates the Range and heading to another location in degrees.
        /// </summary>
        public void RangeAndHeading(CGeoLatLong Other, 
					        out double dRangeMetres, out double hdng)
        {
            double latO = Other.GetLat();
            double longO = Other.GetLong();

            if (m_dLat == latO && m_dLong == longO)
            {
                dRangeMetres = 0;
                hdng = 0;
                return;
            }

            double sin_lat = Math.Sin(m_dLat);
            double sin_latO = Math.Sin(latO);
            double cos_lat = Math.Cos(m_dLat);
            double cos_latO = Math.Cos(latO);
            double cos_alpha = sin_latO * sin_lat + cos_latO * cos_lat * Math.Cos(longO - m_dLong);
            double alpha = Math.Acos(cos_alpha);

            dRangeMetres = alpha * Constants.conEARTH_RADIUS_METRES;

            //check to see if they are on the same line of longitude
            if(m_dLong == longO)
            {
                // No need to check if the locations are the same as done already.
                if(m_dLat > latO)
                {
                    hdng = Constants.conPI;
                    return;
                }
                else
                {
                    hdng = 0;//may as well return 0 as any other
                    return ;
                }
            }

            if((Math.Abs(m_dLat) == -Constants.conHALFPI) | (Math.Abs(latO) == Constants.conHALFPI))
            {
                //check to see if the first is at the south pole or the second is at the north pole
                if((m_dLat == -Constants.conHALFPI) | (latO == Constants.conHALFPI))
                {
                    hdng = 0;
                    return;
                }

                //check to see if the first is at the north pole or the second is at the south
                if((m_dLat == Constants.conHALFPI) | (latO ==-Constants.conHALFPI))
                {
                    hdng = Constants.conPI;
                    return;
                }
            }

            if(longO > m_dLong)
            {
                hdng = Math.Acos(  ( sin_latO - sin_lat * cos_alpha )/( cos_lat * Math.Sin(alpha) )  );
                if ( (longO - m_dLong) > Constants.conPI)
                {
                    // gone from e.g. e179 to w179
                    hdng = Constants.conTWOPI - hdng;
                }
            }
            else
            {
                hdng = Constants.conTWOPI - Math.Acos(  ( sin_latO - sin_lat * cos_alpha )/( cos_lat * Math.Sin(alpha) )  );
                if ( (m_dLong - longO) > Constants.conPI)
                {
                    // gone from e.g. w179 to e179
                    hdng = Constants.conTWOPI - hdng;
                }
            }

            if (hdng == Constants.conTWOPI)
                            hdng = 0;
        }
        /// <summary>
        /// Equality test which is really a proximity.
        /// </summary>
        public bool Equals(CGeoLatLong Other)
        {
            bool bLatClose;
            bool bLongClose;

            if ( m_dLat == 0 )
                bLatClose = Other.GetLat() == 0;
            else
                bLatClose = Math.Abs(( Other.GetLat() - m_dLat ) / m_dLat )
                                                        < Constants.conEqualityTolerance;
            if (!bLatClose)
                return false;		// Get out early if we can.

            if ( m_dLong == 0 )
                bLongClose = Other.GetLong() == 0;
            else
                bLongClose = Math.Abs((Other.GetLong() - m_dLong) / m_dLong)
                                                        < Constants.conEqualityTolerance;
            return (bLongClose);
        }
        /// <summary>
        /// Calculates the heading to another location in degrees.
        /// </summary>
        double Heading(CGeoLatLong Other)
        {
            double latO = Other.GetLat();
            double longO = Other.GetLong();

            //check to see if they are on the same line of longitude
            if(m_dLong == longO)
            {
                // first check to see if the locations are the same
                if (m_dLat == latO)
                    return 0; //may as well return 0 as any other

                if(m_dLat > latO)
                    return 180;
                else
                    return 0;
            }

            if ((Math.Abs(m_dLat) == -Constants.conHALFPI) | (Math.Abs(latO) == Constants.conHALFPI))
            {
                //check to see if the first is at the south pole or the second is at the north pole
                if((m_dLat == -Constants.conHALFPI) | (latO == Constants.conHALFPI))
                    return 0;

                //check to see if the first is at the north pole or the second is at the south
                if((m_dLat == Constants.conHALFPI) | (latO ==-Constants.conHALFPI))
                    return 180;
            }

            double sin_lat = Math.Sin(m_dLat);
            double sin_latO = Math.Sin(latO);
            double cos_lat = Math.Cos(m_dLat);
            double cos_latO = Math.Cos(latO);
            double cos_alpha = sin_latO * sin_lat + cos_latO * cos_lat * Math.Cos(longO - m_dLong);
            double alpha = Math.Acos(cos_alpha);

            double hdng;

            if(longO > m_dLong)
            {
                hdng = Math.Acos(  ( sin_latO - sin_lat * cos_alpha )/( cos_lat * Math.Sin(alpha) )  );
                if ( (longO - m_dLong) > Constants.conPI)
                {
                    // gone from e.g. e179 to w179
                    hdng = Constants.conTWOPI - hdng;
                }
            }
            else
            {
                hdng = Constants.conTWOPI - Math.Acos(  ( sin_latO - sin_lat * cos_alpha )/( cos_lat * Math.Sin(alpha) )  );
                if ( (m_dLong - longO) > Constants.conPI)
                {
                    // gone from e.g. w179 to e179
                    hdng = Constants.conTWOPI - hdng;
                }
            }

            if (hdng == Constants.conTWOPI)
                return 0;

            return hdng;
        }
 /// <summary>
 /// Copy constructor.
 /// </summary>
 public CGeoLatLong(CGeoLatLong Other)
 {
     // simple assignment
     m_dLat = Other.GetLat();
     m_dLong = Other.GetLong();
 }
        /// <summary>
        /// Set using a heading and a range from an origin. Range in metres. 
        /// </summary>
        public void Set(double dHeading, double dRange, CGeoLatLong Origin)
        {
            // alpha is the angular Distance travelled round the earths surface
            double alpha = dRange /Constants.conEARTH_RADIUS_METRES;
            double sin_alpha = Math.Sin(alpha);
            double cos_alpha = Math.Cos(alpha);

            double latO = Origin.GetLat();
            double longO = Origin.GetLong();

            double sin_Olat = Math.Sin(latO);
            double cos_Olat = Math.Cos(latO);

            m_dLat = Math.Asin(  sin_Olat * cos_alpha + cos_Olat * sin_alpha * Math.Cos(dHeading)  );

            m_dLong = longO + Math.Atan2(Math.Sin(dHeading) * sin_alpha * cos_Olat, cos_alpha - sin_Olat * Math.Sin(m_dLat));

            while (m_dLong > Constants.conPI)
                m_dLong -= Constants.conTWOPI;
            while (m_dLong < -Constants.conPI)
                m_dLong += Constants.conTWOPI;
        }
 /// <summary>
 /// Assigment.
 /// </summary>
 public CGeoLatLong Set(CGeoLatLong Other)
 {
     // Simple assignment
     m_dLat = Other.GetLat();
     m_dLong = Other.GetLong();
     // Return reference to this
     return this;
 }
        /// <summary>
        /// Rotation.
        /// </summary>
        public void Rotate(CGeoLatLong Other)
        {
            m_dLat += Other.GetLat();
            m_dLong += Other.GetLong();

            if (m_dLat < -Constants.conHALFPI)
                m_dLat = Constants.conPI + m_dLat;

            if (m_dLat > Constants.conHALFPI)
                m_dLat = -Constants.conPI + m_dLat;

            if (m_dLong < -Constants.conPI)
                m_dLong = Constants.conTWOPI + m_dLong;

            if (m_dLong > Constants.conPI)
                m_dLong = -Constants.conTWOPI + m_dLong;
        }
        /// <summary>
        /// Project the given lat long to x, y using the input parameters to store the result and retaining 
        /// the lat long in the class passed.
        /// </summary>
        public override void Project(CGeoLatLong rLatLong, double dx, double dy)
        {
            dy = rLatLong.GetLat();
            dx = rLatLong.GetLong();

            Project(dy, dx);
        }
        /// <summary>
        /// Finds the range from one position to another based on sperical earth and
        /// great circles. Range is in metres. Error between this and WSG84 slant range is
        /// less than 1% at ranges up to 2000km. (Spherical Law of Math.Cosines).
        /// </summary>
        public double Range(CGeoLatLong Other)
        {
            double latO = Other.GetLat();
            double longO = Other.GetLong();

            if (m_dLat == latO && m_dLong == longO) return 0;

            double A = Math.Sin(m_dLat) * Math.Sin(latO) +
                Math.Cos(m_dLat) * Math.Cos(latO) * Math.Cos(m_dLong - longO);

            return Math.Acos(A) * Constants.conEARTH_RADIUS_METRES;
        }