Tuesday, September 8, 2015

GeoCoding API - Google Integration


GeoCoding API - Google Integration




1.) Google provides lot of API's, with GeoCoding one of them.

Complete documentation can be read from here

You need a key to access the API's. GeoCoding Api is available for both Developers(Free version) and Commercial purpose (License version).

For Free version, go to Google Developers Console

Create a project by choosing GeoCoding API, and generate the key.

 Integration through HttpClient with Google Maps dependency

Piece of Code to start with

URIBuilder url = new URIBuilder(
                    "https://maps.googleapis.com/maps/api/geocode/json?")
                    .addParameter("components", "country:IN")
                    .addParameter("address", searchText)
                    .addParameter("key", apiKey);


where components  is for filtering, is available in the documentation.
           searchText is what user wants to search
           Key is what you have generated, has to be a part of url.
           Json is specified for the output form, can be XML also


RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectionTimeout).build();
            HttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
           
            HttpGet httpRequest;
            httpRequest = new HttpGet(url.build());

            HttpResponse response = client.execute(httpRequest);
            HttpEntity responseEntity = response.getEntity();

String responseText = EntityUtils.toString(responseEntity);

Output responseTextis in the form of json, you can now filter out the results.


Using Google Maps Dependency

Add below in your Pom.xml


       <dependency>

              <groupId>com.google.maps</groupId>
              <artifactId>google-maps-services</artifactId>
              <version>0.1.7</version>
       </dependency> 


AreaZipcodeCityState.java


package com.project;

public class    {
    private Long zipCode;
    private String areaName;
    private String cityName;
    private String stateName;
    public Long getZipCode() {
        return zipCode;
    }
    public void setZipCode(Long zipCode) {
        this.zipCode = zipCode;
    }
    public String getAreaName() {
        return areaName;
    }
    public void setAreaName(String areaName) {
        this.areaName = areaName;
    }
    public String getCityName() {
        return cityName;
    }
    public void setCityName(String cityName) {
        this.cityName = cityName;
    }
    public String getStateName() {
        return stateName;
    }
    public void setStateName(String stateName) {
        this.stateName = stateName;
    }
    public AreaZipcodeCityState(Long zipCode, String areaName, String cityName, String stateName) {
        this.zipCode = zipCode;
        this.areaName = areaName;
        this.cityName = cityName;
        this.stateName = stateName;
    }
    public AreaZipcodeCityState() {
    }
   
}
 



GoogleIntegration.java

package com.project;


import java.util.ArrayList;
import java.util.List;
import com.google.maps.GeoApiContext;
import com.google.maps.GeocodingApi;
import com.google.maps.GeocodingApi.ComponentFilter;
import com.google.maps.GeocodingApiRequest;
import com.google.maps.model.AddressComponent;
import com.google.maps.model.GeocodingResult;
import com.google.maps.model.LatLng;

public class GoogleIntegration {
    private static String API_KEY="";
    private static String COUNTRY_FILTER="IN";
    private static Long DEFAULT_ZIPCODE=Long.valueOf(0);
    private static String DEFAULT_CITY="";
    private static String DEFAULT_AREA="";
    private static String DEFAULT_STATE="";
   
    private static String city = "administrative_area_level_2";
    private static String state = "administrative_area_level_1";
    private static String locality = "locality";
    private static String zipCode = "postal_code";
    private static String neighborhood = "neighborhood";
    private static String premise = "premise";
    private static String sublocality = "sublocality";
    private static String sublocality_level_4 = "sublocality_level_4";
    private static String sublocality_level_3 = "sublocality_level_3";
    private static String sublocality_level_2 = "sublocality_level_2";
    private static String sublocality_level_1 = "sublocality_level_1";
    private static String street_address = "street_address";
    public static List<AreaZipcodeCityState> getGoogleResult(String inputAddress) {
        String address = inputAddress.toLowerCase();
        GeoApiContext context = new GeoApiContext().setApiKey(API_KEY);
        GeocodingApiRequest request = GeocodingApi.newRequest(context);
        request.components(ComponentFilter.country(COUNTRY_FILTER));
        // request.resultType(AddressType.LOCALITY);
        // request.resultType(AddressType.PREMISE);
        request.address(address);

        try {
            ArrayList<AreaZipcodeCityState> resultList = new ArrayList<AreaZipcodeCityState>();
            GeocodingResult[] results = request.await();
            // AddressComponentType type=enum ADMINISTRATIVE_AREA_LEVEL_1;
            for (GeocodingResult result : results) {
                    AreaZipcodeCityState areaZipcodeCityState = new AreaZipcodeCityState(DEFAULT_ZIPCODE,DEFAULT_AREA,DEFAULT_CITY,DEFAULT_STATE);
                    Long zipCode=getZipcodeFromLatLon(context, result.geometry.location);
                    if(zipCode!=null)
                            areaZipcodeCityState.setZipCode(zipCode);
                    for (AddressComponent addressComponent : result.addressComponents) {
                       
                        if (addressComponent.types[0].name().equalsIgnoreCase(city)) {
                            areaZipcodeCityState.setCityName(addressComponent.longName);
                       
                        } else if (addressComponent.types[0].name().equalsIgnoreCase(state)) {
                            areaZipcodeCityState.setStateName(addressComponent.longName);
                       
                        } else if (
                                (addressComponent.types[0].name().equalsIgnoreCase(locality) && addressComponent.longName
                                .toLowerCase().contains(address))
                                || (addressComponent.types[0].name().equalsIgnoreCase(neighborhood)
                                && addressComponent.longName.toLowerCase().contains(address))
                                ||(addressComponent.types[0].name().equalsIgnoreCase(premise)
                                && addressComponent.longName.toLowerCase().contains(address))
                                || (addressComponent.types[0].name().equalsIgnoreCase(sublocality)
                                && addressComponent.longName.toLowerCase().contains(address))
                                || (addressComponent.types[0].name().equalsIgnoreCase(sublocality_level_4)
                                && addressComponent.longName.toLowerCase().contains(address))
                                || (addressComponent.types[0].name().equalsIgnoreCase(sublocality_level_3)
                                && addressComponent.longName.toLowerCase().contains(address))
                                || (addressComponent.types[0].name().equalsIgnoreCase(sublocality_level_2)
                                && addressComponent.longName.toLowerCase().contains(address))
                                || (addressComponent.types[0].name().equalsIgnoreCase(sublocality_level_1)
                                && addressComponent.longName.toLowerCase().contains(address))
                                || (addressComponent.types[0].name().equalsIgnoreCase(street_address)
                                && addressComponent.longName.toLowerCase().contains(address))
                                ) {
                            areaZipcodeCityState.setAreaName(addressComponent.longName);
                        }
                    }
                    resultList.add(areaZipcodeCityState);
            }
            return resultList;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
       
    }

    public static Long getZipcodeFromLatLon(GeoApiContext context, LatLng latLon) {
        GeocodingApiRequest request = GeocodingApi.reverseGeocode(context, latLon);
        try {
            GeocodingResult[] results = request.await();
            for (GeocodingResult reverseGeocodingResult : results) {
                for (AddressComponent addressComponent : reverseGeocodingResult.addressComponents) {
                    if (addressComponent.types[0].name().equalsIgnoreCase(zipCode)) {
                        return Long.valueOf(addressComponent.longName);
                    }
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;

    }

   
}



Concept of reverse GeoCoding

If the search results returned does not contain the zipcodes, then we can make use of Reverse GeoCoding, using lat/long's.

public static Long getZipcodeFromLatLon(GeoApiContext context, LatLng latLon) {
        GeocodingApiRequest request = GeocodingApi.reverseGeocode(context, latLon);
        try {
            GeocodingResult[] results = request.await();
            for (GeocodingResult reverseGeocodingResult : results) {
                for (AddressComponent addressComponent : reverseGeocodingResult.addressComponents) {
                    if (addressComponent.types[0].name().equalsIgnoreCase(zipCode)) {
                        return Long.valueOf(addressComponent.longName);
                    }
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;

    }