假设我有以下型号:
class Person:
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=150)
location = models.PointField()
如何使用geodjango按位置获取k个最近邻居(KNN)?
我是否必须为此编写自定义SQL?
我正在使用PostgreSQL和PostGIS。
答案 0 :(得分:2)
您可以使用raw()
sql查询来使用postgis order_by
运算符:
<->
使用边界框的中心获取最近邻居来计算物体间距离。
<#>
使用边界框本身获取最近邻居来计算物体间距离。
在您的情况下,您想要的那个似乎是<->
运算符,因此是原始查询:
knn = Person.objects.raw(
'SELECT * FROM myapp_person
ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
[location.x, location.y]
)[:k]
由于自己的derpiness而编辑:您可以省略[:k]
以在原始SQL查询上添加LIMIT 1
。 (不要像我一样同时使用它们!)
在回答您的其他问题:How efficient is it to order by distance (entire table) in geodjango时,可能有另一种解决方案:
通过启用spatial indexing
并通过逻辑约束缩小查询范围(如上面链接问题的in my answer所述),您可以实现非常快速的 KNN 查询,如下所示:
current_location = me.location
people = People.objects.filter(
location__dwithin=(current_location, D(km=50))
).annotate(
distance=Distance('location', current_location)
).order_by('distance')[:k]