Você pode usar um
raw()
consulta sql para utilizar postgis order_by
operadores:-
<->
que obtém o vizinho mais próximo usando os centros das caixas delimitadoras para calcular as distâncias entre objetos.
-
<#>
que obtém o vizinho mais próximo usando as próprias caixas delimitadoras para calcular as distâncias entre objetos.
No seu caso, o que você quer parece ser o
<->
operador, portanto, a consulta bruta:knn = Person.objects.raw(
'SELECT * FROM myapp_person
ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
[location.x, location.y]
)[:k]
EDITAR devido à própria derpidez: Você pode omitir o
[:k]
para adicionar LIMIT 1
na consulta SQL bruta. (Não use os dois como eu fiz!) No processo de responder sua outra pergunta:Quão eficiente é ordenar por distância (tabela inteira) no geodjango , outra solução talvez seja possível:
Habilitando a
spatial indexing
e restringir sua consulta por meio de restrições lógicas (conforme explicado na minha resposta
da pergunta vinculada acima), você pode obter um KNN bem rápido consulta da seguinte forma: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]