Geocoding with Android

If you are going to do anything practical with maps, you'll likely have to convert an address (or location) to a latitude/longitude pair. This concept in known as geocoding, and the android. location.Geocoder class provides this facility. In fact, the Geocoder class provides both forward and backward conversion—it can take an address and return a latitude/longitude pair, and it can translate a latitude/longitude pair into a list of addresses. The class provides the following methods:

• List<Address> getFromLocation(double latitude, double longitude, int maxResults)

• List<Address> getFromLocationName(String locationName, int maxResults, double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude, double upperRightLongitude)

• List<Address> getFromLocationName(String locationName, int maxResults)

It turns out that computing an address is not an exact science, due to the various ways a location can be described. For example, the getFromLocationName() methods can take the name of a place, the physical address, an airport code, or simply a well-known name for the location. Thus, the methods provide a list of addresses and not a single address. Because the methods return a list, you are encouraged to limit the result set by providing a value for maxResults that ranges between 1 and 5. Now let's see an example.

Listing 7-16 shows the XML layout and corresponding code for the user interface shown in Figure 7-9. To run the example, you'll need to update the listing with your own map-api key.

Listing 7-16. Working with the Android Geocoder Class

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent">

<LinearLayout android:layout_width="fill_parent" android:layout_alignParentBottom="true"

android:layout_height="wrap_content" android:orientation="vertical" >

<EditText android:layout_width="fill_parent" android:id="@+id/location" android:layout_height="wrap_content" android:text="White House"/>

<Button android:id="@+id/geocodeBtn" android:layout_width="wrap_content"

android:layout_height="wrap_content" android:text="Find Location"/> </LinearLayout>

<com.google.android.maps.MapView android:id="@+id/geoMap" android:clickable="true" android:layout_width="fill_parent" android:layout_height="320px"

android:apiKey="07vhL0usFXryRakmo2A4t8aKViWwKyGJGEDqpdg" />

</RelativeLayout>

import java.io.IOException; import java.util.List;

import android.location.Address;

import android.location.Geocoder;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; import com.google.android.maps.MapView;

public class GeocodingDemoActivity extends MapActivity {

Geocoder geocoder = null; MapView mapView = null; ^Override protected boolean isRouteDisplayed() { return false;

^Override protected void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.geocode); mapView = (MapView)findViewById(R.id.geoMap); // lat/long of Jacksonville, FL int lat = (int)(30.334954*1000000); int lng = (int)(-8l.5625*1000000); GeoPoint pt = new GeoPoint(lat,lng); mapView.getController().setZoom(l0); mapView.getController().setCenter(pt); mapView.getController().animateTo(pt); //

Button geoBtn =(Button)findViewById(R.id.geocodeBtn); geocoder = new Geocoder(this);

geoBtn.setOnClickListener(new OnClickListener(){ ^Override public void onClick(View arg0) { try {

EditText loc = (EditText)findViewById(R.id.location); String locationName = loc.getText().toString();

List<Address> addressList = geocoder.getFromLocationName(locationName, 5);

if(addressList!=null && addressList.size()>0) {

int lat = (int)addressList.get(0).getLatitude()*1000000; int lng = (int)addressList.get(0).getLongitude()*1000000;

GeoPoint pt = new GeoPoint(lat,lng); mapView.getController().setZoom(10); mapView.getController().setCenter(pt); mapView.getController().animateTo(pt);

} catch (IOException e) { e.printStackTrace();

Android Geocoder
Figure 7-9. Geocoding to a point given the location name

To demonstrate the uses of geocoding in Android, type the name of the location, or its address, in the EditText field and then click the Find Location button. In order to find the address of a location, call the getFromLocationName() method of Geocoder. The location can be an address or a well-known name such as "White House." Geocoding can be a timely operation, so we recommend that you limit the results to five, as the Android documentation suggests. The call to getFromLocationName() returns a list of addresses. The sample application takes the list of addresses and processes the first one if any were found. Every address has a latitude and longitude, which you use to create a GeoPoint. You then get the map controller and navigate to the point. Note that before you call animateTo(), you set the zoom level to 10 and center the map to the same point. The zoom level can be set to an integer between 1 and 21, inclusive. As you move from 1 toward 21, the zoom level increases by a factor of 2.

You should understand a few points with respect to geocoding. First, a returned address is not always an exact address. Obviously, because the returned list of addresses depends on the accuracy of the input, you need to make every effort to provide an accurate location name to the Geocoder. Second, whenever possible, set the maxResults parameter to a value between 1 and 5. Lastly, you should seriously consider doing the geocoding operation in a different thread from the UI thread. There are two reasons for this. The first is obvious: the operation is time-consuming and you don't want the UI to hang while you do the geocoding. The second reason is that with a mobile device, you always need to assume that the network connection can be lost and that the connection is weak. Therefore, you need to handle input/output (I/O) exceptions and timeouts appropriately. Once you have computed the addresses, you can then post the results to the UI thread. Let's investigate this a bit more.

0 0

Post a comment