目的
自分のGPS座標と、ある地点の距離郡を計算し、近い順からソートしたい。そこで、いくつかの選択肢を調べてみました。もし、何かご存知ならアドバイスをお願いできませんでしょうか🙇
PostGIS
何が違うのか? PostGISと最新版MySQLの GIS機能を徹底比較によるとMySQLとPostGIS共にGPS座標を計算できるようだ。
開発環境
HomebrewでPostGISをインストール、利用するまで
本番環境
Amazon RDS for PostgreSQLによると、AWSはPostGISに対応している。- PostGIS: Using Geospatial Data with Rails and Django Apps によるとHerokuでも使えそうです。
参考情報
- PostGIS on Rails
- PostGISとは?
- PostgreSQLとOracleで緯度経度から半径nメートル内検索を実行してみる。
- PostGIS ActiveRecord Adapter
- activerecord-postgis-adapterでpostgisを使う
- PostGIS 2.0.0マニュアル日本語訳
- PostGISのよく使う機能をまとめた
MySQL
https://kenpg.bitbucket.org/blog/201511/29/slides20151127_rev.pdf によると出来そうで、今回の要件を満たしそうで直ぐに判断できなかったので、後回しとしました。
MySQL5.7のgeometry型を使えば使えるのではという情報を頂きました。geometry型は5.6でも使えるのですが、インデックスが貼れるのは5.7.4LABからのようです。
[Rails]Railsのバージョンを上げたことでspatial_adapterが使用できなくなりましたを参考に、activerecord-mysql2spatial-adapterを使ってみましたが、なんだかうまく行かずでした。
2年ほど、activerecord-mysql2spatial-adapterも更新が無く、mysql geometry railsなどのクエリで検索してみましたが、あまり情報がヒットせず、gem周りで解決したりするのは、この問題に対してはメジャーな方法ではないのかなと思いました。
そのため、MySQLのコードを発行するプログラムを作成して、この問題に取り組もうと思います。
例えば、このようなマイグレーションを書いてもrake db:migrate
は可能です。
class AddLatlongToShops < ActiveRecord::Migration[5.0]
def change
add_column :shops, :latlong, :geometry
end
end
ただ、db/scheme.rb
がうまく作成できなくなってしまいます。
# Could not dump table "shops" because of following StandardError
# Unknown type 'geometry' for column 'latlong'
ですので、Could not dump table “data” because of following StandardErrorなどを参考にdb/scheme.rb
をやめてdb/structure.sql
を生成するようにしましょう。
--
-- Table structure for table `shops`
--
CREATE TABLE `shops` (
...
`latlong` geometry DEFAULT NULL
...
)
MongoDB
MongoDBのGeospatialを使えば出来るかも。
参考情報
- MongoDBの地理空間インデックス・クエリ整理
- MongoDBの地理空間のインデックスを試してみる
- mongodb - Geospatial Indexing
- PostGIS vs MongoDB
- Is MongoDB more suitable than PostGIS as backend for geo-enabled Django website?
ElasticSearch
SQLで距離を計算する
緯度・経度を用いて距離を算出するSQLが参考になりそう。ただ、件数が増えると実行時間が気になります。10000件程度では問題にはならないようでした。
GeocorderでRailsアプリで簡単に位置情報を扱う はとても便利なgemです。alexreisner/geocoder/lib/geocoder/sql.rb によると上記と同様にSQLで実行しているようです。
geocodedには既知のバグとして pluckやincludesが正常に動作しない場合があるようです。
geocodedのSQLはかなり工夫されていて、素早く動作するように設計されているように感じました。
少し運用してみましたが、実際にデータが増えてくるとレスポンス速度が厳しい感じでした。特に近い距離の中に、結構多めの座標が固まってしまい、工夫しているフィルタ部分を抜けて、結構計算が働いてしまうせいかもしれません。
距離計算?クラウド
軽く見た感じだと、直ぐには見つけられ無さそうだった。