<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=338168267432629&amp;ev=PageView&amp;noscript=1">
Programming

Location Awareness in Django

The identification of the geographic location or geolocation of devices and users who use these devices is now a very common service provided by plenty of companies. Geolocation of electronic devices can be done by relating the geographic location with information such as the device’s IP Address, location of the …


The identification of the geographic location or geolocation of devices and users who use these devices is now a very common service provided by plenty of companies. Geolocation of electronic devices can be done by relating the geographic location with information such as the device’s IP Address, location of the Wi-Fi connection, or even the coordinates of the device GPS.

Step 1: Location awareness in Django is now available through several application APIs such as GeoIPpygeoip, and GeoDjango. Django ships with it a wrapper for MaxMind GeoIP C API which is GeoIP. All you need to make IP-based geolocation possible through GeoIP is to ensure that you have the GeoIP C library installed and either the GeoIP Country or City databases extracted in a specific folder in your Django project files. Simply download GeoLiteCity.dat.gz from http://geolite.maxmind.com/download/geoip/database/ and GeoIP.dat.gz from http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/. GEOIP_PATH in settings.py must also be set accordingly to point to the location of the datasets.

from os.path import abspath, dirname, join
DJANGO_ROOT = abspath(join(dirname(__file__), "../"))
PROJECT_ROOT = abspath(dirname(__file__))
APPPATH = '%s' % PROJECT_ROOT
GEOIP_PATH = PROJECT_ROOT + '/geoip/'

The next step would be to create a folder in the project root directory, name it geoip, and extract the contents of GeoIP.dat.gz and GeoLiteCity.dat.gz there. This is necessary since the GEOIP_PATH should point to the correct directory of the datasets.

from django.contrib.gis.utils import GeoIP
query = '74.207.245.22'
# query = 'bixly.com'

g = GeoIP()
g.country(query)
# {'country_name': 'United States', 'country_code': 'US'}

g.city(query)
# {'city': 'Absecon', 'region': 'NJ', 'area_code': 609, 'longitude': -74.497703552246094, 'country_code3': 'USA', 'latitude': 39.4208984375, 'postal_code': '08201', 'dma_code': 504, 'country_code': 'US', 'country_name': 'United States'}

g.lon_lat(query)
# (-74.497703552246094, 39.4208984375)

g.country_code(query)
# 'US'

g.country_name(query)
# 'United States'

The GeoIP object provides functions that accept either the FQDN (fully qualified domain name) or IP address. This may include the IP address of the server such as 74.207.245.22, IP address of a client computer such as 123.45.12.23, or even a fully qualified domain name such as bixly.com.

The functions provided are easy to use. For example, if you want to get the country name and country code where the computer with IP address 123.45.12.23 is located, simply import GeoIP from django.contrib.gis.utils, create a GeoIP instance g, and call g.country(‘123.45.12.23’). This will return a dictionary that contains the country name and country code of the specified IP address.

With only the IP address or a fully qualified domain name, GeoIP API can provide several functions that give information such as the country code, country name, longitude and latitude coordinates, and city. With this, if you provide a computer’s IP address, GeoIP can easily provide the approximate location of that computer. Please note that the GeoIP City database is around 80% accurate at this time because IP addresses shift location over time. Just make sure you have the latest version of the database from time to time. For more details regarding geolocation accuracy, you may see this page.

Step 2: To utilize some of the functions provided by GeoIP, integrating it with Google Maps API should result to a very simple yet useful web application. Google Maps is a service that provides a rich mapping tool with information such as business locations, driving directions, and the like.

So let’s start off with a quick setup of Google Maps to our application. The first step is to obtain an API Key for the Google Maps API. For local development, input in http://localhost for the web site URL. After obtaining the API key, include the following code below in your template head. This is necessary for Google Maps to work together with all the wrapper plugins for Google Maps API. Do not forget to replace API_KEY with the API key you obtained.

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

jQuery is also needed to make the Google Maps integration easier. jQuery is a rich Javascript library which provides a lot of functionalities for manipulating HTML elements, events, Ajax interactions and the like. In this app demonstration, at least version 1.4.1 is needed since it includes parseJSON which we will use later.

Google Maps integration can easily be done using the jQuery plugin gMap alongside several other wrapper classes (e.g. Google Maps jQuery plugin, Googlemap plugin, etc). Simply download the 2 javascript files,  add them to your original set of javascript files, and include the following codes below in your templates. Wrapper plugins such as gMap simplifies API usage and abstracts all possible unnecessary codes which may affect the programmer’s efficiency and code length.

<script type="text/javascript" src="js/jQuery.min.js"></script>
<script type="text/javascript" src="js/jQuery.gmap-1.1.0-min.js"></script>

To test your Google Maps setup, simply create a div for the map, select the new div element using jQuery’s selector, and call gMap function on it after the document is ready. This is done with the code below. The jQuery selector $() simply accepts arguments such as classes or ids in order to instantly have control over a specific element or elements. For more details regarding jQuery selectors you may visit this page.

<div id="map" style="height: 100%; width: 100%;"></div>
<script type=”text/javascript”>
    $(function(){
        $("#map").gMap();
    });
</script>

The code segment below simply runs any code inside it when the document is ready. This is the shorthand notation for jQuery’s document ready function.

$(function(){
    // insert code here
});

The gMap function simply uses the selected div as the container of the map. It can also accept several arguments such as zoom, latitude, and longitude and other more arguments as stated in the documentation.

Step 3: Obtaining the client’s IP address is another important part of the location awareness application. There are several ways to obtain the client’s IP address. One way would be to get the value stored in the variable REMOTE_ADDR (or sometimes HTTP_X_FORWARDED_FOR) in your django views.py. This has several issues and the setting up just to get it to work locally or in a production server properly may be too hard or may take some time. One example of an issue regarding this method is that the variables which are supposed to store the client’s IP address will contain only 127.0.0.1 (localhost) when you run your server locally.

One of the easiest ways in detecting the client’s IP address without much setup or installation involves including the following code below in the templates to store the IP address to a variable.

<script type="text/javascript">
    var client_ip = null;
    function getip(json){
        client_ip = json.ip;
    }
</script>
<script type="application/javascript" src="http://jsonip.appspot.com/?callback=getip"></script>

http://jsonip.appspot.com/?callback=getip should return something like

getip({"ip": "XXX.XX.XX.XX", "address":"XXX.XX.XX.XX"});

The getip function declared above is called and the IP address gets stored in the client_ipvariable. To get the IP address of the client, just get the value of client_ip when the document is ready.

Step 4: The only step remaining is to combine GeoIP, gMap plugin, getip, and Django together. This is done by creating a view which will return the latitude and longitude given the ip address as url parameter.

from django.contrib.gis.utils import GeoIP

def get_lat_long(request):
    ip,g_city = None, None
    if 'ip' in request.GET:
        ip = request.GET.get('ip')
        g = GeoIP()
        g_city = g.city(ip)
    return HttpResponse(json.dumps([g_city['latitude'],g_city['longitude']]))

The page /get_lat_long?ip=XXX.XX.XX.XX will return something like [XX.XXX, -XXX.XXX]which are the latitude and longitude values respectively. The view get_lat_long accepts the IP address as the URL parameter and simply passes the obtained value as the query parameter to GeoIP city function.

 

Also include the following code below in the template to obtain the latitude and longitude of the ip address stored in client_ip.

<script type="text/javascript"><
    $(function(){
        $.get('get_lat_long?ip='+client_ip, function(data) {
            var lat_long = jQuery.parseJSON(data);
            var lat = lat_long[0];
            var lon = lat_long[1];
            $("#map").gMap({markers: [{ latitude: lat, longitude: lon }],zoom: 16});
        });
    });
</script>

The code above works as follows:

1) When the webpage is ready, an Ajax GET request is performed with the client’s IP Address as the additional parameter.

2) The view get_lat_long returns the latitude and longitude in JSON format and is then passed as data back to the webpage. In other words, data now contains whatever the viewget_lat_long replies back.

3) Since data is just a piece of String, it needs to be converted to JSON format for it to be processed accordingly. This is done using jQuery.parseJSON(data) which is available only to jQuery version 1.4.1 and above.

4) Next, the variables lat and lon will be made to contain the latitude and longitude coordinate values respectively.

5) Lastly, the map marked along the specified latitude and longitude is generated.

Finished Product: The location awareness app we just made simply obtains the client’s IP address and stores it in the variable client_ip, obtains the respective approximate latitude and longitude given the client IP address through ajax call to get_lat_long, and finally displays the Google Map marked along the specified coordinates.

Location awareness applications are common nowadays. There are several services out there that may help you with the functionalities you need in order to make applications like these. All you need to do is to find such services and simply combine them together to make powerful applications.

For reference purposes, the codes are below.

# index.html

<html>
<head>
<script type="text/javascript">
    var client_ip = null;
    function getip(json){
        client_ip = json.ip;
    }
</script>
<script type="application/javascript" src="http://jsonip.appspot.com/?callback=getip"></script>
<script type="text/javascript" src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=API_KEY"></script>
<script type="text/javascript" src="js/jQuery.min.js"></script>
<script type="text/javascript" src="js/jQuery.gmap-1.1.0-min.js"></script>

<script type=”text/javascript”> $(function(){ $.get(‘get_lat_long?ip=’+client_ip, function(data) { var lat_long = jQuery.parseJSON(data); var lat = lat_long[0]; var lon = lat_long[1]; $(“#map”).gMap({markers: [{ latitude: lat, longitude: lon }],zoom: 16}); }); }); </script> </head> <body> <div id=”map” style=”height: 100%; width: 100%;”></div> </body> </html>

# views.py

from django.shortcuts import render_to_response
from django.template import RequestContext
from django.contrib.gis.utils import GeoIP
from django.http import HttpResponse
import json

def get_lat_long(request):
    ip,g_city = None, None
    if 'ip' in request.GET:
        ip = request.GET.get('ip')
        g = GeoIP()
        g_city = g.city(ip)
    return HttpResponse(json.dumps([g_city['latitude'],g_city['longitude']]))

def index(request):
    return render_to_response('index.html',{}, context_instance=RequestContext(request))

References:

Similar posts

Get notified about the latest in Tech

Be the first to know about new tech from the experts at Bixly!