だから私は、プロジェクトのためにRailsでの位置情報ベースのプログラミングについて理解を深めようとしています。要約すると、データベース データは正しいように見えますが、Rails のインメモリ ロジックで正しい結果を得ることができません。
データベースに lonlat 列を作成しました...
add_column :bars, :lonlat, :st_point, geographic: true
私のスキーマファイルに適切なエントリを作成したのは...
t.geography "lonlat", limit: {:srid=>4326, :type=>"st_point", :geographic=>true}
そして、クエリを実行すると、正常なBar.where("ST_Distance(lonlat, 'Point(0,0)') < 10000")
結果が返されます。(私は正確さをチェックしていません。大まかな正気です)。たとえば、実行するBar.where("ST_Distance(lonlat, 'Point(0,0)') < 100").count
と 1 が返されます。これは、たまたま関連するポイントにある単一のレコードです。
しかし、レコードをロードすると...
b1 = Bar.first
b2 = Bar.second
b1.lonlat.distance(b2.lonlat)
# Result is around or below 0.009
その結果は完全に間違っています。実際、2 つのポイントは約 3000 フィート離れており、上記のカウント クエリを簡単に調べると、少なくともデータベースはこれを理解していることがわかります。
したがって、私が知る限り、問題はポイントをメモリにロードした後だけです。
RGeoのいくつかのチュートリアル/ドキュメントの指示に従ってgeography.rb
、以下の内容で名前が付けられた初期化ファイルを作成しました/config/initializers
.
RGeo::ActiveRecord::SpatialFactoryStore.instance.tap do |config|
# By default, use the GEOS implementation for spatial columns.
config.default = RGeo::Geos.factory_generator
# But use a geographic implementation for point columns.
config.register(RGeo::Geographic.spherical_factory(srid: 4326), geo_type: "point")
# Also tried the additional calls to try and get the declaration to match my schema file's column definition
config.register(RGeo::Geographic.spherical_factory(srid: 4326), geo_type: "point", geographic: true)
config.register(RGeo::Geographic.spherical_factory(srid: 4326), geo_type: "st_point")
config.register(RGeo::Geographic.spherical_factory(srid: 4326), geo_type: "st_point", geographic: true)
end
私の理解では、このコード、特に 2 番目の呼び出し は config.register
、点データを地理として扱うよう RGeo に指示する必要があります。この質問に基づいて、スキーマ ファイルに一致するように登録呼び出しを調整する必要があるかもしれないと推測しているので、実際には登録行の 4 つのコピーがあり、geo_type: "point"/"st_point" と存在/不在をカバーしています。geographic: true.
役に立たなかった。
私が見逃している/誤解している/間違っていることは何ですか? 残念ながら、ドキュメントとチュートリアルに基づいて把握できる限界に達しましたが、残念ながら、少し古くなっています。