Postgresql earthdistance - earth_box с радиусом
Пожалуйста, вы можете объяснить мне такое поведение функции earth_box... или что я делаю неправильно?
используемые данные
40.749276, -73.985643 = Empire State Building - is in my table
40.689266, -74.044512 = Statue of Liberty - is my current position in select - 8324m far from Empire State Building
мой стол
=> select id, latitude, longitude, title from requests;
id | latitude | longitude | title
----+-----------+------------+-----------------------
1 | 40.749276 | -73.985643 | Empire State Building
расстояние от Эмпайр Стейт Билдинг до Статуи Свободы
=> SELECT id, latitude, longitude, title, earth_distance(ll_to_earth(40.689266, -74.044512), ll_to_earth(latitude, longitude)) as distance_from_current_location FROM requests ORDER BY distance_from_current_location ASC;
id | latitude | longitude | title | distance_from_current_location
----+-----------+------------+-----------------------+--------------------------------
1 | 40.749276 | -73.985643 | Empire State Building | 8324.42998846164
Моя текущая позиция - Статуя Свободы, которая находится на расстоянии более 8000 м от Empire State Buildng, но выбирайте строку с идентификатором 1, даже если радиус составляет всего 5558 м! Можете ли вы объяснить мне это поведение или что-то не так?
=> SELECT id,latitude,longitude,title FROM requests WHERE earth_box(ll_to_earth(40.689266, -74.044512), 5558) @> ll_to_earth(requests.latitude, requests.longitude);
id | latitude | longitude | title
----+-----------+------------+-----------------------
1 | 40.749276 | -73.985643 | Empire State Building
версии расширений и postgresql
=> \dx
List of installed extensions
Name | Version | Schema | Description
---------------+---------+------------+-------------------------------------------------------------- cube | 1.0 | public | data type for multidimensional
cubes earthdistance | 1.0 | public | calculate great-circle
distances on the surface of the Earth plpgsql | 1.0 |
pg_catalog | PL/pgSQL procedural language
=> select version();
version
-------------------------------------------------------------------------------------------------------------------------------------- PostgreSQL 9.4beta2 on x86_64-apple-darwin13.3.0, compiled by Apple
LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn), 64-bit
спасибо нет
1 ответ
Проблема здесь в том, что earth_box получает Статутные Мили. 8324,42998846164 метра около 5,172560986623845 статутных миль
Решение: преобразовать радиус в единицу уставных миль
earth_box(ll_to_earth(40.689266, -74.044512), 5558/1.609) //doesn't return results
earth_box(ll_to_earth(40.689266, -74.044512), 9000/1.609) //does.
Согласно документу, по умолчанию радиус выражается в метрах.
Я только что протестировал, и из документации видно, что вам нужны как earth_box, так и earth_distance в вашем операторе предложения WHERE.
Итак, вам нужно использовать как earth_box, так и earth_distance вместе, чтобы получить правильные результаты.
Также в документе в описании функции earth_box сказано:
Некоторые точки в этом поле находятся дальше указанного расстояния по большому кругу от местоположения, поэтому в запрос следует включить вторую проверку с использованием earth_distance.
Итак, следующее вернет результаты
SELECT earth_distance(ll_to_earth(40.749276, -73.985643), ll_to_earth(40.689266,-74.044512)) distance
FROM (SELECT 1) test
WHERE
(earth_box(ll_to_earth(40.749276, -73.985643), 9000) @> ll_to_earth(40.689266,-74.044512))
AND earth_distance(ll_to_earth(40.749276, -73.985643), ll_to_earth(40.689266,-74.044512)) <= 9000
order by distance desc
но это не так, поскольку фактическое расстояние составляет около 8324,429988461638 метров
SELECT earth_distance(ll_to_earth(40.749276, -73.985643), ll_to_earth(40.689266,-74.044512)) distance
FROM (SELECT 1) test
WHERE
(earth_box(ll_to_earth(40.749276, -73.985643), 6000) @> ll_to_earth(40.689266,-74.044512))
AND earth_distance(ll_to_earth(40.749276, -73.985643), ll_to_earth(40.689266,-74.044512)) <= 6000
order by distance desc