【发布时间】:2014-06-21 01:15:26
【问题描述】:
我有一个 Location 模型,其中每个位置都有一个纬度和经度坐标,我试图让一个 Location 实例返回基于 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 的 lat 和 -0.165543 的 lon,当我请求时,我的 maxlat,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
【问题讨论】:
标签: ruby-on-rails ruby