Retrieving geographic coordinates for an address by using geocoding

Your application can use the Geocoder class to retrieve the geographic coordinates for an address. For example, your app can prompt the user for an address and then display the address on a map. The address can be in the form of an unstructured string, or a MapLocation object. Geocoding requests can be synchronous or asynchronous.

Specifying an address

The more details that you provide for an address, the more accurate the results can be. For example, if you provide only a street address, the Geocoding server might return a large number of results. However, if you provide sufficient geographic context with your request, you can get away with providing less information about the address. The unstructured address string doesn't always provide the same results as a structured address.
// Structured address

MapLocation address1 = new MapLocation();
address1.addData(MapLocation.LBS_LOCATION_CITY_KEY, "waterloo");
address1.addData(MapLocation.LBS_LOCATION_COUNTRY_KEY, "canada");
address1.addData(MapLocation.LBS_LOCATION_STREET_ADDRESS_KEY, "419 phillip st");
address1.addData(MapLocation.LBS_LOCATION_POSTAL_CODE_KEY, "N2L3X2");

// Unstructured address
 
String address2 = new String("419 phillip st, waterloo, canada, N2L3X2");

Providing geographic context with the address

To help the geocoding server return the most relevant results, provide geographic context with your geocoding request. To provide context, you can create a MapDimensions object that contains geographic coordinates (for example, the BlackBerry device user's current location). By providing context, your application can receive relevant geographic coordinates even if a user provides only an address. If you don't provide a MapDimensions object, your application might use the last location saved in BlackBerry Maps as context, which might not provide the results that you want.

As a best practice, you should provide context from your application. If your application doesn't provide sufficient context with a request, your application might receive irrelevant search results. When you create a MapDimensions object to use with geocoding requests, the values for the width, height, zoom, and rotation are not important.
MapPoint origin = new MapPoint(43.4815, -80.5407);

MapDimensions context = new MapDimensions(origin, 480, 360, 5, 0);

Sending an asynchronous geocoding request

When you send an asynchronous geocoding request, you must pass in a reference to the class that implements the ServerExchangeCallback interface (represented by the callback variable in the following code sample). You must also provide the address, geographic context for the request (for example, the user's current location), and the length of time before the request times out. When you invoke Geocoder.geocode(), the application sends the request to the geocoding server and calls the appropriate ServerExchangeCallback method when it has a result.
MyServerExchangeCallback callback = new MyServerExchangeCallback();

try
{
    Geocoder.getInstance().geocode(callback, address1, context, 0);
} 
catch (GeocodeException e)
{
    // Do something with the exception
}

To create a class that implements the ServerExchangeCallback interface, there are three methods that you must include in your application: requestSuccess(), requestFailure(), and requestHalted(). When a geocoding request is completed, your application invokes one of these methods depending on the result of the request.

A successful geocoding request returns a GeocodeExchange object which contains a Vector of search results that you can access by invoking GeocodeExchange.getResults(). Each index in the Vector contains a net.rim.device.api.lbs.maps.model.MapLocation object that has details about a location, such as a display name, a description, the coordinates, and the address. If you receive multiple results, the most relevant result is located in the first index of the Vector.
public class MyServerExchangeCallback implements ServerExchangeCallback
{
    public void requestSuccess(ServerExchange exchange)
    {
        if(exchange instanceof GeocodeExchange)
        {
            GeocodeExchange geocodeExchange = (GeocodeExchange)exchange;
            Vector results = geocodeExchange.getResults();

            // Do something with the results
        }
    }

    public void requestFailure(ServerExchange exchange)
    {
        // Inform the user of the failure
    }

    public void requestHalted()
    {
        // Invoked when the request is stopped
    }
}

Sending a synchronous reverse geocoding request

For synchronous geocoding requests, your application is not required to implement the ServerExchangeCallback interface. To initiate a synchronous geocoding request, you must specify null instead of passing in a reference to a class that implements ServerExchangeCallback. When you run a synchronous geocoding request, you must verify the result of the request manually. Typically, you should run synchronous geocoding requests on a thread other than the UI thread; otherwise users won't be able to interact with the UI during the request.
GeocodeExchange exchange = Geocoder.getInstance().geocode
        (null, address2, context, 0);
                    
// Check if the request was successful
if(exchange.getExceptionList().size() == 0)
{
    // Do something with the result of the request
}
else
{
    // Inform the user of the failure
}

Was this information helpful? Send us your comments.