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,148
Last edited:

warwound

Expert
Licensed User
Longtime User
Take a look at the attached modified geocoder demo project and these logged results:

Geocoder1.Initialize("Geocoder1")
**********
Result(0)
AddressLines:
28ης Οκτωβρίου 2
Athens 106 77
CountryCode: Greece
Locality: Athens
**********
Result(1)
AddressLines:
Athens
CountryCode: Greece
Locality: Athens
==========

Geocoder1.Initialize3("Geocoder1", "en", "GB")
**********
Result(0)
AddressLines:
28ης Οκτωβρίου 2
Athens 106 77
CountryCode: Greece
Locality: Athens
**********
Result(1)
AddressLines:
Athens
CountryCode: Greece
Locality: Athens
==========

Geocoder1.Initialize3("Geocoder1", "fr", "FR")
**********
Result(0)
AddressLines:
28ης Οκτωβρίου 2
Athènes 106 77
CountryCode: Grèce
Locality: Athènes
**********
Result(1)
AddressLines:
Athènes
CountryCode: Grèce
Locality: Athènes

You can see i've geocoded a coordinate which is in central Athens.
The first AddressLine is the same no matter how i have initialized the Geocoder but the second AddressLine, CountryCode and Locality vary according to the way i've initialized the Geocoder
These results are from a Moto G running KitKat with the device locale set to English(GB).

I'd guess that the geocoder service does not have result data for all possible locales.
So if it has result data for your chosen locale it will return that data otherwise it will return whatever data it has.

Martin.
 

Attachments

  • Geocoder_locale_test.zip
    9.4 KB · Views: 424

Chris Williams

Member
Licensed User
Longtime User
Hello warwound. I have created an app which makes use of your library. Prior to my submitting it in Google Play, I would like to know what I need to do to properly give you credit for your work (I have credits page in the app)
 

warwound

Expert
Licensed User
Longtime User
Hello warwound. I have created an app which makes use of your library. Prior to my submitting it in Google Play, I would like to know what I need to do to properly give you credit for your work (I have credits page in the app)

Are you crediting other b4a lib developers in your app?
Just credit me as you would any other lib writer.

The Geocoder lib contains no code that requires special attribution.
 

achtrade

Active Member
Licensed User
Longtime User
Hello,

I'm using the demo from the post #1 and #61 and I'm not getting result for this address or any other:

568-570 Empire Blvd
Brooklyn, NY 11225
40.664098, -73.943494

please help.

thanks.
 

trueboss323

Active Member
Licensed User
Longtime User
Hi warwound,
I have simple question using your library. Is there a simple way i can get only the current country name from the device's location?
For example, with button click, i use something like : Msgbox("You are in " & countryname , "")
Thank you.
 

warwound

Expert
Licensed User
Longtime User
Hi warwound,
I have simple question using your library. Is there a simple way i can get only the current country name from the device's location?
For example, with button click, i use something like : Msgbox("You are in " & countryname , "")
Thank you.

Do you mean the name of the country that the device is currently located in?
Or the country(language) currently set in the device Settings?

Geocoder can only geocode an address or reverse geocode coordinates - neither of these will do either of the above.
 

trueboss323

Active Member
Licensed User
Longtime User
I mean I want to get the name of the country that the device is currently located.
Is there another library that is capable of doing it, or perhaps you could make one?
 

warwound

Expert
Licensed User
Longtime User
I mean I want to get the name of the country that the device is currently located.
Is there another library that is capable of doing it, or perhaps you could make one?

You need to get the device location - there's various libraries you can use to do that.
Then you need to reverse geocode the device location.

I'd suggest you search the forum for 'network location' and try to locate the device using a non gps method.
Wifi location or location based on network (3g) mast is likely to be the best solution.

My FusedLocationProvider might be worth looking at.
Configure it to use a low power method to get the device location.
 

trueboss323

Active Member
Licensed User
Longtime User
I looked at it, it seems nice thanks. Could you also please give a code example of how i could get the device location or the country in this case?
 

warwound

Expert
Licensed User
Longtime User
Download the example from post #2 in the FusedLocationProvider library.
Modify the activity code so it looks like this:

B4X:
Sub Process_Globals
    Private FusedLocationProvider1 As FusedLocationProvider
    Private LastLocation As Location
End Sub

Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
    '    **    IMPORTANT see manifest for required entries    **
    If FirstTime Then
        FusedLocationProvider1.Initialize("FusedLocationProvider1")
    End If
    
End Sub

Sub Activity_Resume
    '    attempt to connect to the location services
    '    after calling Connect we are waiting for either ConnectionFailed or ConnectionSuccess events
    FusedLocationProvider1.Connect
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    FusedLocationProvider1.Disconnect
End Sub

Sub FusedLocationProvider1_ConnectionFailed(ConnectionResult1 As Int)
    Log("FusedLocationProvider1_ConnectionFailed")
    
    '    the FusedLocationProvider ConnectionResult object contains the various CoonectionResult constants
    
    Select ConnectionResult1
        Case FusedLocationProvider1.ConnectionResult.NETWORK_ERROR
            '    a network error has occurred, this is likely to be a recoverable error
            '    so try to connect again
            FusedLocationProvider1.Connect
        Case Else
            '    TODO handle other errors
    End Select
End Sub

Sub FusedLocationProvider1_ConnectionSuccess
    Log("FusedLocationProvider1_ConnectionSuccess")

    Dim LastKnownLocation As Location
    LastKnowLocation=FusedLocationProvider1.GetLastKnownLocation

    If LastKnowLocation.IsInitialized Then
        GeocodeLocation(LastKnowLocation)
    Else
        Dim LocationRequest1 As LocationRequest
        LocationRequest1.Initialize
        LocationRequest1.SetInterval(1000)    '    1000 milliseconds
        LocationRequest1.SetPriority(LocationRequest1.Priority.PRIORITY_NO_POWER)
        LocationRequest1.SetSmallestDisplacement(1)    '    1 meter
        FusedLocationProvider1.RequestLocationUpdates(LocationRequest1)
    End If
End Sub

Sub FusedLocationProvider1_ConnectionSuspended(SuspendedCause1 As Int)
    Log("FusedLocationProvider1_ConnectionSuspended")
    
    '    the FusedLocationProvider SuspendedCause object contains the various SuspendedCause constants
    
    Select SuspendedCause1
        Case FusedLocationProvider1.SuspendedCause.CAUSE_NETWORK_LOST
            '    TODO take action
        Case FusedLocationProvider1.SuspendedCause.CAUSE_SERVICE_DISCONNECTED
            '    TODO take action
    End Select
End Sub

Sub FusedLocationProvider1_LocationChanged(Location1 As Location)
    Log("FusedLocationProvider1_LocationChanged")

    FusedLocationProvider1.RemoveLocationUpdates
    GeocodeLocation(Location1)
End Sub

Sub GeocodeLocation(Location1 As Location)
    Log("GeocodeLocation: "&Location1.Latitude&", "&Location1.Longitude)
    '    here you can get the Location Latitude and Longitude properties and use the Geocoder library to perform a reverse geocode
    '    if the reverse geocode is successful you will have the country that the device is located in
End Sub

Modify the manifest, replace ACCESS_FINE_LOCATION with ACCESS_COARSE_LOCATION.

Now compile and run the project.
Do you see the GeocodeLocation sub is called and the coordinates of the device's location are logged?

If so you can now update the GeocodeLocation sub to use the Geocoder library to reverse geocode those coordinates.
If the reverse geocode is successful you can extract the device's current country from the Address object.

Martin.
 

trueboss323

Active Member
Licensed User
Longtime User
Hi warwound,
Thanks for your help, i finally got the code to work. The location service says it's failed on the emulator, but it works on the real device, just wondering if that's an issue i should be concerned? Maybe i need to turn on gps in the emulator?
Anyway i played around with GeoLocation sub for a bit, sorry I'm not good at this, can't figure out exactly how to do the reverse geocode part. I also didn't know what exactly to put for Maxresults and Tag , so I just put a 5 and blank. Here's what i tried. I assume you have a better method:

B4X:
Sub GeocodeLocation(Location1 As Location)
    Log("GeocodeLocation: "&Location1.Latitude&", "&Location1.Longitude)
    '    here you can get the Location Latitude and Longitude properties and use the Geocoder library to perform a reverse geocode
    '    if the reverse geocode is successful you will have the country that the device is located in
Dim lc As Geocoder
lc.Initialize("lc")
lc.GetFromLocation(Location1.Latitude, Location1.Longitude,5,"")
Log(lc)
End Sub
 

warwound

Expert
Licensed User
Longtime User
The Geocoder library has never worked on an emulator, only on real devices.

I'd set MaxResults to just 1 and use Null as the Tag value as it is not used in this code.
 

trueboss323

Active Member
Licensed User
Longtime User
The Geocoder library has never worked on an emulator, only on real devices.

I'd set MaxResults to just 1 and use Null as the Tag value as it is not used in this code.

I did the changes as you requested.
Could you please give an example code how I could do a reverse geocode with the longitude and latitude provided?
 

Beja

Expert
Licensed User
Longtime User
GeoCoder is one of the greatest libraries ever written. I am using it for some time now, in more than an app, on my phone and a few friends' and it works like a charm.
I don't think Google will support it in one device and stop in another. Definitely the problem is somewhere else.
 

Shay

Well-Known Member
Licensed User
Longtime User
I am using android 4.1.2, and on my phone it stopped working
For me it is not working anymore
still waiting for solution here
(Again even the above code test, is not working anymore)
 

Beja

Expert
Licensed User
Longtime User
There should be some unidentified issue Shay..
This is what I got recently.
 

Attachments

  • geocoderjpg.jpg
    geocoderjpg.jpg
    83.3 KB · Views: 256
Top