postgreSQLデータベースのlatitude
テーブルにlongitude
列とlocation
列があり、PostgreSQL関数で距離クエリを実行しようとしています。
マニュアルのこの章を読みました:
https://www.postgresql.org/docs/current/static/earthdistance.html
でも私はそこに何かが足りないと思います。
どうすればいいですか?利用可能な他の例はありますか
このモジュールはオプションであり、デフォルトの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;
次に、ポイント演算子を使用した別の例を示します。
初期設定(1回だけ実行する必要があります):
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軸の直感的な考え方に近いため、ポイントは(経度、緯度)として解釈され、その逆は解釈されません。
それはひどいデザインです...しかし、それはそうです。
あなたの出力はマイルになります。
地球表面の2点間の距離を法定マイル単位で示します。
Earthdistanceモジュールを正しくインストールしたとすると、2つの都市間の距離がマイル単位で表示されます。この方法では、より単純な点ベースの地球距離を使用します。 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
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;
入力は度単位(52.34273489、6.23847など)で、出力はメートル単位です。