PostGSIで半径nメートルの範囲内に存在するオブジェクトを取得するSQLを書きたいってことがあってメートルから度へ変換するにはどうするか調べていたことを書きます。
へー、簡単だよ!
おお!簡単簡単・・・こんな感じにすりゃいいんじゃ・・・
select * from hogehoge_tbl where ST_DWithin(position, GeomFromText('POINT(30.1234 140.5678)', 4326), ????)
※ hogehoge_tblのpositionフィールドが座標のフィールドだとします。
あれれ??4326って単位が度、度ってどういうこと??メートルに直すのってどうすんの??えぇ〜!!
例えば半径500mの範囲内にあるって表現したいとき、傍目には下記図の左側なんだけど、実はSQL上では下記図の右側を考えなくてはならない。
ううーー算数が苦手な自分に訳の分からん計算させるとは・・・うぬーー・・・orz...
地球の円周から1度の距離数を算出
地球の円周・・・グーグル様にお願いしたら検索結果ではなくこんな画面が!これは間違いなく信じていい!そう思っていいよね!おれ!
この距離を360°で割ると、1度あたりの距離数が求められます。
40,075(km) ÷ 360 ≒ 111.319(km)
おお!地球の円周1度あたり111.319Kmあるってことですか!結構な距離ありますね。なるほど!図にするとこんな感じです。
まだまだ大きくて扱いづらいので秒の距離を求めます
1度は3600秒ですので、111.319Kmを3600で割れば1秒あたりの距離が求められます。その際、Kmだとわかりづらいので1000をかけてメートル単位にします。
(111.319(km) × 1000) ÷ 3600 ≒ 30.9219444...
1秒あたり約30.92194mまでわかりました。図にするとこんな感じです。
30m単位だと使いづらいので、1メートルあたりの秒数にしてあげます。
1 ÷ 30.92194 ≒ 0.0323394
これで1メートルあたりの秒数が求められました。
例題の500メートル範囲にするには
1メートルあたりの秒数が求められましたので、あとは500をかけて、秒数→度数変換ですので3600で割れば半径nメートル範囲内の度数が分かります。
(0.0323394 × 500)÷ 3600 = 0.0044915833333333
あとはSQLに使うだけです。
select * from hogehoge_tbl where ST_DWithin(position, GeomFromText('POINT(30.1234 140.5678)', 4326), 0.004491583)