If you provide a restaurant guide it would be great to show the next restaurant based on webpage visitors position or the local beer garden specials if its sunny weather? Or offer geo targeted ads on your page? And this could be offered without registration or connection to a social network? I will describe the api/implementation details and offer directly our free “ip to geolocation aggregator”-script.
The first step is determining geo location based on Internet IP address of the visitor. I have found five free service providers which offer data based on the client-IP the geo position and city/country data. Classic “ip to geolocation data offers” are commercial. You have to buy and download a sql dump or csv file with ip ranges from isp with country and city data – some expanded with long/lat values. The second solution (and to save hosting space) is using a http api which offer theses data directly when being called – these looks like the preferred possibility. And the third way is to include a javascript which can integrate the geo position directly without need of a server component.
Hostip.info
HostIP is a community-powered database of IP mapping with a simple REST API. But you can also get the database dump if you have a local database and want to integrate . Simple start a HTTP request with the IP of your visitor and get the following 4-line-result:
- URL:
http://api.hostip.info/get_html.php?ip=xxx&position=true
-
Country: UNITED STATES (US) City: Sugar Grove, IL Latitude: 41.7696 Longitude: -88.4588
For simple integration I will use php lines, php output will be javascript: Fetch the data with the curl module and parse it with a simple regex!
preg_match("/Country:\s+(.*?)\nCity:\s+(.*?)\nLatitude: (\d+\.\d+)\nLongitude: (\d+\.\d+)/", $DATA, $ma); echo " hostip:{country: '".$ma[1]."', city: '".$ma[2]."', long: ".$ma[4].", lat:".$ma[3]."}";
IPInfoDB.com
At ipinfodb (or better known as iplocationtools.com, found via programmableweb.com) you can find some free service to get the position for an IP via API webservice (limitation is 500 connections at a rate faster than 3 per second during a 1h period) or all the data as a sql dump. I choose the API webservice (easy to integrate) with XML-Output, because the city names are save with xml and utf-8 encoding!
- URL:
http://iplocationtools.com/ip_query.php?ip=xxx
-
<?xml version="1.0" encoding="UTF-8"?> <Response> <Ip>74.125.45.100</Ip> <Status>OK</Status> <CountryCode>US</CountryCode> <CountryName>United States</CountryName> <RegionCode>06</RegionCode> <RegionName>California</RegionName> <City>Mountain View</City> <ZipPostalCode>94043</ZipPostalCode> <Latitude>37.4192</Latitude> <Longitude>-122.057</Longitude> </Response>
What do to? Fetch the data and use the simple xml parser to fetch the attributes. php output will be javascript.
$xml = simplexml_load_string($DATA); echo " iplocationtools: {country: '".$xml->CountryName."', city: '".$xml->City."', long: ".$xml->Longitude.", lat:".$xml->Latitude."}";
MaxMind.com
MaxMind.com doesn’t offer a free Webservice like the others. You have to download a binary package with all IP related data for your preferred language. That isn’t as convenient as calling an REST interface.
Our iplocation script will include the javascript url as dynamic loaded javascript. After loading the dynamic parts it looks in the global javascript context for the maxmind functions and include the values in the result object.
- URL: http://j.maxmind.com/app/geoip.js
-
function geoip_country_code() { return 'DE'; } function geoip_country_name() { return 'Germany'; } function geoip_city() { return 'Stuttgart'; } function geoip_region() { return '01'; } function geoip_region_name() { return 'Baden-Württemberg'; } function geoip_latitude() { return '48.7667'; } function geoip_longitude() { return '9.1833'; } function geoip_postal_code() { return ''; }
This javascript interface is ugly and the data defing global functions, which can’t be removed from the global namespace.
<script type="text/javascript" src="http://j.maxmind.com/app/geoip.js"></script> <script type="text/javascript"> if (window.geoip_country_name) { com.unitedCoders.geo.ll.push({ 'name': 'maxmind', 'country': geoip_country_name(), 'city': geoip_city(), 'long': parseFloat(geoip_longitude()), 'lat': parseFloat(geoip_latitude()) }); }; </script>
Here the Javascript code to add the maxmind values in the locationlist of our the global javascript object.
Google AJAX API
The google AJAX API offers a basic loader for many popular javascript libs. I found a nice function at startup: a global google.loader.ClientLocation – object. After some tests the city parameter is not as accurate as in the other location services, but the lat/long values are fine!
<script type="text/javascript" src="http://www.google.com/jsapi?key=###api-key###"></script> <script type="text/javascript"> if (window['google'] && google.loader.ClientLocation) { com.unitedCoders.geo.ll.push({ 'name': 'google', 'country': google.loader.ClientLocation.country, 'city': google.loader.ClientLocation.city, 'long': google.loader.ClientLocation.longitude, 'lat': google.loader.ClientLocation.latitude }); }; </script>
To include the google parameters the google api key must be generated for the domain where the javascript will be used. For this tutorial I used unitedcoderscom.appspot.com as the domain.
WIPmania Location Service
And WIPmania offers a javascript API based on a global javascript object, integration is the same as with the google api.
<script type="text/javascript" src="http://api.wipmania.com/wip.js"></script> <script type="text/javascript"> if (window['WIPlocation']) { com.unitedCoders.geo.ll.push({ 'name': 'WIPmania', 'country': WIPlocation.address.country, 'city': WIPlocation.address.city, 'long': WIPlocation.longitude, 'lat': WIPlocation.latitude }); }; </script>
The same integration like the google api but no need for a application key! But after some tests it turned out that the location data is not too precise!
Geo Location API in the browser
After some googling I found a hint from Adam to get the geo position directly via javascript if the browser is running on a mobile device. The iphone implementation is available with the OS 3.0 update since June 17th 2009. In the future there are also plans to include this with a official W3C API that differs only in the position object. Both implementations provide only the lat/long values not the nearest city’s name. Including looks simple like the other javascript services described below:
if (window['navigator'] && navigator['geolocation']) { navigator.geolocation.getCurrentPosition(function(pos) { if (pos['coords']) { com.unitedCoders.geo.ll.push({ name: 'w3c geo-api', long: pos.coords.longitude, lat: pos.coords.latitude }); } else { com.unitedCoders.geo.ll.push({ name: 'safari on iphone', long: pos.longitude, lat: pos.latitude }); }; }); };
An automatically integration is not useful because there starts a ugly popup dialog to ask the user if the location service should be available for the safari application and then for my domain.
Combine and Improve it
Every IP2geolocation service provider maintain his own database. I got at home three different towns with coordinates that differs for 50 kilometers. To improve this you can choose the two best positions (and discard the rest) or calculate the center point of all results. For some countries the geo location providers knows only the center point of the country so I have chosen only locations with a given city and calculated the middle point of these records for the lat/long values. These values will come with the lat/long-functions.
var com.unitedCoders.geo = { ll: [ { name: 'maxmind', country: 'Germany', city: 'Stuttgart', long: 9.1833, lat: 48.7667}, { name: 'iplocationtools', country: 'Germany', city: 'Bietigheim-bissingen', long: 9.1333, lat:48.9667}, { hostip: {country: 'GERMANY (DE)', city: 'Karlsruhe', long: 8.4, lat:49.05}, ], getLong: function(), //8.905533333333333, getLat: function() // 48.9278 };
After that I have hopefully a more precise position of the visitor than using only one geo location provider’s api. Now I need some services to get content based on this information. For integration of the script I choose to display the position on a map as a simple example.
Show the google map
To visualize the positions on a map the full featured googlemap is too big – I am prefering the static google map. It is just a dynamically build img-url with some parameters (get for your domain a google map api key) which returns a static image.
- URL: http://maps.google.com/staticmap?size=400×300&markers={latitude},{longitude},{size}{color}{alphanumeric-character}
If nothing other given the map will center all markers and fit the zoom level. The API is limited to 1000 calls/hour (of different visitors) but google will be nice in the limits.
And now : I know where you are!
How to integrate all these geo location API?
In Part 2 I will explain with a short php script and a little python script (in the google app engine) the implementation details. For free usage you can include the ip2geoLocation aggregator with the simple integration via one javascript.
If you find more free ip-to-geolocation service proiver feel free to comment this article so we can try to integration the service.

Christian Harms

Latest posts by Christian Harms (see all)
- google code jam 2013 – tic-tac-toe-Tomek solution - April 16, 2013
- Google code jam 2013 – the lawnmower - April 14, 2013
- code puzzles and permutations - April 11, 2013