Skip to content

Instantly share code, notes, and snippets.

@FelicePollano
Created January 13, 2012 10:40
Show Gist options
  • Select an option

  • Save FelicePollano/1605472 to your computer and use it in GitHub Desktop.

Select an option

Save FelicePollano/1605472 to your computer and use it in GitHub Desktop.
RouteResolver
public class RouteResolver
{
string language = "en-GB";
public RouteResolver()
{
}
public RouteResolver(string language)
{
this.language = language;
}
readonly string URITemplate = "http://maps.googleapis.com/maps/api/directions/json?origin={0},{1}&destination={2},{3}&sensor=true&alternatives=true&language={4}";
public void AsyncResolve(double lat1, double lon1,double lat2,double lon2, Action<IEnumerable<Route>> callback)
{
WebClient client = new WebClient();
client.Encoding = Encoding.UTF8;
client.DownloadStringCompleted += (s, e) =>
{
if (e.Error == null)
{
var rinfo = ReadToObject<DirectionsResponse>(e.Result);
callback(rinfo.Routes);
}
else
{
callback(new Route[] { });
}
};
client.DownloadStringAsync(new Uri(GetFormattedUri(lat1, lon1,lat2,lon2)));
}
public static T ReadToObject<T>(string json) where T : class
{
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
T res = ser.ReadObject(ms) as T;
ms.Close();
return res;
}
#region CONTRACTS
[DataContract(Name = "DirectionsResponse")]
public class DirectionsResponse
{
[DataMember(Name = "status")]
public string Status
{
get;set;
}
/// <summary>
/// "routes" contains an array of routes from the origin to the destination. See Routes below.
/// </summary>
[DataMember(Name = "routes")]
public IEnumerable<Route> Routes { get; set; }
public override string ToString()
{
return string.Format("DirectionsResponse - Status: {0}, Results count: {1}", Status, Routes != null ? Routes.Count() : 0);
}
}
/// <summary>
/// duration indicates the total duration of this leg
/// These fields may be absent if the duration is unknown.
/// </summary>
[DataContract(Name = "duration")]
public class Duration
{
[DataMember(Name = "value")]
public int ValueInSec
{
get
{
return (int)Math.Round(Value.TotalSeconds);
}
set
{
Value = TimeSpan.FromSeconds(value);
}
}
/// <summary>
/// value indicates the duration in seconds.
/// </summary>
public TimeSpan Value { get; set; }
/// <summary>
/// text contains a human-readable representation of the duration.
/// </summary>
[DataMember(Name = "text")]
public string Text { get; set; }
}
[DataContract(Name="distance")]
public class Distance
{
/// <summary>
/// value indicates the distance in meters
/// </summary>
[DataMember(Name="value")]
public int Value { get; set; }
/// <summary>
/// text contains a human-readable representation of the distance, displayed in units as used at the origin, in the language specified in the request. (For example, miles and feet will be used for any origin within the United States.) Note that regardless of what unit system is displayed as text, the distance.value field always contains a value expressed in meters.
/// </summary>
[DataMember(Name = "text")]
public string Text { get; set; }
}
[DataContract(Name = "location")]
public class Location
{
[DataMember(Name = "lat")]
public double Lat { get; set; }
[DataMember(Name = "lng")]
public double Long { get; set; }
}
/// <summary>
/// Each element in the steps array defines a single step of the calculated directions. A step is the most atomic unit of a direction's route, containing a single step describing a specific, single instruction on the journey. E.g. "Turn left at W. 4th St." The step not only describes the instruction but also contains distance and duration information relating to how this step relates to the following step. For example, a step denoted as "Merge onto I-80 West" may contain a duration of "37 miles" and "40 minutes," indicating that the next step is 37 miles/40 minutes from this step.
/// </summary>
[DataContract(Name = "step")]
public class Step
{
/// <summary>
/// html_instructions contains formatted instructions for this step, presented as an HTML text string.
/// </summary>
[DataMember(Name = "html_instructions")]
public string HtmlInstructions { get; set; }
/// <summary>
/// distance contains the distance covered by this step until the next step. (See the discussion of this field in Directions Legs above.) This field may be undefined if the distance is unknown.
/// </summary>
[DataMember(Name = "distance")]
public Distance Distance { get; set; }
/// <summary>
/// duration contains the typical time required to perform the step, until the next step (See the description in Directions Legs above.) This field may be undefined if the duration is unknown.
/// </summary>
[DataMember(Name = "duration")]
public Duration Duration { get; set; }
/// <summary>
/// start_location contains the location of the starting point of this step, as a single set of lat and lng fields.
/// </summary>
[DataMember(Name = "start_location")]
public Location StartLocation { get; set; }
/// <summary>
/// end_location contains the location of the starting point of this step, as a single set of lat and lng fields.
/// </summary>
[DataMember(Name = "end_location")]
public Location EndLocation { get; set; }
}
[DataContract(Name = "leg")]
public class Leg
{
/// <summary>
/// steps[] contains an array of steps denoting information about each separate step of the leg of the journey. (See Directions Steps below.)
/// </summary>
[DataMember(Name = "steps")]
public IEnumerable<Step> Steps { get; set; }
/// <summary>
/// distance indicates the total distance covered by this leg
/// </summary>
[DataMember(Name = "distance")]
public Distance Distance { get; set; }
/// <summary>
/// duration indicates the total duration of this leg,
/// </summary>
[DataMember(Name = "duration")]
public Duration Duration { get; set; }
/// <summary>
/// start_location contains the latitude/longitude coordinates of the origin of this leg. Because the Directions API calculates directions between locations by using the nearest transportation option (usually a road) at the start and end points, start_location may be different than the provided origin of this leg if, for example, a road is not near the origin.
/// </summary>
[DataMember(Name = "start_location")]
public Location StartLocation { get; set; }
/// <summary>
/// end_location contains the latitude/longitude coordinates of the given destination of this leg. Because the Directions API calculates directions between locations by using the nearest transportation option (usually a road) at the start and end points, end_location may be different than the provided destination of this leg if, for example, a road is not near the destination.
/// </summary>
[DataMember(Name = "end_location")]
public Location EndLocation { get; set; }
/// <summary>
/// start_address contains the human-readable address (typically a street address) reflecting the start_location of this leg.
/// </summary>
[DataMember(Name = "start_address")]
public string StartAddress { get; set; }
/// <summary>
/// end_addresss contains the human-readable address (typically a street address) reflecting the end_location of this leg.
/// </summary>
[DataMember(Name = "end_address")]
public string EndAddress { get; set; }
}
[DataContract(Name = "route")]
public class Route
{
/// <summary>
/// summary contains a short textual description for the route, suitable for naming and disambiguating the route from alternatives.
/// </summary>
[DataMember(Name = "summary")]
public string Summary { get; set; }
/// <summary>
/// legs[] contains an array which contains information about a leg of the route, between two locations within the given route. A separate leg will be present for each waypoint or destination specified. (A route with no waypoints will contain exactly one leg within the legs array.) Each leg consists of a series of steps. (See Directions Legs below.)
/// </summary>
[DataMember(Name = "legs")]
public IEnumerable<Leg> Legs { get; set; }
/// <summary>
/// waypoint_order contains an array indicating the order of any waypoints in the calculated route. This waypoints may be reordered if the request was passed optimize:true within its waypoints parameter.
/// </summary>
[DataMember(Name = "waypoint_order")]
public int[] WaypointOrder { get; set; }
/// <summary>
/// overview_path contains an object holding an array of encoded points and levels that represent an approximate (smoothed) path of the resulting directions.
/// </summary>
[DataMember(Name = "overview_polyline")]
public string[] OverviewPath { get; set; }
/// <summary>
/// copyrights contains the copyrights text to be displayed for this route. You must handle and display this information yourself.
/// </summary>
[DataMember(Name = "copyrights")]
public string Copyrights { get; set; }
/// <summary>
/// warnings[] contains an array of warnings to be displayed when showing these directions. You must handle and display these warnings yourself.
/// </summary>
[DataMember(Name = "warnings")]
public string[] Warnings { get; set; }
}
#endregion
private string GetFormattedUri(double lat1, double lon1,double lat2,double lon2)
{
return string.Format(CultureInfo.InvariantCulture, URITemplate, lat1, lon1,lat2,lon2,language);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment