Geolocate your visitors with PHP (part 2)

In the first part of this series I showed how you could get the country of a visitor via his IP address. Now with this precious information, I’ll show you how to map the visitor visually on the world map using Google Maps.


You must sign up for a Google Maps API key if you don’t already have one.

After signing up for the key, include the following code in the head of your page :

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOURKEY" type="text/javascript"></script>

replacing the YOURKEY by the key you obtained.

We then define a container to hold our map with a width of 630px and height of 350px :

<div id="map" style="width:630px;height:350px;"></div>

Till now the overall code for the page, including the first part, is :

<?php
	require_once("Net/GeoIP.php");
	
	if (isset($HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR']) && eregi("^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$", 

$HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR'])){
		$ip = $HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR'];
	}
	else{
		$ip = getenv("REMOTE_ADDR");
	}
	
	$geoip = Net_GeoIP::getInstance("./data/GeoIP.dat");

	$country = $geoip->lookupCountryName($ip);
?>

<html>
	<head>
		<title>Google maps</title>
		<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOURKEY" type="text/javascript"></script>	
	</head>
	<body>
		<div id="map" style="width:630px;height:350px;"></div>
	</body>
</html>

Now begins the cool stuff, I’ll show you the complete javascript code and then explain afterwards.

var locator = {    			
	addAddressToMap: function(response) {
		locator.map.clearOverlays();
		if (!response || response.Status.code != 200) {
			//alert("Sorry, we were unable to geocode that address");
		}
		else {
			place = response.Placemark[0];
			point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
			marker = new GMarker(point);
			locator.map.addOverlay(marker);
			marker.openInfoWindowHtml(place.address);
		}
	},

	load: function() {
		if (GBrowserIsCompatible()) {
			locator.map = new GMap2(document.getElementById("map"));
        		locator.map.setCenter(new GLatLng(34, 0), 1);
        		locator.geocoder = new GClientGeocoder();
        		locator.geocoder.getLocations("<?php echo $country; ?>", locator.addAddressToMap);
      		}
    	}
}

We have a nice JSON object with 2 functions in it, namely:

  • load
  • addAddressToMap

The load function

The load function will be called upon loading the page, it will initialize our map, and center it.

locator.map = new GMap2(document.getElementById("map"));
locator.map.setCenter(new GLatLng(34, 0), 1);

We then create an instance of the GClientGeoCoder class which will allow us to obtain geocodes for user specified addresses.

With the object created, we then call the getLocations method with 2 parameters. The first one is the country which we got from the php script and the second parameter being the callback function. In this case our callback function is addAddressToMap.

The addAddressToMap function

The addAddressToMap function is called when the geocoder returns an answer, with response as parameter. The response object contains various information such as the address and the coordinates for the country obtained via the getLocations method.

These coordinates can be accessed via

  • response.Placemark[0].Point.coordinates[1] for longitude and
  • response.Placemark[0].Point.coordinates[0] for latitude

To make things a bit short I’ve placed the response.Placemark[0] in a variable called place :

place = response.Placemark[0];

, thus the coordinates can be accessed via :

place.Point.coordinates[1]
place.Point.coordinates[0]

With these 2 coordinates we create a marker which we’ll plot on the map :

point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
marker = new GMarker(point);
locator.map.addOverlay(marker);

As a bonus we also have a popup showing the country name using the openInfoWindowHtml method. We simply add the following line :

marker.openInfoWindowHtml(place.address);

our final PHP page looks like that :

<?php
	require_once("Net/GeoIP.php");
	
	if (isset($HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR']) && eregi("^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$", 

$HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR'])){
		$ip = $HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR'];
	}
	else{
		$ip = getenv("REMOTE_ADDR");
	}
	
	$geoip = Net_GeoIP::getInstance("./data/GeoIP.dat");

	$country = $geoip->lookupCountryName($ip);

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
		<title>my ip address with Google Maps</title>
		<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOURKEY" type="text/javascript"></script>

		<script type="text/javascript">
    		//<![CDATA[
    		
    		var locator = {    			
    			addAddressToMap: function(response) {
				locator.map.clearOverlays();
				if (!response || response.Status.code != 200) {
					//alert("Sorry, we were unable to geocode that address");
				}
				else {
					place = response.Placemark[0];
					point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
					marker = new GMarker(point);
					locator.map.addOverlay(marker);
					marker.openInfoWindowHtml(place.address);
				}
			},

			load: function() {
				if (GBrowserIsCompatible()) {
					locator.map = new GMap2(document.getElementById("map"));
        				locator.map.setCenter(new GLatLng(34, 0), 1);
        				locator.geocoder = new GClientGeocoder();
        				locator.geocoder.getLocations("<?php echo $country; ?>", locator.addAddressToMap);
				}
      			}
    		}
   
    		//]]>
		</script>
	</head>
	<body onload="locator.load();" onunload="GUnload();">
		<div id="map" style="width:630px;height:350px;"></div>
	</body>
</html>

After the page has been loaded, we just call the locator.load() function which will initialize the whole process.

Be Sociable, Share!

Comments (12)

  1. 8:47 pm, October 8, 2008Mike  / Reply

    How to use this code for multiple ips?

    I tried adding:
    locator.geocoder.getLocations(“”, locator.addAddressToMap);
    but now only $country2 is being displayed on the map.

  2. 1:43 pm, October 9, 2008asvin  / Reply

    Hi Mike

    I’ll have a look and let you know ;-)

  3. 1:34 am, October 23, 2008Antonio  / Reply

    If you want users of your website to see in a map their geographical location altogether with the rest of your visitors, simply add a link to this url: “http://www.uniworldpro.com/uniworldpro/geovisits.php” like this:

    Find out where the users of this website are coming from

    Just install this link, then click on it to inmediately watch your position in the map. As more and more visitors keep accesing it a historic is created with markers on their locations. A visual guestbook kind of. Free and very easy to use.

  4. 12:44 pm, November 3, 2008Tim  / Reply

    We are not very well-versed in programming. Therefore, we are using the PHP API from the IP2Location.

    http://www.ip2location.com/php.aspx

  5. 9:09 pm, December 5, 2008Mike  / Reply

    I solved my problem but now have a new one…

    Can we have 2 maps on one html page??

    I did just that, renaming the locator function for the second map, but it appears to be working only after so many refreshes. The first map is always perfect but the second is missing push pins almost all the time…

    Does anyone has any suggestions??

  6. 11:23 am, January 14, 2009Andy  / Reply

    Nice highlighted example.
    I no longer use MaxMind’s database, as I find the geolocation API of geoplugin more accurate and they have other interesting geo things too.

    http://www.geoplugin.com/examples

    give a few coded examples (and using their PHP class is really easy too.

  7. 2:49 pm, June 22, 2009angeline  / Reply

    Where is this file, Net/GeoIP.php ?

  8. 2:08 pm, September 25, 2009vishwas  / Reply

    i want to use this code but error Net/GeoIP.php

  9. 11:49 am, May 22, 2010Jack Fisher  / Reply

    good examples from commentators make this blog a worthy source for developers.
    Thank you

  10. 11:49 am, May 22, 2010Ertan Fırat  / Reply

    excellent ideas

  11. 11:51 am, May 22, 2010Omer Feyzoglu  / Reply

    sometimes the IP does not reveal the exact location
    of the visitor depending on the location of the server .. any solutions ??

Leave a Reply

Allowed Tags - You may use these HTML tags and attributes in your comment.

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>