示例#1
0
        //
        // Instance Methods
        //
        public double DistanceFrom(Location remoteLocation)
        {
            Verify(this);
            Verify(remoteLocation);

            return Haversine.CalculateDistance(this, remoteLocation);
        }
示例#2
0
        /// <summary>
        /// Creates a box that encloses the specified location, where the sides of the square
        ///  are inRadius miles away from the location at the perpendicular.  Note that we do
        ///  not actually generate lat/lon pairs; we only generate the coordinate that 
        ///  represents the side of the box.
        /// </summary>
        /// <remarks>
        /// <para>Formula obtained from Dr. Math at http://www.mathforum.org/library/drmath/view/51816.html.</para>
        /// </remarks>
        /// <param name="inLocation"></param>
        /// <param name="inRadius"></param>
        /// <returns></returns>
        public static RadiusBox Create(Location inLocation, double inRadius)
        {
            /*
                A point {lat,lon} is a distance d out on the tc radial from point 1 if:

                lat = asin (sin (lat1) * cos (d) + cos (lat1) * sin (d) * cos (tc))
                dlon = atan2 (sin (tc) * sin (d) * cos (lat1), cos (d) - sin (lat1) * sin (lat))
                lon = mod (lon1 + dlon + pi, 2 * pi) - pi

                Where:
                    * d is the distance in radians (an arc), so the desired radius divided by
                        the radius of the Earth.
                    * tc = 0 is N, tc = pi is S, tc = pi/2 is E, tc = 3*pi/2 is W.
            */
            double lat;
            double dlon;
            double dLatInRads = inLocation.Latitude * (Math.PI / 180.0);
            double dLongInRads = inLocation.Longitude * (Math.PI / 180.0);
            double dDistInRad = inRadius / Globals.EarthRadiusMiles;
            RadiusBox box = new RadiusBox();
            box.Radius = inRadius;

            //	N (tc == 0):
            //		lat = asin (sin(lat1)*cos(d) + cos(lat1)*sin(d))
            //			= asin (sin(lat1 + d))
            //			= lat1 + d
            //	Unused:
            //		lon	= lon1, because north-south lines follow lines of longitude.
            box.TopLine = dLatInRads + dDistInRad;
            box.TopLine *= (180.0 / Math.PI);

            //	S (tc == pi):
            //		lat = asin (sin(lat1)*cos(d) - cos(lat1)*sin(d))
            //			= asin (sin(lat1 - d))
            //			= lat1 - d
            //	Unused:
            //		lon	= lon1, because north-south lines follow lines of longitude.
            box.BottomLine = dLatInRads - dDistInRad;
            box.BottomLine *= (180.0 / Math.PI);

            //	E (tc == pi/2):
            //		lat	 = asin (sin(lat1)*cos(d))
            //		dlon = atan2 (sin(tc)*sin(d)*cos(lat1), cos(d) - sin(lat1)*sin(lat))
            //		lon	 = mod (lon1 + dlon + pi, 2*pi) - pi
            lat = Math.Asin(Math.Sin(dLatInRads) * Math.Cos(dDistInRad));
            dlon = Math.Atan2(Math.Sin(Math.PI / 2.0) * Math.Sin(dDistInRad) * Math.Cos(dLatInRads), Math.Cos(dDistInRad) - Math.Sin(dLatInRads) * Math.Sin(lat));
            box.RightLine = ((dLongInRads + dlon + Math.PI) % (2.0 * Math.PI)) - Math.PI;
            box.RightLine *= (180.0 / Math.PI);

            //	W (tc == 3*pi/2):
            //		lat	 = asin (sin(lat1)*cos(d))
            //		dlon = atan2 (sin(tc)*sin(d)*cos(lat1), cos(d) - sin(lat1)*sin(lat))
            //		lon	 = mod (lon1 + dlon + pi, 2*pi) - pi
            dlon = Math.Atan2(Math.Sin(3.0 * Math.PI / 2.0) * Math.Sin(dDistInRad) * Math.Cos(dLatInRads), Math.Cos(dDistInRad) - Math.Sin(dLatInRads) * Math.Sin(lat));
            box.LeftLine = ((dLongInRads + dlon + Math.PI) % (2.0 * Math.PI)) - Math.PI;
            box.LeftLine *= (180.0 / Math.PI);

            return box;
        }
示例#3
0
        /// <summary>
        /// Calculates the great-circle distance between two points on a sphere from their 
        /// longitudes and latitudes.
        /// </summary>
        /// <remarks>See: http://en.wikipedia.org/wiki/Haversine_formula</remarks>
        /// <param name="loc1"></param>
        /// <param name="loc2"></param>
        /// <returns></returns>
        public static double CalculateDistance(Location loc1, Location loc2)
        {
            /*
                The Haversine formula according to Dr. Math.
                http://mathforum.org/library/drmath/view/51879.html

                dlon = lon2 - lon1
                dlat = lat2 - lat1
                a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
                c = 2 * atan2(sqrt(a), sqrt(1-a))
                d = R * c

                Where
                    * dlon is the change in longitude
                    * dlat is the change in latitude
                    * c is the great circle distance in Radians.
                    * R is the radius of a spherical Earth.
                    * The locations of the two points in spherical coordinates (longitude and
                        latitude) are lon1,lat1 and lon2, lat2.
            */
            double dDistance = double.MinValue;
            double dLat1InRad = loc1.Latitude * (Math.PI / 180.0);
            double dLong1InRad = loc1.Longitude * (Math.PI / 180.0);
            double dLat2InRad = loc2.Latitude * (Math.PI / 180.0);
            double dLong2InRad = loc2.Longitude * (Math.PI / 180.0);

            double dLongitude = dLong2InRad - dLong1InRad;
            double dLatitude = dLat2InRad - dLat1InRad;

            // Intermediate result a.
            double a = Math.Pow(Math.Sin(dLatitude / 2.0), 2.0) + Math.Cos(dLat1InRad) * Math.Cos(dLat2InRad) * Math.Pow(Math.Sin(dLongitude / 2.0), 2.0);

            // Intermediate result c (great circle distance in Radians).
            double c = 2.0 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1.0 - a));

            // Distance.
            dDistance = Globals.EarthRadiusMiles * c;

            return dDistance;
        }
示例#4
0
 static void DisplayLocation(Location location)
 {
     Console.WriteLine(location);
     Console.WriteLine();
 }
示例#5
0
        internal static void Verify(Location location)
        {
            if (location == null)
            {
                throw new ArgumentNullException("location");
            }

            if (location.Latitude == double.MinValue)
            {
                throw new ArgumentException("inLoc1.Latitude", string.Format("The database does not contain latitude information for {0}, {1}.", location.City, location.State));
            }

            if (location.Longitude == double.MinValue)
            {
                throw new ArgumentException("inLoc1.Longitude", string.Format("The database does not contain longitude information for {0}, {1}.", location.City, location.State));
            }
        }