/// <summary>
        /// Gets the distance between 2 points calculated with the curvature of the earth.
        /// </summary>
        /// <param name="locationA">
        /// The first point. 
        /// </param>
        /// <param name="locationB">
        /// The second point. 
        /// </param>
        /// <returns>
        /// The straight line distance in kilometers. 
        /// </returns>
        public static double GetStraightLineDistance(Location locationA, Location locationB)
        {
            /*
             * Sourced  from http://www.movable-type.co.uk/scripts/latlong.html
             * Javascript code:
                var R = 6371; // km
                var dLat = (lat2-lat1).toRad();
                var dLon = (lon2-lon1).toRad();
                var lat1 = lat1.toRad();
                var lat2 = lat2.toRad();

                var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                        Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
                var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
                var d = R * c;

             *
             * */
            const double R = 6371; // Mean radius of the earth in KM
            double dlat = ToRads(locationB.Latitude - locationA.Latitude);
            double dlon = ToRads(locationB.Longitude - locationA.Longitude);
            double lat1 = ToRads(locationA.Latitude);
            double lat2 = ToRads(locationB.Latitude);

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

            return R * c;
        }
        /// <summary>
        /// Returns the distance between 2 points using the specified transport mode.
        /// </summary>
        /// <param name="pointA">
        /// The first point 
        /// </param>
        /// <param name="pointB">
        /// The second point 
        /// </param>
        /// <param name="transportMode">
        /// Specified the mode of transport used between points. 
        /// </param>
        /// <returns>
        /// The distance between pointA and pointB 
        /// </returns>
        public Arc GetDistance(Location pointA, Location pointB, TransportMode transportMode)
        {
            // Set parameters
            this.Parameters["mode"] = transportMode.ToString().ToLower();
            this.Parameters["origins"] = pointA.ToString();
            this.Parameters["destinations"] = pointB.ToString();

            // Make XML request
            XmlDocument doc = this.Request();

            if (doc["DistanceMatrixResponse"] == null)
            {
                throw new Exception("XML response is invalid.");
            }

            XmlNode response = doc["DistanceMatrixResponse"];

            // Check for null references
            if (response == null || response["status"] == null)
            {
                throw new Exception("XML response is invalid.");
            }

            // Check request status
            if (response["status"].InnerText != "OK")
            {
                throw new GoogleApiException(response["status"].InnerText);
            }

            // Check for null references
            if (response["row"] == null || response["row"]["element"] == null)
            {
                throw new Exception("XML response is invalid.");
            }

            // Extract element
            XmlNode element = response["row"]["element"];

            // Check for null references
            if (element["duration"]["value"] == null || element["distance"]["value"] == null)
            {
                throw new Exception("XML response is invalid.");
            }

            // Get results
            var duration = new TimeSpan(0, 0, Convert.ToInt32(element["duration"]["value"].InnerText));
            double distance = Convert.ToDouble(element["distance"]["value"].InnerText);

            // Return new object
            return new Arc(
                pointA,
                pointB,
                new TransportTimeSpan { TravelTime = duration, WaitingTime = default(TimeSpan) },
                distance,
                default(DateTime),
                transportMode.ToString());
        }
 /// <summary>
 /// Estimates the distance between 2 points. This method must always underestimate the time and distance.
 /// </summary>
 /// <param name="locationA">
 /// The first point. 
 /// </param>
 /// <param name="locationB">
 /// The second point. 
 /// </param>
 /// <returns>
 /// The <see cref="Arc"/> representing the distance between the 2 points. 
 /// </returns>
 public Arc EstimateDistance(Location locationA, Location locationB)
 {
     double distance = GeometryHelper.GetStraightLineDistance(locationA, locationB);
     var time = TimeSpan.FromHours(distance / this.WalkSpeed);
     return new Arc(
         locationA,
         locationB,
         new TransportTimeSpan { TravelTime = time, WaitingTime = default(TimeSpan) },
         distance,
         default(DateTime),
         "Walking");
 }
Esempio n. 4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Arc"/> class. Initializes a new arc defining information between 2 points.
 /// </summary>
 /// <param name="source">
 /// The source location of the arc. 
 /// </param>
 /// <param name="destination">
 /// The destination location of the arc. 
 /// </param>
 /// <param name="time">
 /// The total time of the arc. 
 /// </param>
 /// <param name="distance">
 /// The total distance in Km of the arc. 
 /// </param>
 /// <param name="departureTime">
 /// The departure time of this arc. Set to default(DateTime) if departure time is not relevant. 
 /// </param>
 /// <param name="transportMode">
 /// Sets the transport id used in the arc. 
 /// </param>
 public Arc(
     Location source, 
     Location destination, 
     TransportTimeSpan time, 
     double distance, 
     DateTime departureTime, 
     string transportMode)
 {
     this.source = source;
     this.destination = destination;
     this.time = time;
     this.distance = distance;
     this.transportMode = transportMode;
     this.departureTime = departureTime;
 }
 /// <summary>
 /// Gets the path walked from locationA to locationB
 /// </summary>
 /// <param name="locationA">
 /// The first point. 
 /// </param>
 /// <param name="locationB">
 /// The second point. 
 /// </param>
 /// <returns>
 /// A list of <see cref="Location"/> objects that designate a path. 
 /// </returns>
 public List<Location> GetPath(Location locationA, Location locationB)
 {
     //// TODO: Impliment Google walking path finding.
     throw new NotImplementedException();
 }
 /// <summary>
 /// Gets the distance walking from locationA to locationB
 /// </summary>
 /// <param name="locationA">
 /// The first point. 
 /// </param>
 /// <param name="locationB">
 /// The second point. 
 /// </param>
 /// <returns>
 /// The <see cref="Arc"/> representing the distance between the 2 points. 
 /// </returns>
 public Arc GetDistance(Location locationA, Location locationB)
 {
     return this.distanceApi.GetDistance(locationA, locationB, TransportMode.Walking);
 }
        /// <summary>
        /// Calculates the new position if you were to move along the bearing for a specified distance.
        /// </summary>
        /// <param name="initial">
        /// The initial location 
        /// </param>
        /// <param name="bearing">
        /// The bearing in degrees from north in degrees. 
        /// </param>
        /// <param name="distance">
        /// The distance travelled in kilometers 
        /// </param>
        /// <returns>
        /// The new position. 
        /// </returns>
        public static Location Travel(Location initial, double bearing, double distance)
        {
            /*
             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));
             * */
            const double R = 6371; // Mean radius of the earth in KM
            bearing = ToRads(bearing);
            double lat1 = ToRads(initial.Latitude);
            double lon1 = ToRads(initial.Longitude);
            double lat2 =
                Math.Asin(
                    (Math.Sin(lat1) * Math.Cos(distance / R))
                    + (Math.Cos(lat1) * Math.Sin(distance / R) * Math.Cos(bearing)));
            double lon2 = lon1
                          +
                          Math.Atan2(
                              Math.Sin(bearing) * Math.Sin(distance / R) * Math.Cos(lat1),
                              Math.Cos(distance / R) - (Math.Sin(lat1) * Math.Sin(lat2)));

            lon2 = ((lon2 + (3.0 * Math.PI)) % (2 * Math.PI)) - Math.PI;

            return new Location(ToDegs(lat2), ToDegs(lon2));
        }
 /// <summary>
 /// Returns the distance between 2 points using the default transport mode (driving).
 /// </summary>
 /// <param name="pointA">
 /// The first point 
 /// </param>
 /// <param name="pointB">
 /// The second point 
 /// </param>
 /// <returns>
 /// The distance between pointA and pointB 
 /// </returns>
 public Arc GetDistance(Location pointA, Location pointB)
 {
     return this.GetDistance(pointA, pointB, TransportMode.Driving);
 }
        /// <summary>
        /// Gets a human readable address that is closest to the provided location.
        /// </summary>
        /// <param name="location">
        /// A location for which you want to find the nearest address 
        /// </param>
        /// <returns>
        /// A string representing a human readable address corresponding to that location. 
        /// </returns>
        public string GetLocationString(Location location)
        {
            this.Parameters.Remove("address");

            // Set new request data
            this.Parameters["latlng"] = location.ToString();

            // Perform XML request
            XmlDocument doc = this.Request();

            if (doc["GeocodeResponse"] == null || doc["GeocodeResponse"]["status"] == null)
            {
                throw new Exception("XML response is invalid.");
            }

            // Check request status
            if (doc["GeocodeResponse"]["status"].InnerText != "OK")
            {
                throw new Exception("Error processing XML request");
            }

            // Get the useful node
            XmlNode locationNode = doc["GeocodeResponse"]["result"]["formatted_address"];

            // Return the new location string
            return locationNode.InnerText;
        }