GeoDjango Distance Filter With Distance Value Stored Within Model - Query
I have an Order model, that has an origin PointField and a range IntegerField. Furthermore, there is an UserProfile model, which has a geo_location PointField. Now, I have an User
Solution 1:
I think you're going to have to drop some SQL in to do what you want, as the GeoDjango helpers don't have a way of you making a suitable Distance object that is simultaneously a Django F object (ie field lookup). You don't say which database you're using, but here's how you do it with PostGIS:
Order.objects.all().extra(
where=['ST_Distance(origin, ST_PointFromText(%s, 4326)) <= CAST(range AS double precision) / 1000'],
params=[user.profile.geo_location.wkt]
)
Let's explain what's happening here, because it's pretty thorny. Going from the left:
.extra()allows you to add extra fields and restrictions into a query; here we're adding a restrictionST_Distance()is the PostGIS function that the GeoDjangodistance_lteoperator converts into (from the Django documentation)ST_PointFromText()converts from WKT syntax into a PostGIS Geometry object4326is the default SRID for Django, but not for PostGIS so we have to specify it- we have to
CASTyour field to double precision because you're using an integer - then we have to divide by 1000 to convert from metres into kilometres, which I believe is what we need
- GeoDjango
Pointfields have an accessor.wktwhich gives their WKT representation, which we needed earlier in ourST_PointFromText()call
Note that according to the PostGIS documentation, ST_Distance() doesn't use indexes, so you may want to investigate using ST_DWithin() instead (it's documented right after ST_Distance()).
Post a Comment for "GeoDjango Distance Filter With Distance Value Stored Within Model - Query"