Monday, 5 August 2013

Textual description of firstImageUrl

Java program to convert location in Latitude Longitude

Converting an address in to latitude and longitude (and vice versa ) is very easy using Google's GeoCoding API. GeoCoding is the process to convert a simple address line like "Apollo Bunder,Mumbai ,Maharashtra, India" to latitude,longitude like "18.92038860,72.83013059999999". Converting latitude,longitude to address is called Reverse GeoCoding.

You can get the output from geocoding api either in json or in xml format .

Here is the sample java program to Convert addresses in to latitude and longitude . I have used Jackson API to convert json response in java Objects , and apache commons IO to make Http calls to geocoding api . Download the jars from here , here , and here .

Input address can be in "address ,city ,state ,country ,zip code" form .
package com.javaroots.latlong;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.codehaus.jackson.map.ObjectMapper;

/**
 * 
 * 
 * @author Abhishek Somani
 * 
 */
public class AddressConverter {
 /*
  * Geocode request URL. Here see we are passing "json" it means we will get
  * the output in JSON format. You can also pass "xml" instead of "json" for
  * XML output. For XML output URL will be
  * "http://maps.googleapis.com/maps/api/geocode/xml";
  */

 private static final String URL = "http://maps.googleapis.com/maps/api/geocode/json";

 /*
  * Here the fullAddress String is in format like
  * "address,city,state,zipcode". Here address means "street number + route"
  * .
  */
 public GoogleResponse convertToLatLong(String fullAddress) throws IOException {

  /*
   * Create an java.net.URL object by passing the request URL in
   * constructor. Here you can see I am converting the fullAddress String
   * in UTF-8 format. You will get Exception if you don't convert your
   * address in UTF-8 format. Perhaps google loves UTF-8 format. :) In
   * parameter we also need to pass "sensor" parameter. sensor (required
   * parameter) — Indicates whether or not the geocoding request comes
   * from a device with a location sensor. This value must be either true
   * or false.
   */
  URL url = new URL(URL + "?address="
    + URLEncoder.encode(fullAddress, "UTF-8") + "&sensor=false");
  // Open the Connection
  URLConnection conn = url.openConnection();

  InputStream in = conn.getInputStream() ;
  ObjectMapper mapper = new ObjectMapper();
  GoogleResponse response = (GoogleResponse)mapper.readValue(in,GoogleResponse.class);
  in.close();
  return response;
  

 }
 
 public GoogleResponse convertFromLatLong(String latlongString) throws IOException {

  /*
   * Create an java.net.URL object by passing the request URL in
   * constructor. Here you can see I am converting the fullAddress String
   * in UTF-8 format. You will get Exception if you don't convert your
   * address in UTF-8 format. Perhaps google loves UTF-8 format. :) In
   * parameter we also need to pass "sensor" parameter. sensor (required
   * parameter) — Indicates whether or not the geocoding request comes
   * from a device with a location sensor. This value must be either true
   * or false.
   */
  URL url = new URL(URL + "?latlng="
    + URLEncoder.encode(latlongString, "UTF-8") + "&sensor=false");
  // Open the Connection
  URLConnection conn = url.openConnection();

  InputStream in = conn.getInputStream() ;
  ObjectMapper mapper = new ObjectMapper();
  GoogleResponse response = (GoogleResponse)mapper.readValue(in,GoogleResponse.class);
  in.close();
  return response;
  

 }

 
 public static void main(String[] args) throws IOException {
  
  GoogleResponse res = new AddressConverter().convertToLatLong("Apollo Bunder,Mumbai ,Maharashtra, India");
  if(res.getStatus().equals("OK"))
  {
   for(Result result : res.getResults())
   {
    System.out.println("Lattitude of address is :"  +result.getGeometry().getLocation().getLat());
    System.out.println("Longitude of address is :" + result.getGeometry().getLocation().getLng());
    System.out.println("Location is " + result.getGeometry().getLocation_type());
   }
  }
  else
  {
   System.out.println(res.getStatus());
  }
  
  System.out.println("\n");
  GoogleResponse res1 = new AddressConverter().convertFromLatLong("18.92038860,72.83013059999999");
  if(res1.getStatus().equals("OK"))
  {
   for(Result result : res1.getResults())
   {
    System.out.println("address is :"  +result.getFormatted_address());
   }
  }
  else
  {
   System.out.println(res1.getStatus());
  }
  
  
  
  
  
 }
 

}
Here are the java classes to convert json response in java objects . I have ignored some fields for simplicity . GoogleResponse in the root class which will contain the Result array and status .
package com.javaroots.latlong;
/**
 * 
 * 
 * @author Abhishek Somani
 * 
 */
public class GoogleResponse {
 
 
 private Result[] results ;
 private String status ;
 public Result[] getResults() {
  return results;
 }
 public void setResults(Result[] results) {
  this.results = results;
 }
 public String getStatus() {
  return status;
 }
 public void setStatus(String status) {
  this.status = status;
 }
 
 

}


Geometry class will have location and other details .
package com.javaroots.latlong;

import org.codehaus.jackson.annotate.JsonIgnore;

/**
 * 
 * 
 * @author Abhishek Somani
 * 
 */
public class Geometry {

 private Location location ;
 
 private String location_type;
 
 @JsonIgnore
 private Object bounds;
 
 @JsonIgnore
 
 private Object viewport;

 public Location getLocation() {
  return location;
 }

 public void setLocation(Location location) {
  this.location = location;
 }

 public String getLocation_type() {
  return location_type;
 }

 public void setLocation_type(String location_type) {
  this.location_type = location_type;
 }

 public Object getBounds() {
  return bounds;
 }

 public void setBounds(Object bounds) {
  this.bounds = bounds;
 }

 public Object getViewport() {
  return viewport;
 }

 public void setViewport(Object viewport) {
  this.viewport = viewport;
 }
 
 
 
 
}


Location class will have latitude and longitude .
package com.javaroots.latlong;
/**
 * 
 * 
 * @author Abhishek Somani
 * 
 */
public class Location {
 
 private String lat;
 
 private String lng;

 public String getLat() {
  return lat;
 }

 public void setLat(String lat) {
  this.lat = lat;
 }

 public String getLng() {
  return lng;
 }

 public void setLng(String lng) {
  this.lng = lng;
 }
 
 

}


Result class will have location , geometry , formatted address and boolean value whether it is partial match or not. Ignored some fields in this class also.

package com.javaroots.latlong;

import org.codehaus.jackson.annotate.JsonIgnore;

/**
 * 
 * 
 * @author Abhishek Somani
 * 
 */
public class Result {
 
 private String formatted_address;
 
 private boolean partial_match;
 
 private Geometry geometry;
 
 @JsonIgnore
 private Object address_components;
 
 @JsonIgnore
 private Object types;

 public String getFormatted_address() {
  return formatted_address;
 }

 public void setFormatted_address(String formatted_address) {
  this.formatted_address = formatted_address;
 }

 public boolean isPartial_match() {
  return partial_match;
 }

 public void setPartial_match(boolean partial_match) {
  this.partial_match = partial_match;
 }

 public Geometry getGeometry() {
  return geometry;
 }

 public void setGeometry(Geometry geometry) {
  this.geometry = geometry;
 }

 public Object getAddress_components() {
  return address_components;
 }

 public void setAddress_components(Object address_components) {
  this.address_components = address_components;
 }

 public Object getTypes() {
  return types;
 }

 public void setTypes(Object types) {
  this.types = types;
 }
 
 
 
}

Here is the example output of the program :
GeoCoding Example :
Lattitude of address is :18.92038860
Longitude of address is :72.83013059999999
Location is APPROXIMATE

Reverse GeoCoding Example
address is :Shahid Bhagat Singh Marg, Apollo Bandar, Colaba, Mumbai, Maharashtra 400001, India
address is :Colaba Depot, Shahid Bhagat Singh Marg, Apollo Bandar, Colaba, Mumbai, Maharashtra 400001, India
address is :Cusrow Baug Colony, Colaba, Mumbai, Maharashtra 400001, India
address is :Apollo Bandar, Colaba, Mumbai, Maharashtra, India
address is :400001, India
address is :Colaba, Mumbai, Maharashtra, India
address is :Mumbai, Maharashtra, India
address is :Mumbai, Maharashtra, India
address is :Maharashtra, India
address is :India

if you do not encode the url params in UTF-8 , you may get error like this :
Exception in thread "main" java.io.IOException: Server returned HTTP response code: 400 for URL: http://maps.googleapis.com/maps/api/geocode/json?address=Apollo Bunder,Mumbai ,Maharashtra, India ,400001&sensor=false
 at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
 at com.javaroots.latlong.AddressConverter.getJSONByGoogle(AddressConverter.java:58)
 at com.javaroots.latlong.AddressConverter.main(AddressConverter.java:72)

Post Comments and Suggestions !!

Update :

There are two limiting factors in using this api (Thanks to ralph for pointing out this ) .First , Google is limiting the number of requests to the Geocoding API to 2,500 requests per day and second ,Geocoding results without displaying them on a map is prohibited .

You can have a look at GeoNames which does not have these restrictions .

Reference