B4A Library Geocoder library

Geocoder library

The Geocoder library enables you to geocode coordinates and reverse geocode addresses.

The library adds two new Objects to the IDE:

Version: 2.1
  • Address
    Methods:
    • HasLatitude As Boolean
      Returns True if a latitude has been assigned to this Address, False otherwise.
    • HasLongitude As Boolean
      Returns True if a longitude has been assigned to this Address, False otherwise.
    • IsInitialized As Boolean
    Properties:
    • AddressLines As List [read only]
      Returns a List of Strings which are the address lines of the Address.
    • AdminArea As String [read only]
      Returns the administrative area name of the Address.
      For example, "CA", or Null if it is unknown.
    • CountryCode As String [read only]
      Returns the country code of the Address.
      For example "US", or Null if it is unknown.
    • CountryName As String [read only]
      Returns the localized country name of the Address.
      For example "Iceland", or Null if it is unknown.
    • FeatureName As String [read only]
      Returns the feature name of the Address.
      For example, "Golden Gate Bridge", or Null if it is unknown.
    • Latitude As Double [read only]
      Returns the latitude of the Address if known.
    • Locality As String [read only]
      Returns the locality of the Address.
      For example "Mountain View", or Null if it is unknown.
    • Longitude As Double [read only]
      Returns the longitude of the Address if known.
    • Phone As String [read only]
      Returns the phone number of the Address if known, or Null if it is unknown.
    • PostalCode As String [read only]
      Returns the postal code of the Address.
      For example "94110", or Null if it is unknown.
    • Premises As String [read only]
      Returns the premises of the Address, or Null if it is unknown.
    • SubAdminArea As String [read only]
      Returns the sub-administrative area name of the Address.
      For example, "Santa Clara County", or Null if it is unknown.
    • SubLocality As String [read only]
      Returns the sub-locality of the Address, or Null if it is unknown.
    • SubThoroughfare As String [read only]
      Returns the sub-thoroughfare name of the Address, or Null if it is unknown.
    • Thoroughfare As String [read only]
      Returns the thoroughfare name of the Address.
      For example, "1600 Ampitheater Parkway", or Null if it is unknown.
    • Url As String [read only]
      Returns the public URL for the Address, or Null if it is unknown.
  • Geocoder
    Events:
    • GeocodeDone (Addresses() As Address, Tag As Object)
    Methods:
    • GetFromLocation (Latitude As Double, Longitude As Double, MaxResults As Int, Tag As Object)
      Gets an Array of Address objects that describe the area immediately surrounding the given Latitude and Longitude.
      The Array of Address objects is passed back to B4A in the GeocodeDone event along with the Tag Object.
      Tag is not used by this method, it is simply a means by which you can associate an identifying Object with this task.
    • GetFromLocationName (LocationName As String, MaxResults As Int, Tag As Object)
      Gets an Array of Address objects that describe the named location.
      LocationName may be a place name such as "Dalvik, Iceland", an address such as "1600 Amphitheatre Parkway, Mountain View, CA", an airport code such as "SFO", etc...
      The Array of Address objects is passed back to B4A in the GeocodeDone event along with the Tag Object.
      Tag is not used by this method, it is simply a means by which you can associate an identifying Object with this task.
    • GetFromLocationName2 (LocationName As String, MaxResults As Int, LowerLeftLatitude As Double, LowerLeftLongitude As Double, UpperRightLatitude As Double, UpperRightLongitude As Double, Tag As Object)
      Returns an array of Addresses that are known to describe the named location within the geographical bounds.
      LocationName may be a place name such as "Dalvik, Iceland", an address such as "1600 Amphitheatre Parkway, Mountain View, CA", an airport code such as "SFO", etc..
      The Array of Address objects is passed back to B4A in the GeocodeDone event along with the Tag Object.
      Tag is not used by this method, it is simply a means by which you can associate an identifying Object with this task.
    • Initialize (EventName As String)
      Initialize the Geocoder object with the device's system Locale.
    • Initialize2 (EventName As String, Language As String)
      Initialize the Geocoder object with a Locale based on Language.
    • Initialize3 (EventName As String, Language As String, Country As String)
      Initialize the Geocoder object with a Locale based on Language and Country.
    • IsInitialized As Boolean
    • IsPresent As Boolean
      Returns true if the Geocoder methods GetFromLocation and GetFromLocationName etc are implemented.
      Lack of network connectivity may still cause these methods to return null or empty lists.

If any of the three Geocoder methods Get??? fail then the GeocodeDone event will simply be passed an array of zero Address objects.
Any exceptions will be caught and sent to the log.

Library files and demo code attached.

Martin.
 

Attachments

  • Geocoder_v2_10.zip
    21.6 KB · Views: 2,004
Last edited:

Marco Nissen

Active Member
Licensed User
Longtime User
I'm getting proper latitude and longitude (confirmed with google maps api), but getFromLocation always returns 0 results (google maps api returns a bunch). Anyone else experience this?

I have the same issue. any help for Marshmallow?
 

MarcoRome

Expert
Licensed User
Longtime User
I have the same issue. any help for Marshmallow?
Try this:


With this line you have this result in json:
{
"results" : [
{
"address_components" : [
{
"long_name" : "277",
"short_name" : "277",
"types" : [ "street_number" ]
},
{
"long_name" : "Bedford Avenue",
"short_name" : "Bedford Ave",
"types" : [ "route" ]
},
{
"long_name" : "Williamsburg",
"short_name" : "Williamsburg",
"types" : [ "neighborhood", "political" ]
},
{
"long_name" : "Brooklyn",
"short_name" : "Brooklyn",
"types" : [ "political", "sublocality", "sublocality_level_1" ]
},
{
"long_name" : "Kings County",
"short_name" : "Kings County",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "New York",
"short_name" : "NY",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "11211",
"short_name" : "11211",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "277 Bedford Ave, Brooklyn, NY 11211, USA",
"geometry" : {

With okhttp is done.
 

brunnlechner

Member
Licensed User
Longtime User
Hello,
is there a change in the Geocoder API since 20.06.2017?
On some devices, only NULL addresses are returned since 20.06.2017

Thank you
Franz
 

DonManfred

Expert
Licensed User
Longtime User
On some devices, only NULL addresses are returned
Just a thought: Does the device have the GoogleApis installed?

The Geocoder query methods will return an empty list if there no backend service in the platform. Use the isPresent() method to determine whether a Geocoder implementation exists.

Honestly i just do not know this lib. In the projects where i needed to have GeoCoding i used the http-api like in the Post #102 from @MarcoRome
 

qnw4ts7pge

Member
Licensed User
Longtime User
I get the following error when trying to access the "AddressLines" list of an Address object:
java.lang.ClassCastException: uk.co.martinpearman.b4a.location.AddressWrapper cannot be cast to android.location.Address
B4X:
'* Note - FoundAddresses is process global
'       Dim FoundAddresses as list

Sub Geocoder1_GeocodeDone(Results() As Address, Tag As Object)
   
   FoundAddresses.Initialize2(Results)

  DumpAddresses(FoundAddresses)
End Sub


Sub DumpAddresses(Addresses As List)
  
   If Addresses.Size>0 Then
     Log("=== GEOCODER ===")
     Log("  Total: "&Addresses.Size)
    
     Dim i As Int, j As Int, sOut As String
    
     For i=0 To Addresses.Size-1
       Dim a As Address
      
       Log("Address("&i&")")
      
       a=Addresses.Get(i)
       Log(a)
       Log(a.AddressLines.Get(0))     '<---- Error here
       Log("---")      
     Next
   Else
     Log("=== GEOCODER ===")
     Log("No Addresses Found")
   End If
End Sub

Any help would be greatly appreciated.
 

qnw4ts7pge

Member
Licensed User
Longtime User
Does it work if you keep it as an array instead of a list?

Interesting.... Your reply got me thinking.

I was assuming that the list.initialize2 method was basically doing the following, but when I code it explicitly, it works.

Changed this:

B4X:
  FoundAddresses.Initialize2(Results)

To this:

B4X:
  If FoundAddresses.IsInitialized Then
     FoundAddresses.Clear
   Else
     FoundAddresses.Initialize
   End If
   
   Dim i As Int
   For i=0 To Results.Length-1
     Dim a As Address
     a=Results(i)
     FoundAddresses.Add(a)
   Next

...and it works perfectly...

Thanks for the quick response, and problem solved.
 

marcick

Well-Known Member
Licensed User
Longtime User
On more of 100 devices where my app is installed, only one seems to suddenly have problems in reverse geocode.
It is a Samsung SM-G920F with Android 7.0. It was working fine for a long time, but suddenly it is not able to show any address.

This is the Geocode_Done code:

B4X:
Dim Address1 As Address
    Dim Adr As String
    If Results.Length>0 Then
        Address1=Results(0)
        Log(Address1)
        If Address1.AddressLines.Size>0 Then
            Adr=Address1.AddressLines.Get(0)
            If Address1.AddressLines.Size>1 Then Adr=Adr & " " & Address1.AddressLines.Get(1)
        Else
            Adr="Unknown address"
        End If
    Else
        Adr="Unknown address"
    End If

Giving a couple of coordinates, this is the normal result (Address1) that I see on the other 99 devices

B4X:
(Address)Address[addressLines=[0:"Via San Giuseppe Benedetto Cottolengo, 13",1:"20037 Paderno Dugnano MI",2:"Italia"],feature=13,admin=null,sub-admin=Città Metropolitana di Milano,locality=Paderno Dugnano,thoroughfare=Via San Giuseppe Benedetto Cottolengo,postalCode=20037,countryCode=IT,countryName=Italia,hasLatitude=true,latitude=45.5720745,hasLongitude=true,longitude=9.1461078,phone=null,url=null,extras=null]

And the above code extracts correctly the address

But on this Samsung, the same couple of coordinates give this result that looks a bit different

B4X:
(Address)Address[addressLines=[0:"Via S. Giuseppe Benedetto Cottolengo, 13, 20037 Paderno Dugnano MI, Italia"],feature=13,admin=Lombardia,sub-admin=Città Metropolitana di Milano,locality=Paderno Dugnano,thoroughfare=Via San Giuseppe Benedetto Cottolengo,postalCode=20037,countryCode=IT,countryName=Italia,hasLatitude=true,latitude=45.5720745,hasLongitude=true,longitude=9.1461078,phone=null,url=null,extras=null]

And the above code fails to extract the address because Address1.AddressLines.Size is 0

Any idea ?
 

marcick

Well-Known Member
Licensed User
Longtime User
I'm trying this workaround:

B4X:
    Dim Address1 As Address
    Dim Adr As String
    If Results.Length>0 Then
        Address1=Results(0)
        Log(Address1)
        If Address1.AddressLines.Size>0 Then
            Adr=Address1.AddressLines.Get(0)
            If Address1.AddressLines.Size>1 Then Adr=Adr & " " & Address1.AddressLines.Get(1)
        Else
            Adr=""
            If Address1.Thoroughfare <> Null Then Adr=Address1.Thoroughfare
            If Address1.SubThoroughfare <> Null Then Adr= Adr & " " & Address1.SubThoroughfare
            If Address1.PostalCode <> Null Then Adr= Adr & " " & Address1.PostalCode
            If Address1.Locality <> Null Then Adr= Adr & " " & Address1.Locality
        End If
    Else
        Adr="Indirizzo sconosciuto"
    End If

but the Address1.Locality contains just "20037 Paderno Dugnano" and should be "20037 Paderno Dugnano MI"
Looks like the text is clipped in the library ?
"MI" is the SubAdminArea as we usually write address in Italy. MI = Milano, TO=Torino, VE=Venezia etc.
If I check Address1.SubAdminArea I obtain "Città Metropolitana di Milano" that looks bad to show
 

Croïd

Active Member
Licensed User
Longtime User
On more of 100 devices where my app is installed, only one seems to suddenly have problems in reverse geocode.
It is a Samsung SM-G920F with Android 7.0. It was working fine for a long time, but suddenly it is not able to show any address.

Any idea ?

@marcick

I think the problem does not come from the library.

Geocoder not works on sony xperia and works fine on nexus

relationship with google key api !
 
Last edited:

Roberto P.

Well-Known Member
Licensed User
Longtime User
Hello to all
I also have problems with address: I have completed standard sample and entered my co-ordinates and can not extract address. See log

reading the post, I did not understand if I should integrate or modify the project to get address from coordinates?!

Latitude = 45.7202
longitude 9.71442
Address1.AddressLines.Size=0
Address1.AddressLines.Size=0
Address1.AddressLines.Size=0
Address1.AddressLines.Size=0
Address1.AddressLines.Size=0


thanks in advice
 

Roberto P.

Well-Known Member
Licensed User
Longtime User
Follow my workaround above when addressline.size is 0

visto che siamo della stessa zona, ti rispondo in Italiano. Ho visto e utilizzato il tuo codice, che funziona (grazie). Anche io riscontro il problema della provincia, che penso sia dovuto alle API e non alla libreria. Credo che per risolverlo, si dovrebbe fare una tabella di conversione delle province Italiane.
ciao
 

marcick

Well-Known Member
Licensed User
Longtime User
Yes, probably, but I'll not spend time without precise data to work on.
I'm actually not showing the Address1.SubAdminArea part that looks bad. Post code and city is enough ... :)
 

SMOOTSARA

Active Member
Licensed User
Longtime User
Geocoder library

The Geocoder library enables you to geocode coordinates and reverse geocode addresses.

The library adds two new Objects to the IDE:

Version: 2.1
  • Address
    Methods:
    • HasLatitude As Boolean
      Returns True if a latitude has been assigned to this Address, False otherwise.
    • HasLongitude As Boolean
      Returns True if a longitude has been assigned to this Address, False otherwise.
    • IsInitialized As Boolean
  • Properties:
    • AddressLines As List [read only]
      Returns a List of Strings which are the address lines of the Address.
    • AdminArea As String [read only]
      Returns the administrative area name of the Address.
      For example, "CA", or Null if it is unknown.
    • CountryCode As String [read only]
      Returns the country code of the Address.
      For example "US", or Null if it is unknown.
    • CountryName As String [read only]
      Returns the localized country name of the Address.
      For example "Iceland", or Null if it is unknown.
    • FeatureName As String [read only]
      Returns the feature name of the Address.
      For example, "Golden Gate Bridge", or Null if it is unknown.
    • Latitude As Double [read only]
      Returns the latitude of the Address if known.
    • Locality As String [read only]
      Returns the locality of the Address.
      For example "Mountain View", or Null if it is unknown.
    • Longitude As Double [read only]
      Returns the longitude of the Address if known.
    • Phone As String [read only]
      Returns the phone number of the Address if known, or Null if it is unknown.
    • PostalCode As String [read only]
      Returns the postal code of the Address.
      For example "94110", or Null if it is unknown.
    • Premises As String [read only]
      Returns the premises of the Address, or Null if it is unknown.
    • SubAdminArea As String [read only]
      Returns the sub-administrative area name of the Address.
      For example, "Santa Clara County", or Null if it is unknown.
    • SubLocality As String [read only]
      Returns the sub-locality of the Address, or Null if it is unknown.
    • SubThoroughfare As String [read only]
      Returns the sub-thoroughfare name of the Address, or Null if it is unknown.
    • Thoroughfare As String [read only]
      Returns the thoroughfare name of the Address.
      For example, "1600 Ampitheater Parkway", or Null if it is unknown.
    • Url As String [read only]
      Returns the public URL for the Address, or Null if it is unknown.
  • Geocoder
    Events:
    • GeocodeDone (Addresses() As Address, Tag As Object)
  • Methods:
    • GetFromLocation (Latitude As Double, Longitude As Double, MaxResults As Int, Tag As Object)
      Gets an Array of Address objects that describe the area immediately surrounding the given Latitude and Longitude.
      The Array of Address objects is passed back to B4A in the GeocodeDone event along with the Tag Object.
      Tag is not used by this method, it is simply a means by which you can associate an identifying Object with this task.
    • GetFromLocationName (LocationName As String, MaxResults As Int, Tag As Object)
      Gets an Array of Address objects that describe the named location.
      LocationName may be a place name such as "Dalvik, Iceland", an address such as "1600 Amphitheatre Parkway, Mountain View, CA", an airport code such as "SFO", etc...
      The Array of Address objects is passed back to B4A in the GeocodeDone event along with the Tag Object.
      Tag is not used by this method, it is simply a means by which you can associate an identifying Object with this task.
    • GetFromLocationName2 (LocationName As String, MaxResults As Int, LowerLeftLatitude As Double, LowerLeftLongitude As Double, UpperRightLatitude As Double, UpperRightLongitude As Double, Tag As Object)
      Returns an array of Addresses that are known to describe the named location within the geographical bounds.
      LocationName may be a place name such as "Dalvik, Iceland", an address such as "1600 Amphitheatre Parkway, Mountain View, CA", an airport code such as "SFO", etc..
      The Array of Address objects is passed back to B4A in the GeocodeDone event along with the Tag Object.
      Tag is not used by this method, it is simply a means by which you can associate an identifying Object with this task.
    • Initialize (EventName As String)
      Initialize the Geocoder object with the device's system Locale.
    • Initialize2 (EventName As String, Language As String)
      Initialize the Geocoder object with a Locale based on Language.
    • Initialize3 (EventName As String, Language As String, Country As String)
      Initialize the Geocoder object with a Locale based on Language and Country.
    • IsInitialized As Boolean
    • IsPresent As Boolean
      Returns true if the Geocoder methods GetFromLocation and GetFromLocationName etc are implemented.
      Lack of network connectivity may still cause these methods to return null or empty lists.

If any of the three Geocoder methods Get??? fail then the GeocodeDone event will simply be passed an array of zero Address objects.
Any exceptions will be caught and sent to the log.

Library files and demo code attached.

Martin.


Hello 🌹
Isn't this library capable of displaying GMT time ?
If the answer is no, it could be a good option for next updating the library 🙏
 
Top