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:
- GeoIP – getting geographic location information from an IP address
- Geocoding – turning an address into a longitude and latitude
- 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).
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:
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.
There are a variety of different sources that maintain IP address to geographic location mapping. Here are some providers: MaxMind and ippages.com.
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 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.
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:
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 “220.127.116.11“:
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 weather.com 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:
When you execute the code above in your IDE or the command line, you can expect output like this: