Returning nearby locations to Django

I have a django model with a custom attribute LocationField

.

class List(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=200)
    location = LocationField(blank=True, max_length=255)

      

The values ​​in this are stored as a format string latitude, longitude

. From my template, I am passing the url like this:/nearby?lat='+somevalue+'&long='+somevalue

Now I want to return adjacent records from List

depending on the passed values.

For this, I wrote the views.py function like this:

def nearby(request):
    if request.GET['lat']:
        lat = request.GET['lat']
        longitude = request.GET['long']
        first_query = Playlist.objects.filter(location__istartswith=lat)
        for f in first_query:
           l = f.index(',')
           n_string = f[l:]

      

To clarify what I did, it first_query

returns all records starting with the same latitude

. However, now I also want to match longitude

, so I run this one for loop

and look for the comma index that separates latitude,longitude

in mine LocationField

. n_string

takes a substring LocationField

and I plan on then matching it to my variable longitude

.

My question has two parts:

  • How do I create a query to match latitude and how do I return it to the template?
  • How can I check, for example, the area of ​​2 square kilometers around this area?

Are there django packages for this?

+3


source to share


3 answers


There are at least 3 ways to do this:

a) Distance from Haersine (example in MySQL)

def nearby_spots_old(request, lat, lng, radius=5000, limit=50):
    """
    WITHOUT use of any external library, using raw MySQL and Haversine Formula
    http://en.wikipedia.org/wiki/Haversine_formula
    """
    radius = float(radius) / 1000.0

    query = """SELECT id, (6367*acos(cos(radians(%2f))
               *cos(radians(latitude))*cos(radians(longitude)-radians(%2f))
               +sin(radians(%2f))*sin(radians(latitude))))
               AS distance FROM demo_spot HAVING
               distance < %2f ORDER BY distance LIMIT 0, %d""" % (
        float(lat),
        float(lng),
        float(lat),
        radius,
        limit
    )

    queryset = Spot.objects.raw(query)
    serializer = SpotWithDistanceSerializer(queryset, many=True)

    return JSONResponse(serializer.data)

      

b) using Geodjango (PostgreSQL + PostGIS)



def nearby_spots_new(request, lat, lng, radius=5000, limit=50):
    """
    WITH USE OF GEODJANGO and POSTGIS
    https://docs.djangoproject.com/en/dev/ref/contrib/gis/db-api/#distance-queries
    """
    user_location = fromstr("POINT(%s %s)" % (lng, lat))
    desired_radius = {'m': radius}
    nearby_spots = Spot.objects.filter(
        mpoint__distance_lte=(user_location, D(**desired_radius))).distance(
        user_location).order_by('distance')[:limit]
    serializer = SpotWithDistanceSerializer(nearby_spots, many=True)

    return JSONResponse(serializer.data)

      

c) some smart queries (think of a circle in a square)

see my answer here: How to filter django model with latitude and longitude coordinates that fall within a specific radius

+6


source


You must use GIS databases to store and perform operations on coordinates, searches, etc.

To keep using location https://docs.djangoproject.com/en/dev/ref/contrib/gis/model-api/#pointfield



As a database you can use https://docs.djangoproject.com/en/dev/ref/contrib/gis/install/#postgis or https://docs.djangoproject.com/en/dev/ref/contrib/ gis / install / spatialite /

To search for nearby you have to use distance search, see examples at https://docs.djangoproject.com/en/dev/ref/contrib/gis/db-api/#distance-lookups

+1


source


Yes, there is a package / project for this Geodjango . You can read the official documentation here .

0


source







All Articles