Android Code Snippet [B4X] Google Geocoding REST API

Discussion in 'Code Snippets' started by Erel, Sep 13, 2017.

  1. Erel

    Erel Administrator Staff Member Licensed User

    This code is compatible with B4A, B4i and B4J (versions with support for resumable subs that return values).

    1. Get an API key: https://developers.google.com/maps/documentation/geocoding/get-api-key

    2.
    Code:
    Sub PlaceToLatLon(Place As StringAs ResumableSub
       
    Dim res() As Double = Array As Double(99999999)
       
    Dim j As HttpJob
       j.Initialize(
    "", Me)
       j.Download2(
    "https://maps.googleapis.com/maps/api/geocode/json"Array As String("key", API_KEY, "address", Place))
       
    Wait For (j) JobDone(j As HttpJob)
       
    If j.Success Then
         
    Dim jp As JSONParser
         jp.Initialize(j.GetString)
         
    Dim m As Map = jp.NextObject
         
    If m.Get("status") = "OK" Then
           
    Dim results As List = m.Get("results")
           
    If results.Size > 0 Then
             
    Dim first As Map = results.Get(0)
             
    Dim geometry As Map = first.Get("geometry")
             
    Dim location As Map = geometry.Get("location")
             res(
    0) = location.Get("lat")
             res(
    1) = location.Get("lng")
           
    End If
         
    End If
       
    Else
         
    Log("Error!")
       
    End If
       j.Release
       
    Return res
    End Sub
    Usage example:
    Code:
    Wait For(PlaceToLatLon("Israel Yodfat")) Complete (ll() As Double)
    If ll(0) <> 9999 Then
       
    Log("Location: " & ll(0) & ", " & ll(1))
    Else
       
    Log("Failed to geocode.")
    End If
     
  2. KMatle

    KMatle Expert Licensed User

    Get address from latitude & longitude (e.g. from the GPS coordinates)
    Code:
    Dim GetAddressJob As HttpJob
        GetAddressJob.Initialize(
    "GetAddress", Me)
        GetAddressJob.Download2(
    "https://maps.googleapis.com/maps/api/geocode/json", _
                  
    Array As String("latlng", lat & "," & lon,"key",API_KEY))
    Get directions (Location A -> Location B)
    Code:
    Dim GetDirectionsJob As HttpJob
        GetDirectionsJob.Initialize(
    "Directions", Me)
        GetDirectionsJob.Download2(
    "https://maps.googleapis.com/maps/api/directions/json", _
                  
    Array As String("origin","Cologne","destination","Paris","key",API_KEY))
     
  3. wes58

    wes58 Active Member Licensed User

    If you use code from post #2 to get directions, you might want to use this code to draw polylines from encoded polyline that you will receive. This gives you an accurate polyline that follows the road.

    Code:
    Dim travelduration As Int = 0
    Dim traveldistance As Int = 0
    Dim start_address As String
    Dim end_address As String
    Dim pline As Polyline
    Dim polyPoints As String

    Sub GetDirections(source As String, destination As String'As ResumableSub
        Dim j As HttpJob
        
    Dim API_KEY As String = "insert your api key "        'directions api key
    '    Get directions (Location A -> Location B)
        j.Initialize("Directions", Me)
        j.Download2(
    "https://maps.googleapis.com/maps/api/directions/json"Array As String("origin", source,"destination", destination,"key",API_KEY))

        
    Wait For (j) JobDone(j As HttpJob)
        
    If j.Success Then
            
    Dim parser As JSONParser
            parser.Initialize(j.GetString)
            
    Dim root As Map = parser.NextObject
            
    If root.Get("status") = "OK" Then
                
    Dim routes As List = root.Get("routes")
                
    For Each colroutes As Map In routes
                    
    Dim legs As List = colroutes.Get("legs")
                    
    For Each collegs As Map In legs
                        start_address  = collegs.Get(
    "start_address")
                        end_address = collegs.Get(
    "end_address")
                        
    Dim steps As List = collegs.Get("steps")
                        
    For Each colsteps As Map In steps
                            
    Dim duration As Map = colsteps.Get("duration")
                            travelduration = travelduration + duration.Get(
    "value")
                            
    Dim distance As Map = colsteps.Get("distance")
                            traveldistance = traveldistance + distance.Get(
    "value")
                        
    Next
                        
    Dim overview_polyline As Map = colroutes.Get("overview_polyline")
                        polyPoints = overview_polyline.Get(
    "points")
                    
    Next
                
    Next
                j.Release
                drawDirections
                
    ToastMessageShow("Distance = " & traveldistance & "m, Time = " & travelduration & "s"True)
            
    Else
                
    ToastMessageShow("Error: " & root.Get("status"), True)
            
    End If
        
    Else
            
    Log("Error!")
        
    End If
        j.Release
    End Sub

    Sub drawDirections
        
    Dim jo As JavaObject
        
    Dim Points As List
        Points.Initialize
        jo.InitializeContext
        Points = jo.RunMethod(
    "decodePoly"Array(polyPoints))  
        
    If Points.Size > 0 Then
            pline = gmap.AddPolyline
            pline.Points = Points
            pline.Color = 
    Colors.Blue
        
    End If
    End Sub

    #if JAVA
    /**
        * Method to decode polyline points
        * Courtesy : jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
        * */
    import java.util.ArrayList;
    import java.util.List;
    import com.google.android.gms.maps.model.LatLng;
       
        public List<LatLng> decodePoly(String encoded){

            List<LatLng> poly = new ArrayList<LatLng>();
            int index = 0, len = encoded.length();
            int lat = 0, lng = 0;

            while (index < len) {
                int b, shift = 0, result = 0;
                do {
                    b = encoded.charAt(index++) - 63;
                    result |= (b & 0x1f) << shift;
                    shift += 5;
                } while (b >= 0x20);
                int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
                lat += dlat;

                shift = 0;
                result = 0;
                do {
                    b = encoded.charAt(index++) - 63;
                    result |= (b & 0x1f) << shift;
                    shift += 5;
                } while (b >= 0x20);
                int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
                lng += dlng;
                LatLng p = new LatLng((((double) lat / 1E5)), (((double) lng / 1E5)));
                poly.add(p);
            }
            return poly;
        }
    #End If
     
  4. magi6162

    magi6162 Well-Known Member Licensed User

    Post #3
    I try your code, but the polyline is approximated, why? (it does not follow the streets)
    ( in googlemap the path is more precise)

    thanks for help
     
  5. wes58

    wes58 Active Member Licensed User

    For me, it works fine. It follows the roads, roundabouts very well. By decoding polyline data the code is using all the information it gets from Google to draw the polyline path. Maybe you should post a picture to show what it looks like?
     
  6. magi6162

    magi6162 Well-Known Member Licensed User

    sorry, as soon as I can send an image
     
  7. Andris

    Andris Active Member Licensed User

    Last edited: Dec 10, 2017
  8. Erel

    Erel Administrator Staff Member Licensed User

    The Android key will not work with a REST api. You should use an unrestricted key.
     
    Andris likes this.
  9. Almora

    Almora Active Member Licensed User

    Code:
    Dim GetAddressJob As HttpJob
        GetAddressJob.Initialize(
    "GetAddress", Me)
        GetAddressJob.Download2(
    "https://maps.googleapis.com/maps/api/geocode/json", _
                  
    Array As String("latlng", lat & "," & lon,"key",API_KEY))
    how can I find the address using this code. can you add a sample project? Thank you
     
    Last edited: Mar 9, 2018
  10. wes58

    wes58 Active Member Licensed User

    You had all information how to do it in posts #1 and #2. But if you still haven't done it, you can try this code:
    Code:
    Sub LatLonToPlace(lat As Double, lon As Double) 'As ResumableSub
        Dim API_KEY As String = "your geocoding api key here"
        
    Dim res As String
        
    Dim GetAddressJob As HttpJob
        GetAddressJob.Initialize(
    "GetAddress", Me)
        GetAddressJob.Download2(
    "https://maps.googleapis.com/maps/api/geocode/json"Array As String("latlng", lat & "," & lon,"key",API_KEY))
        
    Wait For (GetAddressJob) JobDone(GetAddressJob As HttpJob)
        
    If GetAddressJob.Success Then
            
    Dim jp As JSONParser
            jp.Initialize(GetAddressJob.GetString)
            
    Dim m As Map = jp.NextObject
            
    If m.Get("status") = "OK" Then
                
    Dim results As List = m.Get("results")
                
    If results.Size > 0 Then
                    
    Dim first As Map = results.Get(0)
                    res = first.Get(
    "formatted_address")
                    
    Log(res)
                    
    'res contain address string
                End If
            
    End If
        
    End If
        GetAddressJob.Release
    End Sub
     
    stanks, DonManfred and Almora like this.
  11. Alexander Stolte

    Alexander Stolte Well-Known Member Licensed User

    and if i need only the city name?
     
  12. Erel

    Erel Administrator Staff Member Licensed User

    What is the output of Log(GetAddressJob.GetString)?
     
  13. Cebuvi

    Cebuvi Member Licensed User

    Hello

    I need help to get the city name from the result of GetAddressJob.GetString.

    *** Service (starter) Create ***
    ** Service (starter) Start **
    ** Activity (main) Create, isFirst = true **
    ** Activity (main) Resume **
    *** Service (httputils2service) Create ***
    ** Service (httputils2service) Start **
    {
    "plus_code" : {
    "compound_code" : "JVQC+X2 Leicester, UK",
    "global_code" : "9C4WJVQC+X2"
    },
    "results" : [
    {
    "address_components" : [
    {
    "long_name" : "157",
    "short_name" : "157",
    "types" : [ "street_number" ]
    },
    {
    "long_name" : "Belgrave Gate",
    "short_name" : "Belgrave Gate",
    "types" : [ "route" ]
    },
    {
    "long_name" : "Leicester",
    "short_name" : "Leicester",
    "types" : [ "postal_town" ]
    },
    {
    "long_name" : "Leicester",
    "short_name" : "Leicester",
    "types" : [ "administrative_area_level_2", "political" ]
    },
    {
    "long_name" : "England",
    "short_name" : "England",
    "types" : [ "administrative_area_level_1", "political" ]
    },
    {
    "long_name" : "United Kingdom",
    "short_name" : "GB",
    "types" : [ "country", "political" ]
    },
    {
    "long_name" : "LE1 3HS",
    "short_name" : "LE1 3HS",
    "types" : [ "postal_code" ]
    }
    ],
    "formatted_address" : "157 Belgrave Gate, Leicester LE1 3HS, UK",
    "geometry" : {
    "location" : {
    "lat" : 52.64005479999999,
    "lng" : -1.1300998
    },
    "location_type" : "ROOFTOP",
    "viewport" : {
    "northeast" : {
    "lat" : 52.64140378029149,
    "lng" : -1.128750819708498
    },
    "southwest" : {
    "lat" : 52.6387058197085,
    "lng" : -1.131448780291502
    }
    }
    },
    "place_id" : "ChIJRToYdRxhd0gR6MW-duRlnyM",
    "plus_code" : {
    "compound_code" : "JVR9+2X Leicester, United Kingdom",
    "global_code" : "9C4WJVR9+2X"
    },
    "types" : [ "street_address" ]
    },
    {
    "address_components" : [
    {
    "long_name" : "153",
    "short_name" : "153",
    "types" : [ "street_number" ]
    },
    {
    "long_name" : "Belgrave Gate",
    "short_name" : "Belgrave Gate",
    "types" : [ "route" ]
    },
    {
    "long_name" : "Leicester",
    "short_name" : "Leicester",
    "types" : [ "postal_town" ]
    },
    {
    "long_name" : "Leicester",
    "short_name" : "Leicester",
    "types" : [ "administrative_area_level_2", "political" ]
    },
    {
    "long_name" : "England",
    "short_name" : "England",
    "types" : [ "administrative_area_level_1", "political" ]
    },
    {
    "long_name" : "United Kingdom",
    "short_name" : "GB",
    "types" : [ "country", "political" ]
    },
    {
    "long_name" : "LE1",
    "short_name" : "LE1",
    "types" : [ "postal_code", "postal_code_prefix" ]
    }
    ],
    "formatted_address" : "153 Belgrave Gate, Leicester LE1, UK",
    "geometry" : {
    "location" : {
    "lat" : 52.640072,
    "lng" : -1.1303318
    },
    "location_type" : "RANGE_INTERPOLATED",
    "viewport" : {
    "northeast" : {
    "lat" : 52.64142098029151,
    "lng" : -1.128982819708498
    },
    "southwest" : {
    "lat" : 52.63872301970851,
    "lng" : -1.131680780291502
    }
    }
    },
    "place_id" : "EiAxNTMgQmVsZ3JhdmUgR2F0ZSwgTGVpY2VzdGVyLCBVSyIbEhkKFAoSCa2IC3UcYXdIEVg_
    Message longer than Log limit (4000). Message was truncated.



    Thanks
     
  14. Alexander Stolte

    Alexander Stolte Well-Known Member Licensed User

    Erel likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice