public static Route GetRoute(Location from, Location to) { lock (routes) { var key = Route.GetKey(from, to); if (routes.ContainsKey(key)) { return(routes[key]); } const double metersToMiles = 0.000621371192; const int maxDuration = 10; var doc = new XmlDocument(); var elapse = new TimeSpan(0, 0, 0); double totalDistance = 0; var url = "http://maps.googleapis.com/maps/api/directions/xml?origin=" + from.Lat + ", " + from.Lng + "&destination=" + to.Lat + ", " + to.Lng + "&sensor=false&units=imperial"; doc.Load(url); var status = doc.SelectSingleNode("//DirectionsResponse/status"); if (status == null || status.InnerText == "ZERO_RESULTS") { return(null); } var waypoints = new List <Waypoint> { new Waypoint(@from, new TimeSpan(0), 0) }; var legs = doc.SelectNodes("//DirectionsResponse/route/leg"); foreach (XmlNode leg in legs) { var stepNodes = leg.SelectNodes("step"); foreach (XmlNode stepNode in stepNodes) { var duration = int.Parse(stepNode.SelectSingleNode("duration/value").InnerText); var distance = double.Parse(stepNode.SelectSingleNode("distance/value").InnerText) * metersToMiles; var duration2 = new TimeSpan(0, 0, int.Parse(stepNode.SelectSingleNode("duration/value").InnerText)); var end = new Location(double.Parse(stepNode.SelectSingleNode("end_location/lat").InnerText), double.Parse(stepNode.SelectSingleNode("end_location/lng").InnerText)); var totalDistanceTemp = totalDistance; totalDistance += distance; var timeSpanTemp = elapse; elapse += duration2; if (duration > maxDuration) { var polyline = stepNode.SelectSingleNode("polyline/points").InnerText; var locations = DecodePolylinePoints(polyline); waypoints.AddRange(IncreaseGranularityInPolylineList(locations, duration, maxDuration, timeSpanTemp.TotalSeconds, distance, totalDistanceTemp)); } else { waypoints.Add(new Waypoint(end, elapse, totalDistance)); } } } waypoints.Add(new Waypoint(to, elapse, totalDistance)); var route = new Route(waypoints.ToArray()); routes.Add(key, route); return(route); } }