【问题标题】:Geocoding addresses with geocoder gem and PostGIS database with RGeo使用 geocoder gem 对地址进行地理编码,使用 RGeo 对 PostGIS 数据库进行地理编码
【发布时间】:2012-11-06 04:45:19
【问题描述】:

我正在尝试使用地理编码器 gem 来查找地址和坐标。我希望它与我的 PostGIS 空间数据库和 RGeo gem 一起使用,它使用 POINT 功能而不是分别保存纬度和经度值。因此,我尝试使用我的模型将地理编码器查找的结果保存到 RGeo POINT 功能中:

class Location < ActiveRecord::Base
  attr_accessible :latlon, :name, :address
  set_rgeo_factory_for_column(:latlon, RGeo::Geographic.spherical_factory(:srid => 4326))

  geocoded_by :name_and_address do |obj, results|
    if geo = results.first
      obj.latlon = Location.rgeo_factory_for_column(:latlon).point(geo.longitude, geo.latitude)
    end
  end

  after_initialize :init
  after_validation :geocode


  def init
    self.latlon ||= Location.rgeo_factory_for_column(:latlon).point(0, 0)
  end

  def latitude
    self.latlon.lat
  end

  def latitude=(value)
    lon = self.latlon.lon
    self.latlon = Location.rgeo_factory_for_column(:latlon).point(lon, value)
  end

  def longitude
    self.latlon.lon
  end

  def longitude=(value)
    lat = self.latlon.lat
    self.latlon = Location.rgeo_factory_for_column(:latlon).point(value, lat)
  end

  def name_and_address
    "#{self.name}, #{self.address}"
  end

end

我现在可以在 Rails 控制台中执行以下操作:

test = Location.new(name: "Eiffel Tower") // => #<Location id: nil, name: "Eiffel Tower", latlon: #<RGeo::Geographic::SphericalPointImpl:0x81579974 "POINT (0.0 0.0)">, created_at: nil, updated_at: nil, address: nil>
test.geocode    //  => #<RGeo::Geographic::SphericalPointImpl:0x81581ac0 "POINT (2.294254 48.858278)">

太棒了! 但是,当我想保存我的测试位置时,这会触发 :after_validation:geocode 的调用,我收到一个错误:

NoMethodError: undefined method `lon' for nil:NilClass
    from /Users/sg/rails-projects/geo_rails_test/app/models/location.rb:24:in `latitude='
    from /Users/sg/rails-projects/geo_rails_test/app/models/location.rb:7:in `block in <class:Location>'
    from /Users/sg/.rvm/gems/ruby-1.9.3-p194/gems/geocoder-1.1.2/lib/geocoder/stores/base.rb:108:in `call'
    from /Users/sg/.rvm/gems/ruby-1.9.3-p194/gems/geocoder-1.1.2/lib/geocoder/stores/base.rb:108:in `do_lookup'
    from /Users/sg/.rvm/gems/ruby-1.9.3-p194/gems/geocoder-1.1.2/lib/geocoder/stores/active_record.rb:278:in `geocode'
    from /Users/sg/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/callbacks.rb:405:in `_run__1498365873506454431__validation__51840359655181017__callbacks'
    [...]

地理编码回调似乎删除了 RGeo 对象,因此它的内置方法以及我的 getter 和 setter 方法不再可用。 为什么?有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails activerecord callback geocoding postgis


    【解决方案1】:

    这是一个该死的错字......

    它有效。我把它搁置了,也许其他人有同样的问题或更好的解决方案......

    我还添加了reverse_geocode 案例。

    现在看看它能做什么:

    1.9.3p194 :310 > loc = Location.new(name: "Vatikan")
     => #<Location id: nil, name: "Vatikan", latlon: #<RGeo::Geographic::SphericalPointImpl:0x8148add8 "POINT (0.0 0.0)">, created_at: nil, updated_at: nil, address: nil> 
    1.9.3p194 :311 > loc.save
       (0.2ms)  BEGIN
      SQL (0.6ms)  INSERT INTO "locations" ("address", "created_at", "latlon", "name", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["address", "Via Pio X, 00120, Vatican City"], ["created_at", Sat, 17 Nov 2012 19:26:59 UTC +00:00], ["latlon", #<RGeo::Geographic::SphericalPointImpl:0x81570554 "POINT (12.453389 41.902916)">], ["name", "Vatikan"], ["updated_at", Sat, 17 Nov 2012 19:26:59 UTC +00:00]]
       (0.9ms)  COMMIT
     => true 
    

    我喜欢这个! :-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-07
      • 1970-01-01
      • 2011-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多