Geocoding Tutorial – Getting physical address from IP address (using ippages)

Posted December 18th, 2007 by

Introduction

I’ve been interested in geocoding for a long time now, and I’ve been working on integrating geocoding into the ScreamingToaster platform. I’m writing a series of tutorials on geocoding that will help you integrate location based functionality into your projects with minimum effort. I plan to cover the following topics:

  1. GeoIP – getting geographic location information from an IP address
  2. Geocoding – turning an address into a longitude and latitude
  3. Reverse Geocoding – turning a longitude/latitude into an address.

This tutorial addresses the first item on this list. Given an IP address, this tutorial will show you how to get location information from it. You can then use this location information for many different things, like looking up weather there, or perhaps displaying a pushpin on google maps, etc. To learn more about geocoding and the Google Maps API, read this chapter in the Google Maps Hack book (on Safari Books Online).

Background information

Locations on earth can be specified by a combination of longitude, latitude, and elevation. You can read all about it here on wikipedia. The following code is enough to identify a geographic location:

   1: double latitude;
   2: double longitude;

This is the bare minimum information that you will need, but you will be able to get by and interface with many location based services just with this data. How do you get this long/lat data? If your app has access to a GPS device, then it can read the GPS coordinates from it (NMEA standard) – the GPS receiver sends lat/long information every few seconds via a serial port, USB, or Bluetooth connection to your laptop or mobile device, and you can then use that data. Alternatively, if you know the IP address where your desktop, mobile, or web based app is running, then you might be able to get geographic information out of it. There are issues with this and it’s not always reliable, and these issues are explained here.

Services available

There are a variety of different sources that maintain IP address to geographic location mapping. Here are some providers: MaxMind and ippages.com.

MaxMind GeoIP

MaxMind keeps a database of these address to IP mappings, and it updates them quite regularly. If you want the most accurate data, then you have to pay for it, and you can purchase a license for the data from MaxMind. You can also get semi-accurate data from them for free. They provide APIs to allow you to access this data in Java, and just about every other language. They provide a web service (not SOAP, but XML over HTTP) that you have to pay to use. You can get more information on it here. If you wanted to use the free City GeoIP database, then you could create your own web service and host it for free (with less accurate data).

ippages.com

Ippages takes a different route from MaxMind, and it provides a SOAP based web service that you can use to get to the IP address and location mapping data. Ippages provides 5000 lookups a day for free, and if you need a higher SLA (service level agreement) than that, then you can buy it from them.

Either one of these service providers might be a good choice for you depending on your requirements. If you need to embed this database, then MaxMind is great, since you don’t have to pay per transaction. If you want a hosted solution and simply pay as you go, then Ippages or MaxMind would work for you.

Source code

In this tutorial, I will use Ippages, since MaxMind has a very easy to use Java API, and it wouldn’t be much of a tutorial :) . Plus, I went with ippages, since I don’t like the idea of upgrading my GeoIP database every month. I’ve provided a ZIP file that contains all the source code, IDEA project files, and any libraries you would need to get this working.

WSDL to Java

The first thing that I did was take the WSDL from the ippages service, and feed it through Apache Axis 1.4 to get the Java classes to invoke the service and get it’s results – no need to parse XML and all that time consuming busy work… Don’t worry, you don’t have to use Axis to generate the classes, since I’ve included them in the ZIP file you can download.

Make the service call and process the location data

Invoking the Java class to get the location information for an IP address is very simple. Here’s the code:

   1: import Provider.GeoIP.*;
   2: import org.apache.commons.lang.builder.*;
   3:
   4: /**
   5:  * Lookup is a simple class that uses the ippages.com GeoIP lookup web service. Given an IP address, it
   6:  * returns a {@link IP_Address_Lookup_Properties} object, which contains all the geographic information
   7:  * available on the given IP address.
   8:  *
   9:  * @author Nazmul Idris
  10:  * @version 1.0
  11:  * @since Dec 18, 2007, 7:36:46 PM
  12:  */
  13: public class Lookup {
  14:
  15: /**
  16:  * Simple driver for this class. Takes an input from the command line, which is an IP address and
  17:  * tries to perform a lookup to get the location information associated with the IP address.
  18:  *
  19:  * @param args IP address that you want to get location information on
  20:  *
  21:  * @throws Exception if there are issues with service invocation, exceptions are thrown
  22:  */
  23: public static void main(String[] args) throws Exception {
  24:   String ipaddress = (args.length == 0)
  25:                      ? "64.41.145.134"
  26:                      : args[0];
  27:
  28:   IP_Address_Lookup_Properties locationInfo = lookupLocationForIPAddress(ipaddress);
  29:
  30:   String prettyPrint = ToStringBuilder.reflectionToString(locationInfo, ToStringStyle.MULTI_LINE_STYLE);
  31:
  32:   System.out.println(prettyPrint);
  33: }
  34:
  35: /**
  36:  * This is the actual method which calls the SOAP service on ippages.com. The classes used by this
  37:  * method are all generated from the WSDL provided by ippages.com, using Axis1.4.
  38:  *
  39:  * @param ipaddr IP address you want to get info on
  40:  *
  41:  * @return location information
  42:  */
  43: public static IP_Address_Lookup_Properties lookupLocationForIPAddress(String ipaddr) throws Exception {
  44:   Showmyip_lookupBindingStub binding;
  45:
  46:   binding = (Showmyip_lookupBindingStub)
  47:       new Showmyip_lookupLocator().getshowmyip_lookupPort();
  48:
  49:   // Time out after a minute
  50:   binding.setTimeout(60000);
  51:
  52:   // Perform Lookup
  53:   IP_Address_Lookup_Properties value = null;
  54:
  55:   value = binding.showmyip_lookup(ipaddr, "", "", "", "");
  56:
  57:   return value;
  58: }
  59:
  60: }//end class Lookup

You just have to call the Lookup.lookupLocationForIPAddress() method and pass it a String that contains the IP address (in the form of an IP_Address_Lookup_Properties object). This will return data that looks like this, for the IP address “64.41.145.134“:

If you look at the ZIP file, you will find that all the source code is under the src/ folder, and all the necessary libraries are in the lib folder. If you look through the source code, you will see that I’ve used a class called ToStringBuilder, to turn the IP_Address_Lookup_Properties object into a String without writing any code. The Apache Jakarta Commons libraries have some really wonderful libraries that you can leverage to make your life a lot easier. I plan on covering more of these useful libraries in future tutorials on developerlife.

The IP_Address_Lookup_Properties is a serializable bean that has all the address information that you might need. You can get longitude (locationInfo.getLONGITUDE()) and latitude (locationInfo.getLATITUDE()) from it as well as zip code (locationInfo.gePOSTAL_ZIP_CODE()), etc.

Next steps – tying it together with weather lookup

I provided source code in my weather.com tutorial to get weather data from weather.com’s web services using Java. It’s possible to tie them together very easily. If you have the code from both this tutorial and the weather.com one you will be able to do the following:

   1: // resolve an IP address to location data
   2: String ipaddress = "64.41.145.134";
   3: IP_Address_Lookup_Properties locationInfo = lookupLocationForIPAddress(ipaddress);
   4:
   5: // get the zip code from the location
   6: String zipcode = locationInfo.getPOSTAL_ZIP_CODE();
   7:
   8: // create a weather service stub
   9: WeatherConfigurationIF config = new DefaultWeatherConfigurationBean(
  10:     weatherServer, partnerID, licenseKey);
  11: WeatherGateway gateway = new WeatherGateway(config);
  12:
  13: // get the weather for this zip code
  14: WeatherReport weather = gateway.getFullForecast(zipcode, 3);
  15: System.out.println(weather);

When you execute the code above in your IDE or the command line, you can expect output like this:

Comments and feedback

If you want to comment on this article, please click here.


Comments are closed.