7

lat()RGeo は、getter メソッドやlon()、POINT オブジェクトから緯度と経度の値を取得するなど、POINT 機能用の組み込みメソッドを提供します。残念ながら、これらはセッターとして機能しません。例えば:

point = RGeo::Geographic.spherical_factory(:srid => 4326).point(3,5)     // => #<RGeo::Geographic::SphericalPointImpl:0x817e521c "POINT (3.0 5.0)">

私がすることができます:

point.lat      // => 5.0
point.lon      // => 3.0

しかし、私はできません:

point.lat = 4    // => NoMethodError: undefined method `lat=' for #<RGeo::Geographic::SphericalPointImpl:0x00000104024770>

セッターメソッドの実装方法に関する提案はありますか? モデルでそれを行うか、フィーチャ クラスを拡張しますか?

4

3 に答える 3

32

私はRGeoの作成者なので、この回答は信頼できるものと見なすことができます。

要するに、これを行うことは避けてください。RGeoオブジェクトは、不変オブジェクトであることが意図されているため、意図的にセッターメソッドを持っていません。これは、キャッシュしたり、ハッシュキーとして使用したり、スレッド間で使用したりできるようにするためです。RGeoの計算の中には、フィーチャオブジェクトの値が変更されないことを前提としているため、このような変更を行うと、予期しない予期しない結果が生じる可能性があります。

本当に「変更された」値が必要な場合は、新しいオブジェクトを作成します。例えば:

p1 = my_create_a_point()
p2 = p1.factory.point(p1.lon + 20.0, p2.lat)
于 2012-11-27T07:13:28.610 に答える
2

もっとエレガントな解決策があるかもしれませんが、うまくいくものを見つけました。

私のLocationモデルでは、次のメソッドを追加しました。

  after_initialize :init


  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
于 2012-11-17T18:29:26.583 に答える
0

私は自分のモデルで次のようなことをしました:

class MyModel < ActiveRecord::Base

  attr_accessor :longitude, :latitude
  attr_accessible :longitude, :latitude

  validates :longitude, numericality: { greater_than_or_equal_to: -180, less_than_or_equal_to: 180 }, allow_blank: true
  validates :latitude, numericality: { greater_than_or_equal_to: -90, less_than_or_equal_to: 90 }, allow_blank: true

  before_save :update_gps_location

  def update_gps_location
    if longitude.present? || latitude.present?
      long = longitude || self.gps_location.longitude
      lat = latitude || self.gps_location.latitude
      self.gps_location = RGeo::Geographic.spherical_factory(srid: 4326).point(long, lat)
    end
  end
end

次に、次のように位置を更新できます。

my_model.update_attributes(longitude: -122, latitude: 37)

私のアプリではデータを読み取る必要はなく、書き込むだけなので、after_initialize ブロックに経度/緯度をロードしませんでした。ただし、簡単に追加できます。

検証のためのこの回答の功績。

于 2013-05-10T22:22:53.700 に答える