Ruby on Rails では、
Model.find(:all, :origin =>[緯度,経度], :within=>10)
http://geokit.rubyforge.org/
を使うことで、DBに格納している地点情報が、注目している地点から10km以内にあることを計算できるそうです。
この計算アルゴリズムを分かりやすく説明してください。
ソースを読めばいいのでしょうが、時間が無いので、「はてな」の皆様のお力をお借りいたしたく、よろしくお願いします。
遅れました。しっかり読んでませんが・・hnagoyaさんの回答と私も同じだと思います。
実際にやって見た場合のSQLのログです。
DB:MySQL
テーブル:Points(lat、lngカラムを持っています)
script/console
Point.find(:all, :origin =>[37.792,-122.393], :within=>10)
実際に発行されたSQL
SELECT *, SQRT(POW(111.1819*(37.792-points.lat),2)+
POW(73.0397180183497*(-122.393-points.lng),2))
AS distance FROM `points` WHERE (points.lat>37.7021492524216 AND points.lat<37.8818507475784 AND points.lng>-122.50670044169 AND points.lng<-122.27929955831 AND SQRT(POW(111.1819*(37.792-points.lat),2)+
POW(73.0397180183497*(-122.393-points.lng),2))
<= 10)
一つ一つの地点で計算しるようです。
こういうのあるのですね、知りませんでした。ご質問の趣旨にあうかどうか自信がないのですが
1. 上記URLからRDOC APIへ飛んでMethodsを眺めて distance_to から呼び出されている distance_between で距離を計算していると判断。
2. Google Code Search で「distance_between geokit」を検索して
http://www.google.co.jp/codesearch?hl=ja&q=distance_between+geok...
がソースコードだろうと判断。
3. 2の31~44行目を眺めると
3s. formura=sphere の場合は、球面三角法を使って計算(こちらがdefault、地球は真球だとして計算しているらしい)
3f. formula=flat の場合は、(平面上の)三平方の定理を使って計算(ごく狭い範囲で地球の丸さを無視してよいとき用か?)
てなかんじだと思います。
なお3sについてはhatenaじゃないですが、下記が参考になるかもしれません。
有用な情報をありがとうございます。
やはり、1つ1つの地点について計算しているのですね。
formuraによって場合分けしているのは参考になりました。パクろうっと(笑)。
遅れました。しっかり読んでませんが・・hnagoyaさんの回答と私も同じだと思います。
実際にやって見た場合のSQLのログです。
DB:MySQL
テーブル:Points(lat、lngカラムを持っています)
script/console
Point.find(:all, :origin =>[37.792,-122.393], :within=>10)
実際に発行されたSQL
SELECT *, SQRT(POW(111.1819*(37.792-points.lat),2)+
POW(73.0397180183497*(-122.393-points.lng),2))
AS distance FROM `points` WHERE (points.lat>37.7021492524216 AND points.lat<37.8818507475784 AND points.lng>-122.50670044169 AND points.lng<-122.27929955831 AND SQRT(POW(111.1819*(37.792-points.lat),2)+
POW(73.0397180183497*(-122.393-points.lng),2))
<= 10)
一つ一つの地点で計算しるようです。
具体的なログを示していただきありがとうございます。参考になります。
たしかに1つずつ計算していますね。
具体的なログを示していただきありがとうございます。参考になります。
たしかに1つずつ計算していますね。