Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
An application for transparently geotagging your models.
Python JavaScript
branch: master



This is a WIP and is not to be used in production unless you know what you're doing.

The documentation also outdated. But it shouldn't be for long.


For the clustering:

  • scikit.learn

For the template tags:

  • django-ttags


Via pip:

pip install -e git+git://

The old fashioned way:

  1. Download repo
  2. Unpack and cd django_geotagging-new
  3. python install


  • add geottagging to settings.INSTALLED_APPS
  • If you want the maps to be displayed, include the necessary javascript:: <!-- Map stuff --> <script src="{{ STATIC_URL }}js/vendor/underscore.js" type="text/javascript" charset="utf-8"></script> <script src="{{ STATIC_URL }}js/vendor/backbone.js" type="text/javascript" charset="utf-8"></script> <script src="{{ STATIC_URL }}js/vendor/jquery.tmpl.js" type="text/javascript" charset="utf-8"></script> <script src="" type="text/javascript"></script> <script src="" type="text/javascript"></script> <script src="" type="text/javascript"></script> <script src="{{ STATIC_URL }}js/common/global.js" type="text/javascript"></script> <script src="{{ STATIC_URL }}js/app/Spot.js" type="text/javascript" charset="utf-8"></script> <script src="{{ STATIC_URL }}js/app/MapView.js" type="text/javascript" charset="utf-8"></script>



To use geotagging in your models you will need to have GeoDjango installed in your project.

To add geotagging to a model make it inherit from the GeoTag model that you need to use. Currently the following GeoTagging types are available:



from geottaging.models import PointGeoTag

class Attraction(PointGeoTag):
    name = models.CharField(max_length=100)

The model should now have a field called geotagging_point that stores the point information. Also, a new manager is added to the model under Model.geo_objects so the geographical queries can be made.


>>> Attraction.objects.all()
[<Attraction>, ...]
>>> Attraction.geo_objects.all()
[<Attraction>, ...]
>>> Attraction.objects.filter(geotagging_point__intersects=an_area)
... error
>>> Attraction.geo_objects.filter(geotagging_point__intersects=an_area)
[<Attraction>, ...]

To add alias to the geotagging_point field, simply write a property to access it. This will not allow the new name to be used in querysets, but it will be available to the object:

class Attraction(PointGeoTag):
    def _get_point(self):
        return self.geotagging_point
    location = property(_get_point)


To add the geotagging to the admin, just use the admin provided at:



from geotagging import admin
from yourproject.apps.attractions.models import Attraction, admin.GeoTaggedModelAdmin)


Route optimization

The geotagging app provides a view for optimizing routes. The optimization is done by calls to the google maps directions api.

This view takes a list of waypoints to be routed and returns the optimal order.

The list of waypoints can be provided in two ways:

  • A model and a list of ids: In this case, the request will look something like this:

  • A list of locations separated by |: The locations can be either names or lat-long objects. The request will look like one of these:


The result is always returned in terms of what was specified in the request. This means that for the previous three requests the response would be


optimal_order: [
"<Attraction: My house>"
"<Attraction: Malmö>"
"<Attraction: köpenhamn>"
success: true


-optimal_order: [
success: true

and 3):

-optimal_order: [
success: true




Need documentation for the maps feature. Some stuff to remember when documenting:

  • an object can implement get_title(self) -> string to assign the title to a marker

  • The first parameter must be either a PointGeoTag subclass, a queryset of PointGeoTag subclasses, a list of PointGeoTag subclases or a LatLong string.

  • Add the reset context processor to avoid map ids from increasing:

    'django.core.context_processors.request', 'geotagging.context_processors.map_counter_reset',

  • Document what's available to the template

  • Missing stuff (make markers clickable, avoid markers from overlapping)

Including maps in templates

To start including maps you need to make sure the request and map_counter_reset context processors are eneabled:


and that the views use RequestContext.

That should be enough for static maps.

For dynamic maps the views should include the required javascript:

{% block extra_head %}
{% geotagging_maps_api %}
{% endblock %}




Here's a basic template to include some maps:

{% extends "base.html" %}
{% load geotagging_maps %}

{% block content %}
<div id="map">
   <div id="placeholder-map" style="height:400px"></div>
{% endblock %}

{% block js %} {# at the end of the page #}
    {{ block.super }}
    {% maps_js "map" items_to_be_mapped %}
{% endblock %}
Something went wrong with that request. Please try again.