4
votes

I want to calculate the distance between points in C# with the google maps distance matrix API.

I use the following code to make the request :

private void MapsAPICall()
    {
        //Pass request to google api with orgin and destination details
        HttpWebRequest request =
            (HttpWebRequest)WebRequest.Create("http://maps.googleapis.com/maps/api/distancematrix/json?origins="
            + "51.123959,3.326682" + "&destinations=" + "51.158089,4.145267" 
            + "&mode=Car&language=us-en&sensor=false");

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        using (var streamReader = new StreamReader(response.GetResponseStream()))
        {
            var result = streamReader.ReadToEnd();

            if (!string.IsNullOrEmpty(result))
            {
                Distance t = JsonConvert.DeserializeObject<Distance>(result);
            }
        }
    }

And then I want to parse the json answer into the Distance class:

public struct Distance
{
   // Here I want to parse the distance and duration
}

Here is an example of the json response I receive : http://maps.googleapis.com/maps/api/distancematrix/json?origins=Vancouver+BC&destinations=San+Francisco&mode=bicycling&language=fr-FR&sensor=false

How do I parse the distance and duration into the Distance class?
This is the first time I use Json so I'm not experienced with it.

Ps: I have the json.net library installed.

4

4 Answers

5
votes

Web Essentials has an option to 'Paste JSON as classes'. This will generate the classes you need to deserialize your JSON.

Using this option will generate the following for you:

public class Distance
{
    public string text { get; set; }
    public int value { get; set; }
}

public class Duration
{
    public string text { get; set; }
    public int value { get; set; }
}

public class Element
{
    public Distance distance { get; set; }
    public Duration duration { get; set; }
    public string status { get; set; }
}

public class Row
{
    public Element[] elements { get; set; }
}

public class Parent
{
    public string[] destination_addresses { get; set; }
    public string[] origin_addresses { get; set; }
    public Row[] rows { get; set; }
    public string status { get; set; }
}

(If you want, you can refactor the generated code to make it more readable. You will need to add Json.NET attributes to make sure that serialization is still working)

Then inside your code you can use the following line to deserialize your code:

Parent result = JsonConvert.DeserializeObject<Parent>(json);
2
votes

Update for Visual Studio 2015+

As a complement to Wouter de Kort's helpful answer, here is an update for Visual Studio 2015+.

Visual Studio 2015+ has that handy 'Paste JSON as Classes' that Wouter kindly described.

To generate the needed classes for GoogleMaps API JSON deserialization yourself:

  1. In a Web Browser or REST client, navigate to the GoogleMaps API URL with some test parameters populated. For example: https://maps.googleapis.com/maps/api/distancematrix/json?origins=30.3449153,-81.860543&destinations=33.7676932,-84.4906437&language=en-US&units=imperial&key=<API_KEY>
  2. Copy (Ctrl+C) the resulting raw JSON response from your browser/client to your clipboard.
  3. In Visual Studio 2015+, open the .cs file in which you would like to create the classes.
  4. Place your cursor in the .cs file where you would like the classes generated.
  5. From Visual Studio's menu choose Edit > Paste Special > Paste JSON as Classes

Example of Resulting Classes

public class Rootobject
{
    public string[] destination_addresses { get; set; }
    public string[] origin_addresses { get; set; }
    public Row[] rows { get; set; }
    public string status { get; set; }
}

public class Row
{
    public Element[] elements { get; set; }
}

public class Element
{
    public Distance distance { get; set; }
    public Duration duration { get; set; }
    public string status { get; set; }
}

public class Distance
{
    public string text { get; set; }
    public int value { get; set; }
}

public class Duration
{
    public string text { get; set; }
    public int value { get; set; }
}

From that point on, you can follow the rest of Wouter's advice.

Rootobject result = JsonConvert.DeserializeObject<Rootobject>(json);
0
votes

It's late but could be useful to someone. In such cases where we have a JSON string and wants to have a proper class structure to deserialize it correctly, you may use online tool http://json2csharp.com/

Just paste your JSON string and click on Generate button. It will provide you with the required class structure. It's that simple. This approach is useful when you want to avoid installing external tools.

-1
votes

The 'Distance' type will need to correctly model the JSON schema e.g:

public string[] destination_addresses { get; set; }
public string[] origin_addresses { get; set; }
public Row[] rows { get; set; }
public string status { get; set; }

(and of course then the sub-types like Row will also need to be modelled)

Other than that, your usage of Json.Net:

Distance t = JsonConvert.DeserializeObject<Distance>(result);

should be ok