2014-06-19 53 views
1

我有,每個位置有度的緯度和經度座標位置的模式,我想有一個位置實例返回內基於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 > ? AND lat < ? AND lon > ? AND lon < ?",minlat,maxlat,minlon,maxlon) 
    end 

當我創建一個位置,並要求範圍:

l1 = Location.find_by_post_code("SW11") 

這個返回的51.4663經緯度和-0.165543我maxlat一個LON,minlat,maxlon,MINLON值均爲當我要求實在太小:

l1.in_range(10) 

maxlat = 51.466344087822264 
minlat = 51.46625591217773 
maxlon = -0.1654722301720378 
minlon = -0.1656137698279622 

所以我認爲這些值的計算是錯誤的,但是在找到更多資源時遇到了困難,有誰知道獲取最大和最小座標值的正確方法嗎?


編輯 - 隨後回答,完整的工作代碼如下:

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 > ? AND lat < ? AND lon > ? AND lon < ?",minlat,maxlat,minlon,maxlon).to_a 
    locations.each do |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) 

    a = 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 

回答

0

我認爲問題出在你的代碼沒有張貼,具體而言,to_degto_rad方法。也許你已經寫了整數除法,而不是在兩種方法中的浮點除法?請注意,在Ruby中,3/2==13/2.0==1.5

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] 
# ] 
+0

輝煌,我添加了正確修改後的代碼,非常感謝你! – JonleePeakman