Module: ActiveRecord::Base::NearestNeighbor::Scopes

Included in:
ClassMethods
Defined in:
lib/active_record_nearest_neighbor/scopes.rb

Instance Method Summary collapse

Instance Method Details

#bounding_box_close_to(params) ⇒ Object


3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/active_record_nearest_neighbor/scopes.rb', line 3

def bounding_box_close_to(params)
  latitude = params[:latitude]
  longitude = params[:longitude]
  limit = params[:limit]

  # default of 10km
  distance = params[:distance] || 10000

  # If we have an object id, don't include the object in results
  not_id_subclause = params[:id] ? "id != #{params[:id]}" : ''

  where(%{ST_DWithin(#{table_name}.lonlat, ST_GeographyFromText('SRID=4326;POINT(#{longitude} #{latitude})')::geometry, #{distance})}).
    where(not_id_subclause).
  order(%{ST_Distance(
    #{table_name}.lonlat,
    ST_GeographyFromText('SRID=4326;POINT(#{longitude} #{latitude})')::geometry
  )}).
  limit(params[:limit])
end

#k_nearest_neighbor_close_to(params) ⇒ Object


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/active_record_nearest_neighbor/scopes.rb', line 23

def k_nearest_neighbor_close_to(params)
  longitude = params[:longitude]
  latitude = params[:latitude]
  limit = params[:limit]  || 'NULL'
  # If we have an object id, don't include the object in results
  not_id_subclause = params[:id] ? "WHERE(id != #{params[:id]})" : ''

  find_by_sql(
     %{WITH closest_candidates AS (
        SELECT "#{table_name}".* FROM "#{table_name}"
        #{not_id_subclause}
        ORDER BY
          #{table_name}.lonlat::geometry <->
          ST_GeographyFromText('SRID=4326;POINT(#{longitude} #{latitude})')::geometry
      )
      SELECT *
      FROM closest_candidates
      ORDER BY
        ST_Distance(
          closest_candidates.lonlat,
          ST_GeographyFromText('SRID=4326;POINT(#{longitude} #{latitude})')::geometry
        )
      LIMIT #{limit};} 
  )
end