从数据库中检索几何列的值时遇到问题。我保存了一个RGeo::Cartesian::PolygonImpl
实例,重新加载记录,当我检索值时,我得到一个String
而不是几何。
我的config/database.yml
有:
development:
adapter: postgis
encoding: unicode
pool: 10
timeout: 5000
schema_search_path: public
database: XXXX
username: XXXX
password: XXXX
我的表具有以下列定义:
CREATE TABLE properties
# ...
parcel geometry(Polygon,3785),
# ...
我的模型具有以下设置:
class Property < ActiveRecord::Base
set_rgeo_factory_for_column(:parcel, RGeo::Geographic.simple_mercator_factory(srid: 3785))
# ...
end
通过 Rails 控制台,我正在创建一个多边形并将其保存到 DB(为简洁起见,输出进行了删节):
2.1.5 :052 > f = Property.rgeo_factory_for_column(:parcel)
2.1.5 :053 > points_array = [{"latitude"=>49.130917114292146, "longitude"=>-122.85873269458159}, {"latitude"=>49.131504470050885, "longitude"=>-122.85873269458159}, {"latitude"=>49.131504470050885, "longitude"=>-122.85743450541838}, {"latitude"=>49.130917114292146, "longitude"=>-122.85743450541838}, {"latitude"=>49.130917114292146, "longitude"=>-122.85873269458159}]
2.1.5 :054 > points = points_array.collect {|p| f.point(p['longitude'], p['latitude'])}
2.1.5 :055 > projection = f.polygon(f.linear_ring(points)).projection
2.1.5 :056 > property = Property.find(123)
2.1.5 :057 > property.parcel = projection
=> #<RGeo::Cartesian::PolygonImpl:0xb82223c "POLYGON ((-13676571.563067732 6297104.554633035, -13676571.563067732 6297204.480123126, -13676427.049311131 6297204.480123126, -13676427.049311131 6297104.554633035, -13676571.563067732 6297104.554633035))">
2.1.5 :058 > property.save!
2.1.5 :059 > property.parcel.class
=> RGeo::Cartesian::PolygonImpl
此时,如果我得到 property.parcel
的值,我正确地得到了RGeo::Cartesian::PolygonImpl
。但是,如果我现在重新加载记录,我会得到一个字符串:
2.1.5 :060 > property.reload
2.1.5 :061 > p.parcel
=> "0103000020C90E000001000000050000009FA6047203166AC18F1B7F23840558419FA6047203166AC15956BA1E9D055841F0F49361F1156AC15956BA1E9D055841F0F49361F1156AC18F1B7F23840558419FA6047203166AC18F1B7F2384055841"
2.1.5 :062 > p.parcel.class
=> String
现在,需要注意的一件有趣的事情是,如果我在ActiveRecord::Relation
上使用#pluck
,我确实会得到RGeo多边形:
2.1.5 :069 > props = Property.where('parcel is not null').limit(1)
=> #<ActiveRecord::Relation [#<Property id: 37362, parcel: "0103000020C90E0000010000000700000050550F59F9C35EC0...">]>
2.1.5 :070 > props[0].parcel
=> "0103000020C90E0000010000000700000050550F59F9C35EC0F3C61F98209B4840F2A22041F9C35EC0698E70A32C9B484094FF2041F9C35EC0DA12B4A52C9B484048F5426AFCC35EC03C9ED6B02C9B48405079426AFCC35EC0B7EDD1AD2C9B4840E0E72F82FCC35EC0C0BA55A3209B484050550F59F9C35EC0F3C61F98209B4840"
2.1.5 :071 > props.collect(&:parcel)
=> ["0103000020C90E0000010000000700000050550F59F9C35EC0F3C61F98209B4840F2A22041F9C35EC0698E70A32C9B484094FF2041F9C35EC0DA12B4A52C9B484048F5426AFCC35EC03C9ED6B02C9B48405079426AFCC35EC0B7EDD1AD2C9B4840E0E72F82FCC35EC0C0BA55A3209B484050550F59F9C35EC0F3C61F98209B4840"]
2.1.5 :072 > props.pluck(:parcel)
=> [#<RGeo::Geographic::ProjectedPolygonImpl:0xac42e08 "POLYGON ((-123.06209398744 49.2119321971094, -123.062088281509 49.2122997569648, -123.062088281846 49.2123000268236, -123.062281194104 49.2123013542118, -123.062281193653 49.2123009944002, -123.062286898406 49.2119335335351, -123.06209398744 49.2119321971094))">]
所以我相信 Rails 在通过列访问器访问时不知道将值转换为几何体存在问题,但我不完全确定为什么会发生这种情况。
我的项目具有以下设置:
- 红宝石 2.1.5
- 导轨 4.1.8
- activerecord-postgis-adapter 2.2.1
- rgeo 0.3.20
- rgeo-activerecord 2.0.0
- 邮政 9.3.5
- 后地理信息系统 2.1.4
升级一个rails项目之后,我也一直在为activerecord-postgis-adapter
而苦苦挣扎。无论您使用什么库,Rails 中的 PostGIS 数据似乎都是一头挑剔的野兽(我现在在这个问题上打开了大约 3 打浏览器选项卡)。我注意到一个容易忽视的问题是,如果 rgeo
gem 在构建时找不到 geos 库。您可以从 rails 控制台对此进行测试:
require 'rgeo'
RGeo::Geos.supported?
如果返回 false,则可能会阻止 postgis 适配器将该值解析回几何类型。请参阅 https://stackoverflow.com/a/31170056/83743 了解如何解决此问题。