ruby on rails - Locations in range -
i have location model each location has lat , lon coordinate in degrees, trying have location instance homecoming locations within range of specified distance based on http://www.mullie.eu/geographic-searches/:
def in_range(distance) earth_radius = 3958.75587 maxlat = self.lat + to_deg(distance / earth_radius) minlat = self.lat - to_deg(distance / earth_radius) maxlon = self.lon + to_deg(distance / earth_radius / math::cos(to_rad(self.lat))) minlon = self.lon - to_deg(distance / earth_radius / math::cos(to_rad(self.lat))) location.where("lat > ? , lat < ? , lon > ? , lon < ?",minlat,maxlat,minlon,maxlon) end
when create location , request range:
l1 = location.find_by_post_code("sw11")
this returns lat of 51.4663 , lon of -0.165543 maxlat,minlat,maxlon,minlon values far little when request:
l1.in_range(10) maxlat = 51.466344087822264 minlat = 51.46625591217773 maxlon = -0.1654722301720378 minlon = -0.1656137698279622
so think calculation these values wrong having problem finding more resources on this, know right way obtain max , min coordinate values?
edit - subsequently answered, total working code below:
class location < activerecord::base earth_radius = 3958.75587 def in_range(distance) maxlat = self.lat + rad2deg(distance / earth_radius) minlat = self.lat - rad2deg(distance / earth_radius) maxlon = self.lon + rad2deg(distance / earth_radius / math.cos(deg2rad(self.lat))) minlon = self.lon - rad2deg(distance / earth_radius / math.cos(deg2rad(self.lat))) locations = location.where("lat > ? , lat < ? , lon > ? , lon < ?",minlat,maxlat,minlon,maxlon).to_a locations.each |location| if self.distance_to(location) > distance locations.delete(location) end end locations end def distance_to(location) lat_source_rad = deg2rad(self.lat) lat_destination_rad = deg2rad(location.lat) lat_delta = deg2rad(location.lat - self.lat) lon_delta = deg2rad(location.lon - self.lon) = math::sin(lat_delta/2.0) * math::sin(lat_delta/2.0) + math::cos(lat_source_rad) * math::cos(lat_destination_rad) * math::sin(lon_delta/2.0) * math::sin(lon_delta/2.0) b = 2 * math::atan2(math::sqrt(a), math::sqrt(1.0-a)) c = earth_radius * b end private def rad2deg(rad) rad / math::pi * 180.0 end def deg2rad(deg) deg / 180.0 * math::pi end end
i think problem lies on code didn't post, specifically, to_deg
, to_rad
method. maybe have wrote integer partition instead of float partition somewhere in 2 methods? note 3/2==1
3/2.0==1.5
in ruby.
class location radius = 3958.75587 attr_accessor :lat, :lng def initialize(lat, lng) @lat = lat @lng = lng end def ranges(distance) maxlat = @lat + rad2deg(distance / radius) minlat = @lat - rad2deg(distance / radius) maxlng = @lng + rad2deg(distance / radius / math.cos(deg2rad(@lat))) minlng = @lng - rad2deg(distance / radius / math.cos(deg2rad(@lat))) [[minlat, maxlat], [minlng, maxlng]] end private def rad2deg(rad) rad / math::pi * 180.0 end def deg2rad(deg) deg / 180.0 * math::pi end end l = location.new(51.4663, -0.165543) p l.ranges(10) #=> [ # [51.32156821710003, 51.611031782899964], # [-0.39786664062357346, 0.06678064062357347] # ]
ruby-on-rails ruby
No comments:
Post a Comment