--- layout: old_post title: Rails:座標計算用のプラグイン GeoKit permalink: /tatsuya/show/262-rails-geokit --- Web 2.0 Technologies: GeoKit: a plugin for location-based Rails apps

Rails用に座標計算をやってくれるプラグインGeoKitてのが出たそうな、機能としては

面白そうなのでちょっと試してみる。インストールはいつも通りgemで

ruby script/plugin install svn://rubyforge.org/var/svn/geokit/trunk

ほんで適当なモデルを作る

ruby script/generate scaffold_resource Store lat:float lng:float
rake migrate

できた/model/storeを修正後、script/consoleで試してみる。

class Store < ActiveRecord::Base
  acts_as_mappable
end

経度/緯度で指定した位置から指定距離内をfind

>> Store.find(:all, :lat=>9.0, :lng=>9.0, :conditions=>'distance<70')
=> [#<Store:0x47e7da0 @attributes={"lng"=>"8", "id"=>"4", "lat"=>"9", "distance", "68.315811587408"}>]

SELECT *,(ACOS(COS(0.15707963267949)*COS(0.15707963267949)*COS(RADIANS(lat))*COS(RADIANS(lng))+COS(0.15707963267949)*SIN(0.15707963267949)*COS(RADIANS(lat))*SIN(RADIANS(lng))+ SIN(0.15707963267949)*SIN(RADIANS(lat)))*3963) AS distance FROM stores WHERE ((ACOS(COS(0.15707963267949)*COS(0.15707963267949)*COS(RADIANS(lat))*COS(RADIANS(lng))+COS(0.15707963267949)*SIN(0.15707963267949)*COS(RADIANS(lat))*SIN(RADIANS(lng))+SIN(0.15707963267949)*SIN(RADIANS(lat)))*3963)<70)

おー凄いSQL。。このSQL読む元気ないけど、まあsin, cos, tanで計算してると。

住所を文字列で指定、一定距離内をfind

>>Store.find(:all, :origin=>'100 Spear st, San Francisco, CA', :conditions=>'distance<10')

Google geocoding. Address: 100 Spear st, San Francisco, CA. Result:

SELECT *, (ACOS(COS(0.659604046252148)*COS(-2.13617795307338)*COS(RADIANS(lat))*COS(RADIANS(lng))+ COS(0.659604046252148)*SIN(-2.13617795307338)*COS(RADIANS(lat))*SIN(RADIANS(lng))+ SIN(0.659604046252148)*SIN(RADIANS(lat)))*3963) AS distance FROM stores WHERE ( (ACOS(COS(0.659604046252148)*COS(-2.13617795307338)*COS(RADIANS(lat))*COS(RADIANS(lng))+ COS(0.659604046252148)*SIN(-2.13617795307338)*COS(RADIANS(lat))*SIN(RADIANS(lng))+ SIN(0.659604046252148)*SIN(RADIANS(lat)))*3963)<10)

住所の文字列をGoogleのGeocodingAPIで緯度・経度に直して、同じように計算?SQL凄い

サンフランシスコとロスアンジェルスの距離

>> cisco=GeoKit::Geocoders::YahooGeocoder.geocode('100 Spear st, San Francisco, CA')
>> losAngeles=GeoKit::Geocoders::YahooGeocoder.geocode('2126 S Central Ave, Los Angeles, CA')
>> p losAngeles.distance_from(cisco, :units=>:kms)
561.502467660011

このあたり日本の住所取れるかどうかはGoogle/YahooのAPI次第ってことだよね?あとで調べるてみるかも、みないかも。