PostgreSQL纬度经度查询

Ida*_*dan 25 postgresql postgis

我有PostgreSQL数据库中的表latitudelongitudelocation,我试图用PostgreSQL函数执行距离查询.

我阅读了本手册的这一章:

https://www.postgresql.org/docs/current/static/earthdistance.html

但我想我错过了那里的东西.

我该怎么办?有更多的例子吗?

Ste*_*ber 38

这是使用点运算符的另一个例子:

初始设置(只需运行一次):

create extension cube;
create extension earthdistance;
Run Code Online (Sandbox Code Playgroud)

然后是查询:

select (point(-0.1277,51.5073) <@> point(-74.006,40.7144)) as distance;

     distance     
------------------
 3461.10547602474
(1 row)
Run Code Online (Sandbox Code Playgroud)

请注意,points使用LONGITUDE FIRST创建.根据文件:

点被视为(经度,纬度)而不是相反,因为经度更接近于x轴的直观概念和y轴的纬度.

这是一个糟糕的设计...但这就是它的方式.

您的输出将以英里为单位.

给出地球表面两点之间的法定距离.


str*_*kol 22

此模块是可选的,未安装在默认的PostgreSQL instalatlion中.您必须从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;
Run Code Online (Sandbox Code Playgroud)

  • 要使用KM而不是里程,请使用常量111.12和92.215替换69.1和57.3 (8认同)
  • 你能解释一下这里的数学吗?69.1和57.3代表什么? (3认同)

Mik*_*ll' 9

假设您已正确安装了地球距离模块,这将为您提供两个城市之间的英里距离.该方法使用更简单的基于点的地球距离.请注意,point()的参数是第一个经度,然后是纬度.

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
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这个答案是最好的方法。您只需要运行`CREATE EXTENSION cube';创建扩展Earthdistance;`以安装Earthdistance。 (2认同)

Thi*_*ijs 6

使用Haversine公式得到@ 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;
Run Code Online (Sandbox Code Playgroud)

输入以度为单位(例如52.34273489,6.23847),输出以米为单位.

  • 我不确定我是否同意使用“Δ”和“λ”等特殊字符是一个好主意。 (3认同)