0

因此,我正在尝试在 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. 帮助。

我错过了什么/误解/做错了什么?我猜这是一个配置问题,只是不知道它是什么,不幸的是,我已经达到了我可以根据文档和教程计算出的极限——唉——有点过时了。

4

1 回答 1

0

所以在做了一些额外的实验后,我终于意外地找到了解决方案。

原来我不需要配置块。没有它,就会加载正确的默认值。重新阅读,显然文档试图涵盖另一个用例,我只是没有像我希望的那样清楚地理解它。

于 2018-04-18T19:22:42.340 回答