私の現在のプロジェクトの1つとして、あなたがしようとしているものと非常によく似た何かを達成しました。考慮すべき大きな点は、モデルを保存するたびに新しいジオコーディング要求をしたくないということです。新しい地理座標を毎回取得する必要がない場合は、むしろ時間がかかり、非効率です。
また、IPアドレスから取得したジオコーディング結果は非常に不正確です。場合によってはまともな結果が得られることもありますが、多くの場合、近くの別の町にデータセンターの座標が表示されます。地域の正確さを求めている場合、IPジオコーディングの精度は、実行しようとしていることに十分対応できる可能性があります。
これは私は属性が変更されていない場合はジオコーディングをrerequestingないという問題に取り組ん方法です:
require 'us_states' # this is just an array of states and abbreviations
include Geokit::Geocoders
class Location < ActiveRecord::Base
acts_as_mappable
validates_presence_of :name, :address_1, :city, :state, :zip
validates_format_of :zip, :with => /^([0-9]{5})(-[0-9]{4})?$/
validates_inclusion_of :state, :in => US_STATES_ABRS
before_save :get_geo_coords
# request_geocoding attribute is intended to help with unit testing
attr_accessor_with_default :request_geocoding, true
private
def get_geo_coords
# if lat and lng are already defined
if self.lat && self.lng && self.id
# find existing location
l = Location.find(self.id)
# and if location params are the same as existing location
# then we do not need to request geocords again
loc_attrs = %w{address_1 address_2 city state zip}
if loc_attrs.all? {|attr| self.attribute_for_inspect(attr) == l.attribute_for_inspect(attr)}
self.request_geocoding = false
end
end
if self.request_geocoding
# Request new geocoding
loc = MultiGeocoder.geocode("#{self.address_1}, #{self.city}, #{self.state}, #{self.zip}")
if loc.success
self.lat = loc.lat
self.lng = loc.lng
else
errors.add_to_base("Unable to geocode your location. Are you sure your address information is correct?")
end
end
end
end
素晴らしい!私はこれを今すぐ動作させようとしていますが、これはたくさんの助けになります。特に、loc.successブロックが大いに役立っています。 –