georoot
georoot

Reputation: 3617

Calculating near GPS coordinates in Django

I have got a model in Django that stores a list of GPS coordinates for location. What I need to do is implement a search. I take the coordinates of the user from his device. What I need to do is show him locations nearby, and also the functionality that he can filter his search radius.

What we initially had in mind was to iterate through all the data and find matches. But that would be inefficient even with caching.

What I need to know is can I use Neo4j graph database for the same or should I stick to existing ORM.

In case of existing ORM, what is the most efficient way to write a search filter that returns me list of nearby locations.

In case of Neo4j, I am totally new and would appreciate if you can point me to some resources with a sample implementation for the same with Django.

Here is the current models that we are using

from __future__ import unicode_literals                                         
                                                                                
from django.db import models                                                    
from django.contrib.auth.models import User                                     
                                                                                
class Category(models.Model):                                                   
        name = models.CharField(max_length = 100, blank = False)                
                                                                                
class Location(models.Model):                                                   
        name = models.CharField(max_length = 100, blank = True)                 
        cordinateX = models.FloatField(max_length = 50 , blank = False)         
        cordinateY = models.FloatField(max_length = 50 , blank = False)         
                                                                                
class Activity(models.Model):                                                   
        owner = models.ForeignKey(User,blank = True, null = True)               
        name = models.CharField(max_length = 100,blank = False)                 
        about = models.TextField(max_length = 500, blank = False)               
        location = models.ForeignKey(Location, blank = True, null = True)       
        category = models.ManyToManyField(Category, blank = True)               
        status = models.BooleanField(default = False)                           
        deleted = models.BooleanField(default = False)                          
        createdAt = models.DateTimeField(auto_now_add=True)                     
                                                                                
        def __unicode__(self):                                                  
                return self.name

Can I use Neo4j graph database for this or should I stick to existing ORM?

Based on A comment, I am assuming using GeoDjango the Location should change, and lat,long should be replaced with Point from GeoDjango models.

This added another question, would there be problems in foreign key with existing models to geodjango models. The search filter should be able to fetch nearby Activity and show then in order nearest to farthest.

Upvotes: 2

Views: 1997

Answers (1)

e4c5
e4c5

Reputation: 53734

Once you have installed Geodjango you can convert your models to spatial
models by changing your import to

from django.contrib.gis.db import models

As you rightly guessed your Location model would change.

class Location(models.Model):                                                   
    name = models.CharField(max_length = 100, blank = True)                 
    coords = models.PointField() 

Can you have a foreign key from Activity to Location? definitely yes. Your Activity model wouldn't need to change

As for fetching nearby activities and displaying them from the order of nearest to furthest. This is what your query is going to look like

from django.contrib.gis.db.models.functions import Distance
Activity.objects.annotate(
  distance=Distance('location__coords',somepoint)
).order_by('distance')

Where somepoint is a point object. You can even get fancy and allow somepoint to come from another model with the use of Django F objects.

At this stage I must warn you that whether you use geodjango or some other platform queries like the above might become slow if you have a very large number lot of locations in your database.

The secret to speeding up the query is to apply a filter that removes points that are too far way. That's where dwithin enters the picture.

Upvotes: 1

Related Questions