MistyD
MistyD

Reputation: 17223

Filter a queryset field of PointField for items within a specific distance range is incorrect

I would like to filter a queryset for items within a specific range. This is what my model looks like

class modelEmployee(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
    location = models.PointField(srid=4326,max_length=40, blank=True,null=True) 
    objects = GeoManager()

Now this is how I am running a filter command. To return items within a specific range of 90 miles.

qset = modelEmployee.objects.filter(location__distance_lte=(someLocation, D(mi=90)))

The result returns an item whose distance is actually 223.732 miles which it shouldnt return.

These are the locations of the two items

location A - lat: 47.628641 and long: -117.402997

location B - lat: 47.618337 and long: -122.205341

The distance b/w the two is actually 223.732 miles. I must be filtering it wrong. Any suggestions on where I might be going wrong ?

Upvotes: 5

Views: 2850

Answers (3)

Gabriel Muj
Gabriel Muj

Reputation: 3805

From docs geo spatial query you should use dwithin

Your example should use it like this:

qset = modelEmployee.objects.filter(location__dwithin=(someLocation, D(mi=90)))

Upvotes: 8

Anil Kumar Gupta
Anil Kumar Gupta

Reputation: 179

You can try this ref(gis/db-api), I hope it will work what you want.

Example:

from django.contrib.gis.db import models
class SouthTexasCity(models.Model):
    name = models.CharField(max_length=30)
    # A projected coordinate system (only valid for South Texas!)
    # is used, units are in meters.
    point = models.PointField(srid=32140)

Then distance queries may be performed as follows:

from django.contrib.gis.geos import GEOSGeometry
from django.contrib.gis.measure import D # ``D`` is a shortcut for ``Distance``
from geoapp.models import SouthTexasCity
# Distances will be calculated from this point, which does not have to be projected.
pnt = GEOSGeometry('POINT(-96.876369 29.905320)', srid=4326)
# If numeric parameter, units of field (meters in this case) are assumed.
qs = SouthTexasCity.objects.filter(point__distance_lte=(pnt, 7000))
# Find all Cities within 7 km, > 20 miles away, and > 100 chains away (an obscure unit)
qs = SouthTexasCity.objects.filter(point__distance_lte=(pnt, D(km=7)))
qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(mi=20)))
qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(chain=100)))

Upvotes: 0

shashank
shashank

Reputation: 1161

From Django docs distance_lte is for returns models where the distance to the geometry field from the lookup geometry is greater than or equal to the given distance value.

qset = modelEmployee.objects.filter(location__distance_lte=(someLocation, D(m=90)))

you can use dwithin for the query.

qset = modelEmployee.objects.filter(poly__dwithin=(geom, D(m=5)))

Upvotes: 0

Related Questions