1

For an example, I have a model like this

class Place < ActiveRecord::Base
    # has a "latitude" & "longitude" field
    # notice it has "max_distance" field (meter), will be different on each record
end

How can I achieve a query that given a coordinate point, will get all places within in range between distance coordinate point and max_distance field.

lat = 37.792
lng = -122.393

Place.query_in_range_by_point([lat, lng])
# will get nearest places within range "max_distance" field 

I have been looking in Geocoder & Geo-Kit gem documentation, but not found any functionality like that.

If gem above not supported the functionality, can anyone suggest another method that can solve the problem?

Thanks

dkiswanto
  • 192
  • 1
  • 2
  • 12

3 Answers3

1

I think that near functions of Geocoder can satisfy your requirement.

class Place < ActiveRecord::Base
  def self.query_in_range_by_point(lat, lng)
    self.near([lat, lng], self.max_distance)
  end
end

Geocoder document refer to this function: https://github.com/alexreisner/geocoder#for-activerecord-models

oreoluwa
  • 5,553
  • 2
  • 20
  • 27
Tai
  • 1,244
  • 9
  • 11
1

I think that the following patch can solve the problem.

Create the following file config/initializers/geokit_rails_patch.rb

module Geokit::ActsAsMappable
  module ClassMethods
    def query_in_range_by_point(options = {})
      sql = build_distance_sql(options)

      where("#{sql} <= #{table_name}.max_distance")
    end

    private

    def build_distance_sql(options)
      origin = extract_origin_from_options(options)
      units = extract_units_from_options(options)
      formula = extract_formula_from_options(options)

      distance_sql(origin, units, formula)
    end
  end
end

Then you can query like

Place.query_in_range_by_point(origin: [-23.5062855, -55.0919171])

0

Sorry I'm posting this as an answer, but the formatting is off when posting code samples in the comment section.

....

by place, I mean having the latitude, longitude, max_distance properties, because if that is the case, then you may only need

class Place < AR::Base
  ...
  def nearby_places
    Place.where.not(id: id).near([latitude, longitude], max_distance)
  end
  ...
end

To access these nearby places, just do:

place = Place.first
nearby_places = place.nearby_places
oreoluwa
  • 5,553
  • 2
  • 20
  • 27
  • i'm sorry, but it's not a "Place object" that have (latitude, longitude, and max_distance) the argument for the function is any point (latitude, longitude only) – dkiswanto Jan 20 '18 at 14:38
  • oh. would you be able to describe your use case? Perhaps, requires thinking in a different way – oreoluwa Jan 20 '18 at 14:41