Запрос долготы долготы PostgreSQL
У меня есть столбцы latitude
и longitude
в таблице location
в базе данных PostgreSQL,
и я пытаюсь выполнить запрос расстояния с помощью функции PostgreSQL.
Я прочитал эту главу руководства:
https://www.postgresql.org/docs/current/static/earthdistance.html
но я думаю, что там что-то не хватает.
Как мне это сделать? Есть ли еще примеры доступных
Ответы
Ответ 1
Этот модуль является необязательным и не установлен в стандартном instalatlion PostgreSQL. Вы должны установить его из каталога contrib.
Вы можете использовать следующую функцию для вычисления приблизительного расстояния между координатами (в милях):
CREATE OR REPLACE FUNCTION distance(lat1 FLOAT, lon1 FLOAT, lat2 FLOAT, lon2 FLOAT) RETURNS FLOAT AS $$
DECLARE
x float = 69.1 * (lat2 - lat1);
y float = 69.1 * (lon2 - lon1) * cos(lat1 / 57.3);
BEGIN
RETURN sqrt(x * x + y * y);
END
$$ LANGUAGE plpgsql;
Ответ 2
Вот еще один пример использования точечного оператора:
create extension cube;
create extension earthdistance;
select (point(-0.1277,51.5073) <@> point(-74.006,40.7144)) as distance;
distance
------------------
3461.10547602474
(1 row)
Обратите внимание, что points
создаются с LONGITUDE FIRST. В документации :
Точки берутся как (долгота, широта), а не наоборот, потому что долгота ближе к интуитивной идее оси x и широты по оси y.
Какой ужасный дизайн... но так, как есть.
Ответ 3
Предполагая, что вы правильно установили модуль заземления, это даст вам расстояние в милях между двумя городами. Этот метод использует более простые наземные расстояния на основе точек. Обратите внимание, что аргументы точки() - это первая долгота, затем широта.
create table lat_lon (
city varchar(50) primary key,
lat float8 not null,
lon float8 not null
);
insert into lat_lon values
('London, GB', 51.67234320, 0.14787970),
('New York, NY', 40.91524130, -73.7002720);
select
(
(select point(lon,lat) from lat_lon where city = 'London, GB') <@>
(select point(lon,lat) from lat_lon where city = 'New York, NY')
) as distance_miles
distance_miles
--
3447.58672105301
Ответ 4
Более точная версия ответа @strkol, используя Формула Хаверсина
CREATE OR REPLACE FUNCTION distance(
lat1 double precision,
lon1 double precision,
lat2 double precision,
lon2 double precision)
RETURNS double precision AS
$BODY$
DECLARE
R integer = 6371e3; -- Meters
rad double precision = 0.01745329252;
φ1 double precision = lat1 * rad;
φ2 double precision = lat2 * rad;
Δφ double precision = (lat2-lat1) * rad;
Δλ double precision = (lon2-lon1) * rad;
a double precision = sin(Δφ/2) * sin(Δφ/2) + cos(φ1) * cos(φ2) * sin(Δλ/2) * sin(Δλ/2);
c double precision = 2 * atan2(sqrt(a), sqrt(1-a));
BEGIN
RETURN R * c;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Вход находится в градусах (например, 52.34273489, 6.23847), а выход - в метрах.