使用两个地址的地理编码器

Geocoder to work with two addresses

rails 4.1.3 带有 Geocoder 的应用程序 gem 在模型上具有以下属性

  t.decimal :origin_lon, :precision => 15, :scale => 10
  t.decimal :origin_lat, :precision => 15, :scale => 10
  t.point :origin_lonlat, :srid => 3857
  t.decimal :destination_lon, :precision => 15, :scale => 10
  t.decimal :destination_lat, :precision => 15, :scale => 10
  t.point :destination_lonlat, :srid => 3857

模型定义为

geocoded_by :origin, :latitude  => :origin_lat, :longitude => :origin_lon
geocoded_by :destination, :latitude  => :destination_lat, :longitude => :destination_lon

但是如果我在控制台中 运行:

Circuit.create(origin: 'avenue des Champs-Élysées, 90 Paris', destination: 'Place Mariejol, Antibes')

不用查了,是毕加索博物馆...
仅填充目标数据。如果 geocoded_by 指令的顺序颠倒并且服务器重新启动,则正在填充原始数据。很明显,在这种语法下,只能调用一次 geocoded_by

什么语法允许两个同时搜索?

问题是 geocoded_by calls geocoder_init, which only contains one set of options,所以 geocoded_by :destination 破坏了 geocoded_by :origin

def geocoder_init(options)
  unless defined?(@geocoder_options)
    @geocoder_options = {}
    require "geocoder/stores/#{geocoder_file_name}"
    include Geocoder::Store.const_get(geocoder_module_name)
  end
  @geocoder_options.merge! options
end

您可以编写自己的 ActiveRecord 挂钩来对两者进行地理编码:

class Circuit < ActiveRecord::Base
  before_save :geocode_endpoints

  private

  def geocode_endpoints
    if origin_changed?
      geocoded = Geocoder.search(origin).first
      if geocoded
        self.origin_lat = geocoded.latitude
        self.origin_lon = geocoded.longitude
      end
    end
    # Repeat for destination
  end
end

看看 geocode method to see how the gem does it, what kind of errors, it handles. etc. Unfortunately, we can't use do_lookup 因为它依赖于配置的选项而不是接受参数。