我有latitude
和longitude
列在location
列在PostgreSQL數據庫中, 我試圖用PostgreSQL函數執行距離查詢。PostgreSQL經緯度查詢
我閱讀手冊的這一章:
https://www.postgresql.org/docs/current/static/earthdistance.html
,但我覺得我失去了一些東西在那裏。
我該怎麼做?是否有更多示例可用
我有latitude
和longitude
列在location
列在PostgreSQL數據庫中, 我試圖用PostgreSQL函數執行距離查詢。PostgreSQL經緯度查詢
我閱讀手冊的這一章:
https://www.postgresql.org/docs/current/static/earthdistance.html
,但我覺得我失去了一些東西在那裏。
我該怎麼做?是否有更多示例可用
此模塊是可選的,並未安裝在默認的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;
假設你已經正確安裝了earthdistance模塊,這會給你兩個城市之間的英里的距離。該方法使用更簡單的基於點的地球距離。請注意,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
中謝謝,此答案是執行此操作的最佳方法。你只需要運行'CREATE EXTENSION cube; CREATE EXTENSION earthdistance;'安裝earthdistance。 – sudo 2015-07-27 23:51:15
下面是使用點操作又如:
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
與經度FIRST創建。根據documentation:
因爲經度更接近直觀的x軸和緯度到y軸,所以點取經度,緯度,反之亦然。
這是可怕的設計......但是就是這樣。
得到了一個清潔比基於'earthdistance'的其他答案投票 – igorsantos07 2015-11-22 05:24:49
謝謝你,偉大的解決方案! – Bagdat 2016-06-18 19:50:58
@ strkol的回答的一個更精確的版本,使用Haversine formula
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)和輸出是在米。
你能解釋一下這裏的數學嗎? 69.1和57.3代表什麼? – jamesfzhang 2013-07-15 18:00:44
我會想象它們是用來將緯度和經度轉換爲英里的常量。 – 2013-09-24 16:05:41
要使用KM而不是英里數,請使用常量111.12和92.215來替換69.1和57.3 – 2014-06-09 23:19:30