LoginSignup
5
2

More than 5 years have passed since last update.

Haversine formulaを使ってローケーションベースでソートする

Posted at

longitude と latitudeを使って、ある地点からのロケーションベースのソートをしたいときってありますね。
そこで使えそうなのが

Haversine formulaという公式です。
http://en.wikipedia.org/wiki/Haversine_formula

image
これが最終的に
image
のように展開できます。(式の展開などはめんどくさいので省略します。。。)

この公式をpostgresql上で実際のサンプルデータを使ってみてみると

select id,name,latitude,longitude from cities;

id name latitude longitude
3 Kuala Lumpur 3.146685 101.686656
1 Singapore 1.283333 103.833333
4 Bangkok 13.787395 100.524502
5 Hong Kong 22.27833 114.15889
6 Jakarta -6.193806 106.843314
2 Manila 14.603352 120.984682
7 Taipei 25.105495 121.557441

このサンプルデータを使い、Kuala Lumpurに近いポイントでソートしてみます。

\set lat  3.046685
\set lng  100.686656

SELECT 
    id,name,latitude,longitude , 
    3956 * 2 * 
    ASIN(
        SQRT(
            POWER(SIN( (:lat - abs(cities.latitude)) * pi()/180 / 2), 2 ) + COS(:lat * pi()/180) * COS(cities.latitude * pi()/180) * POWER(SIN((:lng - cities.longitude) * pi()/180 / 2)
        , 2)
        )
    ) 
    AS distance 
    from cities order by distance;
id name latitude longitude distance
3 Kuala Lumpur 3.146685 101.686656 69.2892623017496
1 Singapore 1.283333 103.833333 248.908449383448
6 Jakarta -6.193806 106.843314 476.126654090718
4 Bangkok 13.787395 100.524502 741.677180652493
2 Manila 14.603352 120.984682 1595.9777030627
5 Hong Kong 22.27833 114.15889 1605.53830449593
7 Taipei 25.105495 121.557441 2059.91627144258

このような結果になりました。
*パフォーマンス等は考慮してません。。。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2