Использование geoDjango, в чем разница между
myObj.objects.filter(point__dwithin(...etc.))
а также
myObj.objects.filter(point__distance_lt(...etc.))
?
Это одно и то же или немного разные вещи?
Использование geoDjango, в чем разница между
myObj.objects.filter(point__dwithin(...etc.))
а также
myObj.objects.filter(point__distance_lt(...etc.))
?
Это одно и то же или немного разные вещи?
Хорошо, я провел небольшое исследование, но не знаю, полезны ли результаты;)
Я просмотрел модульные тесты которые они используют для проверки запросов к БД, но они не дают реальных подсказок (мне).
Я попытался сравнить сгенерированный SQL:
У меня уже есть гео-приложение, использующее базу данных PostgreSQL. Когда я выполняю этот запрос с помощью __distance_lt
:
Place.objects.filter(location__distance_lt=(p.location, D(km=1))).query.as_sql()
Я получаю этот сгенерированный SQL:
SELECT (some_fields_here)
FROM "places_place"
WHERE ST_distance_sphere("places_place"."location", %s) < 1000.0
Когда я пытаюсь сделать то же самое с __dwithin
, я получаю сообщение об ошибке:
Place.objects.filter(location__dwithin=(p.location, D(km=1))).query.as_sql()
TypeError: Only numeric values of degree units are allowed on geographic DWithin queries.
Поэтому мне пришлось изменить запрос, чтобы не использовать объект D
:
Place.objects.filter(location__dwithin=(p.location, 1)).query.as_sql()
что приводит к
SELECT (some fields here)
FROM "places_place"
WHERE ST_DWithin("places_place"."location", %s, 1)
Обзор:
__dwithin
– принимает значения градусов в качестве параметра расстояния.
– использует функцию ST_DWithin
SQL.
__distance_lt
— может принимать другие значения расстояния ;).
— использует функцию ST_distance_sphere
SQL.
Кстати, я получаю разные результаты с обоими запросами, но я думаю, это в основном из-за того, что я не знаю, какое значение «степени» использовать.
dwithin
теперь принимает удаленные объекты. Возможно, данное сообщение об ошибке было неверным. Я могу только предположить, что это изменилось за эти годы. Я обновлю свой ответ. Спасибо!
- person Felix Kling; 27.05.2013