使用数据库中存储的纬度和经度,根据距离获取结果

问题描述

|| 我有一个用户模型,每个用户的表中都存储着纬度和经度。我想以给定的纬度和经度获取30公里范围内的所有用户。任何使用表中的经度和纬度来计算距离的插件
id   name   latitude  longitude
 1   abc    43.56     56.34
 2   xyz    46.34     57.87
 3   mno    50.34     23.56
假设这是我的表值(它只是一个示例数据。)。我想从给定海拔高度(30.89,56.45)提取30公里范围内的所有用户     

解决方法

        思维狮身人面像可以根据经纬度的距离进行搜索,排序和过滤:http://freelancing-god.github.com/ts/en/geosearching.html     ,        有漂亮的Geokit gem可以将此方法添加到模型中:
Store.find(:all,:origin =>[37.792,-122.393],:within=>10)
甚至
Store.find(:all,:origin=>\'100 Spear st,San Francisco,CA\',:within=>10)
    ,        利用Wicked发布的Movable-Type脚本的帮助,我计算出了两点之间的距离(使用Active记录中具有lat,lng属性的方法):
def calc_distance(origin)
  radius = 6371
  lat1 = to_rad(origin[0])
  lat2 = to_rad(self.lat)
  lon1 = to_rad(origin[1])
  lon2 = to_rad(self.lng)
  dLat = lat2-lat1   
  dLon = lon2-lon1

  a = Math::sin(dLat/2) * Math::sin(dLat/2) +
       Math::cos(lat1) * Math::cos(lat2) * 
       Math::sin(dLon/2) * Math::sin(dLon/2);
  c = 2 * Math::atan2(Math::sqrt(a),Math::sqrt(1-a));
  d = radius * c
end

def to_rad angle
  angle * Math::PI / 180 
end
Geokit非常健壮,但我只需要计算距离,加上Geokit需要非sqlite数据库     ,        试试这个链接。有此方法的详细说明。 http://www.movable-type.co.uk/scripts/latlong.html 另外,我在网上找到了这种C#算法。希望对您有所帮助。
class DistanceAlgorithm
{
    const double PIx = 3.141592653589793;
    const double RADIO = 6378.16;

    /// <summary>
    /// This class cannot be instantiated.
    /// </summary>
    private DistanceAlgorithm() { }

    /// <summary>
    /// Convert degrees to Radians
    /// </summary>
    /// <param name=\"x\">Degrees</param>
    /// <returns>The equivalent in radians</returns>
    public static double Radians(double x)
    {
        return x * PIx / 180;
    }

    /// <summary>
    /// Calculate the distance between two places.
    /// </summary>
    /// <param name=\"lon1\"></param>
    /// <param name=\"lat1\"></param>
    /// <param name=\"lon2\"></param>
    /// <param name=\"lat2\"></param>
    /// <returns></returns>
    public static double DistanceBetweenPlaces(
        double lon1,double lat1,double lon2,double lat2)
    {
        double dlon = lon2 - lon1;
        double dlat = lat2 - lat1;

        double a = (Math.Sin(dlat / 2) * Math.Sin(dlat / 2)) + Math.Cos(lat1) * Math.Cos(lat2) * (Math.Sin(dlon / 2) * Math.Sin(dlon / 2));
        double angle = 2 * Math.Atan2(Math.Sqrt(a),Math.Sqrt(1 - a));
        return angle * RADIO;
    }