因此,我正在尝试在 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
这个结果是完全错误的。事实上,这两个点相距大约 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
我的理解是这段代码——尤其是第二次调用 config.register
,应该告诉 RGeo 将点数据视为地理数据。基于这个问题,我猜我可能需要调整寄存器调用以匹配我的模式文件,所以我实际上有 4 个寄存器行的副本,涵盖 geo_type:“point”/“st_point”,以及存在/不存在没有geographic: true.
帮助。
我错过了什么/误解/做错了什么?我猜这是一个配置问题,只是不知道它是什么,不幸的是,我已经达到了我可以根据文档和教程计算出的极限——唉——有点过时了。