Skip to content

Commit

Permalink
geocoded_through now works.
Browse files Browse the repository at this point in the history
  • Loading branch information
vpuzzella committed May 28, 2011
1 parent e6974cf commit 959e8dd
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 24 deletions.
4 changes: 1 addition & 3 deletions lib/geocoder/models/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ def reverse_geocoded_by(latitude_attr, longitude_attr, options = {}, &block)
def geocoded_through(assoc_name)
assoc = reflect_on_association assoc_name
# TODO: Raise an error if assoc is not a belongs_to
geocoder_init assoc.klass.geocoder_options.merge( :through => assoc,
:geocode => nil,
:reverse_geocode => nil )
geocoder_init assoc.klass.geocoder_options.merge(:through => assoc)
end

private # --------------------------------------------------------------
Expand Down
5 changes: 4 additions & 1 deletion lib/geocoder/models/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ def reverse_geocoded_by
fail
end


def geocoded_through(assoc_name)
fail
end

private # ----------------------------------------------------------------

def geocoder_init(options)
Expand Down
50 changes: 31 additions & 19 deletions lib/geocoder/stores/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,9 @@ def full_near_scope_options(latitude, longitude, radius, options)
"COS(#{latitude} * PI() / 180) * COS(#{lat_attr} * PI() / 180) * " +
"POWER(SIN((#{longitude} - #{lon_attr}) * PI() / 180 / 2), 2) ))"
options[:order] ||= "#{distance} ASC"
default_near_scope_options(latitude, longitude, radius, options).merge(
:select => "#{options[:select] || '*'}, " +
"#{distance} AS distance" +
(bearing ? ", #{bearing} AS bearing" : ""),
:having => "#{distance} <= #{radius}"
)

default_near_scope_options(latitude, longitude, radius, distance, bearing, options).
merge(:having => "#{distance} <= #{radius}")
end

##
Expand Down Expand Up @@ -156,35 +153,50 @@ def approx_near_scope_options(latitude, longitude, radius, options)

distance = "(#{dy} * ABS(#{lat_attr} - #{latitude}) * #{factor}) + " +
"(#{dx} * ABS(#{lon_attr} - #{longitude}) * #{factor})"
default_near_scope_options(latitude, longitude, radius, options).merge(
:select => "#{options[:select] || '*'}, " +
"#{distance} AS distance" +
(bearing ? ", #{bearing} AS bearing" : ""),
:order => distance
)

default_near_scope_options(latitude, longitude, radius, distance, bearing, options).
merge(:order => distance)
end

##
# Options used for any near-like scope.
#
def default_near_scope_options(latitude, longitude, radius, options)
def default_near_scope_options(latitude, longitude, radius, distance, bearing, options)
lat_attr = geocoder_options[:latitude]
lon_attr = geocoder_options[:longitude]

if through = geocoder_options[:through]
through_table_name = through.table_name

lat_attr = "#{through_table_name}.#{geocoder_options[:latitude]}"
lon_attr = "#{through_table_name}.#{geocoder_options[:longitude]}"
end

b = Geocoder::Calculations.bounding_box([latitude, longitude], radius, options)

conditions = \
["#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] +
[b[0], b[2], b[1], b[3]]

if obj = options[:exclude]
conditions[0] << " AND #{table_name}.id != ?"
conditions << obj.id
end

select = "#{options[:select] || "#{table_name}.*"}, #{distance} AS distance"
select << ", #{bearing} AS bearing" if bearing

group = columns.map{ |c| "#{table_name}.#{c.name}" }.join(',')
group << ", #{lat_attr}, #{lon_attr}" if through

{
:group => columns.map{ |c| "#{table_name}.#{c.name}" }.join(','),
:order => options[:order],
:limit => options[:limit],
:offset => options[:offset],
:conditions => conditions
}
:select => select,
:group => group,
:order => options[:order],
:limit => options[:limit],
:offset => options[:offset],
:conditions => conditions
}.merge!(through ? {:joins => through.name} : {})
end
end

Expand Down
8 changes: 7 additions & 1 deletion lib/geocoder/stores/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ def geocoded?
# Coordinates [lat,lon] of the object.
#
def to_coordinates
[:latitude, :longitude].map{ |i| send self.class.geocoder_options[i] }
[:latitude, :longitude].map do |i|
if assoc = self.class.geocoder_options[:through]
send assoc.name
else
self
end.send self.class.geocoder_options[i]
end
end

##
Expand Down

0 comments on commit 959e8dd

Please sign in to comment.