Byron Kiourtzoglou

About Byron Kiourtzoglou

Byron is a master software engineer working in the IT and Telecom domains. He is always fascinated by SOA, middleware services and mobile development. Byron is co-founder and Executive Editor at Java Code Geeks.

Reverse Geocoding with Yahoo API

A very popular group of services in smartphones are the Location Based Services. Geocoding is the process that finds the geographic coordinates ,in latitude and longitude, from other geographical data, like street addresses or postal codes.

In this tutorial we are going to talk about reverse Geocoding. That is the process that uses the user’s coordinates and finds out street addresses an nearby points of interest. For this tutorial we are going to Use Yahoo! PlacaFinder which in an excellent API for reverse Geocoding. To fully use the API, you are going to need a kay. But for this tutorial this won’t be necessary.

In short, in order to do reverse Geocoding you will :

  • Bundle a button with an OnClickListener, that invokes performReverseGeocodingInBackground method, which retrieves the current location.
  • Perform the data retrieval using the information from the Location object, using a class that extend AsyncTasks, to enable easy use of the UI thread because Internet communication activities are time consuming
  • Construct a GeoCoder class that makes use of the Yahoo API
  • Use an HttpRetriever and an XmlParser get the data from Yahoo and parse it.
  • Format the query string concatenating the user’s coordinates to the Yahoo API base url
  • Then use a DefaultHTPClient to perform the HTTP request/response.
package com.javacodegeeks.android.lbs;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.javacodegeeks.android.lbs.model.GeoCodeResult;
import com.javacodegeeks.android.lbs.services.GeoCoder;

public class LbsGeocodingActivity extends Activity {

    private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 1; // in Meters
    private static final long MINIMUM_TIME_BETWEEN_UPDATES = 1000; // in Milliseconds

    private GeoCoder geoCoder = new GeoCoder();

    protected LocationManager locationManager;
    protected Location currentLocation;

    protected Button retrieveLocationButton;
    protected Button reverseGeocodingButton;

    @Override
    public void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  setContentView(R.layout.main);

  retrieveLocationButton = (Button) findViewById(R.id.retrieve_location_button);

  reverseGeocodingButton = (Button) findViewById(R.id.reverse_geocoding_button);

  locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

  locationManager.requestLocationUpdates(

    LocationManager.GPS_PROVIDER, 

    MINIMUM_TIME_BETWEEN_UPDATES, 

    MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,

    new MyLocationListener()

  );

  retrieveLocationButton.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

    showCurrentLocation();

}

  });

  reverseGeocodingButton.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

    performReverseGeocodingInBackground();

}

  });

    }    

    protected void performReverseGeocodingInBackground() {

  showCurrentLocation();

  new ReverseGeocodeLookupTask().execute((Void[])null);
    }

    protected void showCurrentLocation() {

  currentLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

  if (currentLocation != null) {

String message = String.format(

  "Current Location n Longitude: %1$s n Latitude: %2$s",

  currentLocation.getLongitude(), currentLocation.getLatitude()

);

Toast.makeText(LbsGeocodingActivity.this, message,

  Toast.LENGTH_LONG).show();

  }

    }   

    private class MyLocationListener implements LocationListener {

  public void onLocationChanged(Location location) {

String message = String.format(

  "New Location n Longitude: %1$s n Latitude: %2$s",

  location.getLongitude(), location.getLatitude()

);

Toast.makeText(LbsGeocodingActivity.this, message, Toast.LENGTH_LONG).show();

  }

  public void onStatusChanged(String s, int i, Bundle b) {

Toast.makeText(LbsGeocodingActivity.this, "Provider status changed",

  Toast.LENGTH_LONG).show();

  }

  public void onProviderDisabled(String s) {

Toast.makeText(LbsGeocodingActivity.this,

  "Provider disabled by the user. GPS turned off",

  Toast.LENGTH_LONG).show();

  }

  public void onProviderEnabled(String s) {

Toast.makeText(LbsGeocodingActivity.this,

  "Provider enabled by the user. GPS turned on",

  Toast.LENGTH_LONG).show();

  }

    }

    public class ReverseGeocodeLookupTask extends AsyncTask <Void, Void, GeoCodeResult> {

  private ProgressDialog progressDialog;

  @Override

  protected void onPreExecute() {

this.progressDialog = ProgressDialog.show(

  LbsGeocodingActivity.this,

  "Please wait...contacting Yahoo!", // title

  "Requesting reverse geocode lookup", // message

  true // indeterminate

);

  }

  @Override

  protected GeoCodeResult doInBackground(Void... params) {

return geoCoder.reverseGeoCode(currentLocation.getLatitude(), currentLocation.getLongitude());

  }

  @Override

  protected void onPostExecute(GeoCodeResult result) {

this.progressDialog.cancel();

Toast.makeText(LbsGeocodingActivity.this, result.toString(), Toast.LENGTH_LONG).show();

  }

    }

}
package com.javacodegeeks.android.lbs.services;

import com.javacodegeeks.android.lbs.model.GeoCodeResult;

public class GeoCoder {

    private static final String YAHOO_API_BASE_URL = "http://where.yahooapis.com/geocode?q=%1$s,+%2$s&gflags=R&appid=[yourappidhere]";

    private HttpRetriever httpRetriever = new HttpRetriever();
    private XmlParser xmlParser = new XmlParser();

    public GeoCodeResult reverseGeoCode(double latitude, double longitude) {

  String url = String.format(YAHOO_API_BASE_URL, String.valueOf(latitude), String.valueOf(longitude));

  String response = httpRetriever.retrieve(url);

  return xmlParser.parseXmlResponse(response);

    }

}
package com.javacodegeeks.android.lbs.services;

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.util.Log;

public class HttpRetriever {

    private final String TAG = getClass().getSimpleName();

    private DefaultHttpClient client = new DefaultHttpClient();

    public String retrieve(String url) {

  HttpGet get = new HttpGet(url);

  try {

HttpResponse getResponse = client.execute(get);

HttpEntity getResponseEntity = getResponse.getEntity();

if (getResponseEntity != null) {

    String response = EntityUtils.toString(getResponseEntity);

    Log.d(TAG, response);

    return response;

}

  } catch (IOException e) {

e.printStackTrace();

  }

  return null;

    }

}
package com.javacodegeeks.android.lbs.services;

import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import android.util.Log;

import com.javacodegeeks.android.lbs.model.GeoCodeResult;

public class XmlParser {

    private final String TAG = getClass().getSimpleName();

    public GeoCodeResult parseXmlResponse(String response) {

  try {

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

DocumentBuilder db = dbf.newDocumentBuilder();

Document doc = db.parse(new InputSource(new StringReader(response)));

NodeList resultNodes = doc.getElementsByTagName("Result");

Node resultNode = resultNodes.item(0);

NodeList attrsList = resultNode.getChildNodes();

GeoCodeResult result = new GeoCodeResult();

for (int i=0; i < attrsList.getLength(); i++) {

    Node node = attrsList.item(i);

    Node firstChild = node.getFirstChild();

    if ("line1".equalsIgnoreCase(node.getNodeName()) && firstChild!=null) {

  result.line1 = firstChild.getNodeValue();

    }

    if ("line2".equalsIgnoreCase(node.getNodeName()) && firstChild!=null) {

  result.line2 = firstChild.getNodeValue();

    }

    if ("line3".equalsIgnoreCase(node.getNodeName()) && firstChild!=null) {

  result.line3 = firstChild.getNodeValue();

    }

    if ("line4".equalsIgnoreCase(node.getNodeName()) && firstChild!=null) {

  result.line4 = firstChild.getNodeValue();

    }

}

Log.d(TAG, result.toString());

return result;

  }

  catch (Exception e) {

e.printStackTrace();

  }

  return null;

    }

}
package com.javacodegeeks.android.lbs.model;

public class GeoCodeResult {

    public String line1;
    public String line2;
    public String line3;
    public String line4;

    @Override
    public String toString() {

  StringBuilder builder = new StringBuilder();

  builder.append("Location:");

  if (line1!=null)

builder.append("-"+line1);

  if (line2!=null)

builder.append("-"+line2);

  if (line3!=null)

builder.append("-"+line3);

  if (line4!=null)

builder.append("-"+line4);

  return builder.toString();

    }

}

 
This was an example on how to perform Reverse Geocoding with Yahoo API.

Related Article:

Related Whitepaper:

Beginning Android Application Development (Free Sample Chapter)

Create must-have applications for the latest Android OS!

The Android OS is a popular and flexible platform for many of today's most in-demand mobile devices. This full-color guide offers you a hands-on introduction to creating Android applications for the latest mobile devices. Veteran author Wei Meng Lee accompanies each lesson with real-world examples to drive home the content he covers. Beginning with an overview of core Android features and tools, he moves at a steady pace while teaching everything you need to know to successfully develop your own Android applications.

Get it Now!  

Examples Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Examples Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books
Get tutored by the Geeks! JCG Academy is a fact... Join Now
Hello. Add your message here.