Preface:

One of readers asked me to write about getting the names of the location that I touch on the map if it is possible to get names from coordinates. That query triggered me to write this article. The answer is yes we can get location names if we have coordinates, the process is called Geocoding.

Geocoding is the process in which we translate latitude and longitude sets to text based address or string location names. Like if we have the coordinates 33695043,73050000 and we want to know which location is it. We will use geocoding and will find out that its Islamabad, the capital of Pakistan. Same is the case with Reverse Geocoding, if we have the name Islamabad, we can Reverse Geocode it to fine the coordinates. To continue with this article I have used the code from my last tutorial i.e, https://mirnauman.wordpress.com/2012/04/26/android-google-maps-tutorial-part-7-drawing-a-path-or-line-between-two-locations/ but u guys don’t need to use the code from that tutorial. You can use ur current google maps app and just insert the OnTouchEvent method the YourOverlay Class that extends Overlay Class

A lil boring theory:

We will use the Geocoder Class. This class is used for Geocoding and Reverse Geocoding. Now in Reverse Geocoding things can be a lil tricky coz the returned latitude, longitude values depend on the string address details that a user has provided. It may be just a city name, a city name with a street name or a city name with street name and name of a building or specific location. The Geocoder class requires a backend service that is not included in the core android framework. The Geocoder query methods will return an empty list if there no backend service in the platform. The major public methods of this class are getFromLocation() and getFromLocationName(). The earlier one will transform lat,long values to string location names and the later one will get the coordinates from string location names. both the methods will return an array of address i.e, List< Addresses >.

Enough theory, now some real stuff

Add the following code to the class that extends Overlay Class


@Override
 public boolean onTouchEvent(MotionEvent event, MapView mapView)
 {
 //---when user lifts his finger---
 if (event.getAction() == 1) {
 GeoPoint p = mapView.getProjection().fromPixels(
 (int) event.getX(),
 (int) event.getY());

 Toast.makeText(getBaseContext(),
 p.getLatitudeE6() / 1E6 + "," +
 p.getLongitudeE6() /1E6 ,
 Toast.LENGTH_SHORT).show();

 Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
 try {
 List<Address> addresses = geoCoder.getFromLocation(p.getLatitudeE6() / 1E6, p.getLongitudeE6() / 1E6, 1);

 String strCompleteAddress= "";
 if (addresses.size() > 0)
 {
 for (int i=0; i<addresses.get(0).getMaxAddressLineIndex();i++)
strCompleteAddress+= addresses.get(0).getAddressLine(i) + "\n";
 }
 Log.i("MyLocTAG => ", strCompleteAddress);
 Toast.makeText(getBaseContext(), strCompleteAddress, Toast.LENGTH_LONG).show();
 }
 catch (IOException e) {
 Log.i("MyLocTAG => ", "this is the exception part");
 e.printStackTrace();
 }
 return true;
 }
 else
 return false;
 }

The first Toast will show only the latitude and longitude in number for the location that is touched. Then we created an object of the Geocoder class.


Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());

Than we called the getFromLocation method, provided it with the latitude and longitude values and the number of search results that will be returned.


List<Address> addresses = geoCoder.getFromLocation(p.getLatitudeE6()  / 1E6,  p.getLongitudeE6() / 1E6, 1);

After this we concatenate each value in the Addresses array list to get a single string with the complete location address.


for (int i=0; i<addresses.get(0).getMaxAddressLineIndex();i++)
 strCompleteAddress += addresses.get(0).getAddressLine(i) + "\n";

The last part displays a Toast that will show the string location name.


Toast.makeText(getBaseContext(), strCompleteAddress, Toast.LENGTH_LONG).show();

Geocoding snapshot showing the complete string location name that is touched on the map

Same is the case with Reverse Geocoding, if we have the string location name we can get the coordinates to that location by using Reverse Geocoding. The sample code for Reverse Geocoding is attached below.


Geocoder geoCoder = new Geocoder(this, Locale.getDefault());
 try {
 List<Address> addresses = geoCoder.getFromLocationName("Bhattai Rd Islamabad", 5);
 String strCompleteAddress = "";
 if (addresses.size() > 0) {
 p = new GeoPoint(
 (int) (addresses.get(0).getLatitude() * 1E6),
 (int) (addresses.get(0).getLongitude() * 1E6));
 mc.animateTo(p);
 mapView.invalidate();
 }
 } catch (IOException e) {
 e.printStackTrace();
 }