隔週連載groonga

第2回 groongaをRuby On Railsでも使ってみた ~chikamap.comの事例から

この記事を読むのに必要な時間:およそ 4 分

mroongaを使ってchikamap.comを作った地価マップ作成者です。

筆者は趣味でプログラムなどをしています。元々はWindowsをメインで使っていましたが,数年前からRubyが気になりMacへ乗り替えてRuby On Railsで色々個人的なサイトを作っています。

今回は,素人ながらgroonga,mroongaを使ってサイトを作った事例を紹介します。

chikamap.comとは

chikamap.comは中古住宅・土地購入の際に参考になる地価履歴やその周辺の公共施設・交通機関などの基本的な情報を地図から表示するというだけの簡単なサイトです。

サイトとしてはデータを表示するだけなので構築は比較的簡単な部類だと思いますが,「地図への地価履歴表示」「その周辺の公共施設,交通機関を表示」部分について位置情報としてのデータベース検索が必要になります。

地図への地価履歴表示

検索の方法はデータベースに登録してある地価の位置情報を,Google マップで表示している地図の北西の緯度経度と南東の緯度経度から,四角いエリアとしてその内側にあるデータを絞り込んで表示します。

北西・南東のポイント

北西・南東のポイント

その周辺の公共施設,交通機関を表示

この地図に表示された地価のポイントをクリックすることで,指定の半径何kmの周辺施設,交通機関を検索し表示します。

周辺施設・交通機関地図例

周辺施設・交通機関地図例

データベース自体には上のような四角いエリア内のデータを検索するような機能は元々あったりしますが,ある位置から半径何kmのデータを検索するようなデータベースの機能は作成当時の自分では見つけることができませんでした。

しかし位置情報からのデータベース検索方法を色々探している内に,このククログの記事が目に留まりました。この記事ではgroongaを使って四角いエリア内,半径何km内のデータを検索する方法が記載されており,まさに自分の必要としている機能が簡単に実現できるものでした。

groonga導入にあたってですがgroongaにはgroongaを直接使う以外に,groongaを軸として次のような関連プロダクトがあります。

rroonga

groongaをRubyから使えるようにしたもので,MySQLなどのデータベースを使わずに検索ができる。

mroonga

groongaをMySQLから使えるようにしたもので,MySQLから直接検索ができる。

groongaを直接コマンドから実行しても良いのですがchikamap.comはRuby On Railsを使って作っているため,MySQL経由でgroongaが使えればデータの登録から検索までコードがすっきりするのではないかと思い今回初めてmroongaを使ってみました。

データベースへの位置情報データ登録について

地価の情報,周辺施設・交通機関のデータについては緯度経度としてデータを保存します。これにはMySQLのデータタイプとしてpointというspatialデータタイプを使うことになります。しかし素のRailsではmigrationでエラーが出るためactiverecord-mysql2spatial-adapter gemを使っています。これを使うとt.pointのようにmigrationが書けます。

# db/migrate/xxxxxxx.rb

create_table :model_names, options: "ENGINE=mroonga" do |t|
  # point データタイプ
  t.point :location, null: false
end

データはRuby On Railsでいつもやるようにモデルを経由してsaveしていけば良いので,groongaを使うための特別な変更は必要ありません。

四角いエリアのデータ検索

データを入れた後,地図に表示されている四角いエリアでのデータは次のように検索しています。

north_west = "#{north_west_longitude} #{north_west_latitude}"
south_east = "#{south_east_longitude} #{south_east_latitude}"
ModelName.where("MBRContains(GeomFromText('LineString(#{north_west}, #{south_east})'), location)")

難しいことは抜きにして,北西と南東の緯度経度さえ分かればこれだけでそのエリア内のデータが抽出できとても簡単です。

Google マップAPIのgetBounds()から表示中の南西と北東の緯度経度(south-west and north-east corners)が取得できます。これを北西・南東の緯度経度へ置き換えて使っています。

著者プロフィール

地価マップ作成者(ちかまっぷさくせいしゃ)

趣味プログラマ。株式会社クリアコード須藤さんがgroongaメーリングリスト,twitterで「groonga利用事例をWebの記事にしてもいいよと言う方は連絡してください」と呼びかけられていたのが目に留まり,今回記事の執筆に参加させてもらいました。

コメント

コメントの記入