0

My setup:

  • Ruby 2.0.0
  • Rails 3.2.12
  • most recent pg gem
  • most recent activerecord-postgis-adapter gem
  • most recent rgeo-geojson gem
  • Postgres 9.1.6
  • PostGIS 2

I've asked something similar a few days ago. (Need to convert a Boolean from Postgres (== String) to a Ruby Boolean). There I had to convert a value from a custom select to boolean. This was pretty straight forward, by just adding this to my model:

def value_name
  ActiveRecord::ConnectionAdapters::Column.value_to_boolean(self[:value_name])
end

But now I receive a value of type Point (which is a type from PostGIS). Its string representation in database looks like "0101000000EE7C3F355EF24F4019390B7BDA011940", but it has to become a (I think) RGeo::Feature::Point or maybe RGeo::Geos::CAPIPointImpl ?!

Now I looked at ActiveRecord::ConnectionAdapters::Column (http://rubydoc.info/docs/rails/ActiveRecord/ConnectionAdapters/Column), I can only find value_to_boolean and value_to_decimal.

Then I recognized that there is also ActiveRecord::ConnectionAdapters::PostgreSQLColumn (http://rubydoc.info/docs/rails/ActiveRecord/ConnectionAdapters/PostgreSQLColumn), but it doesn't seem to have any useful methods.

Thank you!

4

3 回答 3

2

是的,postgis 适配器确实有效,并提供了更优雅的解决方案。

在我的 Gemfile 中:

gem 'rails', '3.2.12'

gem 'pg'
gem 'rgeo-activerecord'
gem 'activerecord-postgis-adapter'

然后在模型中:

class MyPoint < ActiveRecord::Base
  set_rgeo_factory_for_column(:geom, RGeo::Geos.factory(srid: 4326))
  attr_accessible :geom
end

查看您的 RGeo 安装是否支持 Geos:

>> RGeo::Geos::supported?
true

这就是你得到的 - 在这种情况下模型的属性 geom RGeo::Geos::CAPIPointImpl(将根据工厂类而有所不同)。要让这个工厂正常工作,您需要在安装 RGeo 之前安装带有开发文件的 Geos。不一定是 Geos 工厂和 4326,RGeo 有工厂在纯 Ruby 中实现,在文档中找到你最好的匹配工厂类和 SRID:http ://rubydoc.info/github/dazuma/rgeo/master/index

于 2013-03-12T16:52:13.893 回答
2

我找到了一个解决方案(搜索rgeoand parse):

def my_value
  a = RGeo::WKRep::WKBParser.new
  a.parse(self[:my_value])
end

我只需要知道这是否是正确的方法。来自 Java 世界,我是这样读的:

  • For every(!) my_value: 创建一个新的 WKBParser 实例

如果是这种情况:我怎样才能只创建它的一个实例并在每次调用该方法时重用它?


或者更详细地说:自动解析器如何处理这个问题?它在哪里被调用?

我认为它是在这里创建的:https ://github.com/dazuma/activerecord-postgis-adapter/blob/master/lib/active_record/connection_adapters/postgis_adapter/spatial_column.rb (第179和181行)

但是我怎样才能在我的模型中重用它呢?

背景信息:解析器自动适用于真实表列,但我的列是在查询中创建的。


找到了正确的方法:

def my_value
  RGeo::Geos.factory.parse_wkb(self[:my_value])
end

:)

于 2013-02-27T17:46:39.090 回答
2

尝试这样的事情:

def value_name
  point_regex = /POINT \(([0-9]*\.[0-9]*) ([0-9]*\.[0-9]*)\)/
  match_data = self[:value_name].match(point_regex)
  match_data[1], match_data[2]
end

它将返回几个值 [x, y] 代表您的观点。你必须做相反的事情,即定义一个value_name=(x,y)。

于 2013-02-27T17:16:56.297 回答