Darren O'Neill

Using PostGIS and GeoDjango to find your nearest neighbour

Firstly create a database table to hold points of interest. You should probably use South / Django's syncdb. SQL shown for reference:

CREATE TABLE store (
    id integer NOT NULL,
    name character varying(100),
    location geography(Point,4326),
    longitude double precision,
    latitude double precision
);

CREATE INDEX store_location_idx ON store USING gist (location);

Setup Django to use the PostGIS database engine in your settings file:

DATABASES = {
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.postgis',
        'NAME': 'dbname',
        'USER': 'dbuser',
        'PASSWORD': 'password',
        'HOST': '',
        'PORT': '',
    }
}

Create the model (based on the SQL above):

from django.contrib.gis.geos import Point
from django.contrib.gis.db import models

class Store(models.Model):
    name = models.CharField(max_length=100)
    location = models.PointField(geography=True, srid=4326)
    longitude = models.FloatField()
    latitude = models.FloatField()
    objects = models.GeoManager()

    def save(self, **kwargs):
        self.location = Point(self.longitude, self.latitude)
        super(Store, self).save(**kwargs)

In a view get all the points of interest within a 100 mile radius of a specified longitude / latitude:

from django.contrib.gis.geos import Point
from django.contrib.gis.measure import D

point = Point(lng, lat)
points = Store.objects.filter(
    location__distance_lte=(point, D(mi=100))
).distance(point).order_by('distance')

Show the results in a template:

<ul>
    {% for point in points %}
    <li>{{ point.name }} is {{ point.distance.mi|floatformat }} miles away</li>
    {% endfor %}
</ul>