http://q.hatena.ne.jp/1224295014の関連質問です。


Ruby on Rails では、
Model.find(:all, :origin =>[緯度,経度], :within=>10)
http://geokit.rubyforge.org/
を使うことで、DBに格納している地点情報が、注目している地点から10km以内にあることを計算できるそうです。

この計算アルゴリズムを分かりやすく説明してください。
ソースを読めばいいのでしょうが、時間が無いので、「はてな」の皆様のお力をお借りいたしたく、よろしくお願いします。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2008/10/20 22:17:29
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:cuspos No.2

回答回数49ベストアンサー獲得回数10

ポイント80pt

遅れました。しっかり読んでませんが・・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)

一つ一つの地点で計算しるようです。

id:pahoo

具体的なログを示していただきありがとうございます。参考になります。

たしかに1つずつ計算していますね。

2008/10/20 22:16:48

その他の回答1件)

id:hnagoya No.1

回答回数26ベストアンサー獲得回数3

ポイント60pt

こういうのあるのですね、知りませんでした。ご質問の趣旨にあうかどうか自信がないのですが


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じゃないですが、下記が参考になるかもしれません。

http://oshiete.eibi.co.jp/qa249931.html?ans_count_asc=0

http://vldb.gsi.go.jp/sokuchi/surveycalc/main.html

id:pahoo

有用な情報をありがとうございます。

やはり、1つ1つの地点について計算しているのですね。

formuraによって場合分けしているのは参考になりました。パクろうっと(笑)。

2008/10/19 18:16:39
id:cuspos No.2

回答回数49ベストアンサー獲得回数10ここでベストアンサー

ポイント80pt

遅れました。しっかり読んでませんが・・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)

一つ一つの地点で計算しるようです。

id:pahoo

具体的なログを示していただきありがとうございます。参考になります。

たしかに1つずつ計算していますね。

2008/10/20 22:16:48
  • id:zzz_1980
    これかな?
    http://earthcode.com/blog/2006/11/hey_want_to_sort_your_query_by.html
  • id:pahoo
    情報をありがとうございます。
    いただいたソースは、2地点間の距離計算のみのようですが。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません