Resolved Google map API call from winform

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
159
Programming Experience
1-3
I have a winform app and want to add a call a Google API with two or more postcodes and I want the API to return the driving distance between these 2 or more point.

I intend to use net.http and newtonsoft JSON object. JohnH posted code for an earlier answer that should help me.

The API on another forum is
"http://maps.googleapis.com/maps/api...e2&mode=bicycling&language=en-EN&sensor=false"

I believe you can country too!

Before I proceed what else should I know?

I know you need a token but some say you don't?
 
Code:
Private Async Sub Button2_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim address = "https://us-central1-dadsofunny.cloudfunctions.net/DadJokes/random/jokes"
    Using client As New Net.Http.HttpClient(), result = Await client.GetAsync(address)
        If result.IsSuccessStatusCode Then
            Dim content = Await result.Content.ReadAsStringAsync
            Dim j = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Joke)(content)
            TextBox1.Lines = {j.Type, j.Setup, j.Punchline}
        Else
            TextBox1.Text = "error downloading"
        End If
    End Using
End Sub

Class Joke
    Public Property Id As String
    Public Property Type As String
    Public Property Setup As String
    Public Property Punchline As String
End Class
 
The returned json:
{
"destination_addresses" : [],
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to Account Changes | Google Maps Platform | Google Cloud",
"origin_addresses" : [],
"rows" : [],
"status" : "REQUEST_DENIED"
}
Follow the link given in error message for information about account changes.

Here is documentation for Overview | Distance Matrix API | Google Developers
I haven't tried it, but it seems to me that you can send http requests and get json data in return with this api just like the jokes one.
 
So here is my code so far, cant get access to the json object fields.

I am getting back OK from the API, but need to traverse the fields...

VB.NET:
Imports System.IO
Imports System.Net
Imports System.Net.Http
Imports Newtonsoft.Json

Public Class Form1
    Private API_Key As String = "xxxx" 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub

    Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim address = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=B34+123H&destinations=L01+KF59&language=en-EN&key=" & Me.API_Key.ToString & "&sensor=false"
        Using client As New Net.Http.HttpClient(), result = Await client.GetAsync(address)
            If result.IsSuccessStatusCode Then
                Dim content = Await result.Content.ReadAsStringAsync
                Dim G = Newtonsoft.Json.JsonConvert.DeserializeObject(Of GMatrix)(content)
                TextBox1.Text = G.ToString() ' {G.status, G.elements}
                TextBox2.Text = G.status.ToString()
              
  Dim reader As New JsonTextReader

                Using (r = reader.StringReader(content)))
                    While (reader.Read())
                        Me.TextBox2.Text = Me.TextBox2.Text & reader.TokenType & " " & reader.ValueType & " " & reader.Value & vbCrLf
                    End While

                End Using



                Dim rows = G.rows
                For Each r In rows.
                    Me.TextBox2.Text = Me.TextBox2.Text & r.elements.distance.text
                Next

            Else
                TextBox2.Text = "error downloading"
            End If
        End Using
    End Sub

    Class GMatrix
        Public Property status As String
        Public Property elements As String
        Public Property rows As String
      
    End Class
 
JSON object looks like this....
JSON:
{
   "status":"OK",
   "origin_addresses":[
      "Vancouver, BC, Canada",
      "Seattle, État de Washington, États-Unis"
   ],
   "destination_addresses":[
      "San Francisco, Californie, États-Unis",
      "Victoria, BC, Canada"
   ],
   "rows":[
      {
         "elements":[
            {
               "status":"OK",
               "duration":{
                  "value":340110,
                  "text":"3 jours 22 heures"
               },
               "distance":{
                  "value":1734542,
                  "text":"1 735 km"
               }
            },
            {
               "status":"OK",
               "duration":{
                  "value":24487,
                  "text":"6 heures 48 minutes"
               },
               "distance":{
                  "value":129324,
                  "text":"129 km"
               }
            }
         ]
      },
      {
         "elements":[
            {
               "status":"OK",
               "duration":{
                  "value":288834,
                  "text":"3 jours 8 heures"
               },
               "distance":{
                  "value":1489604,
                  "text":"1 490 km"
               }
            },
            {
               "status":"OK",
               "duration":{
                  "value":14388,
                  "text":"4 heures 0 minutes"
               },
               "distance":{
                  "value":135822,
                  "text":"136 km"
               }
            }
         ]
      }
   ]
}
 
Last edited by a moderator:
Click code button </> and select "JSON", paste the json data in dialog, and it get easier to read. I fixed the post.
 
"rows" is not a string, it is an array of some sort. I haven't look at the structure. In json {} means object and [] means array, "x": means property, the part after : is the value/object of property.
You can probably work out the data classes from the documentation, or possibly there exist some sort of mapper utility that can take sample data and generate the classes for you.
 
I understand that John but you first have to assign the class structure to match and then use the reader to read each element...
 
I fixed the formatting of json data in post 5 so it's easier to see the structure. You can just break it down from bottom to top.
pseudo class structures:
class ValuePair
property value as integer
property text as string

class Element
property status as string
property duration as ValuePair
property distance as ValuePair

class Row
property elements as Element array

class Reponse
property status as string
property origin_addresses as string array
property destination_addresses as string array
property rows as Row array
Then with a call to JsonConvert.DeserializeObject(Of Reponse)(content) you have the whole data tree parsed.
 
So here is the VB.net class code....
VB.NET:
  Class ValuePair
        Public Property value As Integer
        Public Property text As String
    End Class

    Class Element
        Public Property status As String
        Public Property duration As ValuePair
        Public Property distance As ValuePair
    End Class

    Class Row
        Public Property elements As Element()  'Array
    End Class

    Class Response
        Public Property status As String
        Public Property origin_addresses As String() ' Array
        Public Property destination_addresses As String() ' Array
        Public Property rows As Row() 'Array
    End Class

Not sure how to use though, I will try
 
Last edited:
Tried this but comig back with error...

VB.NET:
 Dim response = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Response)(content)
TextBox1.Text = response.status               
TextBox2.Text = response.rows(0).elements(0).distance.value

Error on last line Object Ref not set to instance of object! maybe in class???
 
When content is the json string you posted line 3 returns 1734542.
 
Hi,

Got it working thanks, I'm using Eircodes from Ireland so had to add +ire to the string!

But thanks for your help worked a treat!
 
Last edited:
Thats the correct answer but doesnt work for me, what am I missing?
Only you can see what your content string contains.
 
Add a reply rather than change a post that has been replied to.
Got it working thanks, I'm using Eircodes from Ireland so had to add +ire to the string!
That would suggest you got an error with your previous request. In documentation the error codes are explained, only when status is "OK" the response contains expected data. Errors may occur for many reasons and your code should include a check for this. If you look back to the error response shown in post 3 you see it has a non-OK status and also a "error_message" property, add this property to the response class.
VB.NET:
if response.status = "OK" then
   'good to go
else
   'show reponse.status and response.error_message
end if
 
Back
Top