问题
I want to have a radius based distance search. To do this, I want to create a buffer around a point object in order to filter objects that are inside it.
Here is where I am at with it:
>>> lat = 37.7762179974
>>> lon = -122.411562492
>>> from django.contrib.gis.geos import Point
>>> pnt = Point(lat, lon)
>>> buf = pnt.buffer(0.0001)
But I am having problems filtering the Thing
objects based on whether they are inside the buffer:
>>> z = Thing.objects.filter(pnt__intersects=buf)
(I know that the above is incorrect, but I use it to elaborate what I am trying to do.)
How can I create a buffer around the Point
and then filter Things
that are inside the buffer
?
EDIT: models.py
class Thing(models.Model):
lat = models.FloatField()
lon = models.FloatField()
How can I filter based on a point comprised of a combination of these two model fields?
This cannot work obviously, because I do not have a pnt
field in my model:
>>> pnt = Point(lat, lon)
>>> z = Thing.objects.filter(pnt__intersects=buf)
But how can I do something similar?
回答1:
I'm not sure what you mean by "buffer", but if you want a radius based distance search you might try using the... distance!
Here is an example with a kilometer metric:
from django.contrib.gis.measure import D
Thing.objects.filter(pnt__distance_lte=(pnt,D(km=distance)))
You should certainly have a look at the docs: https://docs.djangoproject.com/en/dev/ref/contrib/gis/db-api/#distance-lookups
回答2:
PostGIS has a method called ST_MakePoint which can create a 2D, 3D or 4D point.
In a previous answer we saw that it is possible to create a custom database function from an existing PostGIS function:
from django.contrib.gis.db.models.functions import GeoFunc
class MakePoint(GeoFunc):
function='ST_MakePoint'
Now we can create a point by annotate()ing and apply the intersects
on it:
z = Thing.objects.annotate(pnt=MakePoint('lat', 'lon'))
.filter(pnt__intersects=buf)
You can achieve the same effect by utilizing GeoFunc() and F() expressions:
from django.contrib.gis.db.models.functions import GeoFunc
z = Thing.objects.annotate(pnt=GeoFunc(
F('lat'), F('lon'),
function='ST_MakePoint'
).filter(pnt__intersects=buf)
Note: You could consider adding a pnt
field in your Thing
model and avoid the above.
来源:https://stackoverflow.com/questions/19144834/geodjango-how-to-buffer-from-point