Получать результаты на основе расстояния, используя широту и долготу, хранящиеся в базе данных - PullRequest
0 голосов
/ 12 июня 2011

У меня есть модель пользователя, и у каждого пользователя есть широта и долгота, хранящиеся в таблице. Я хочу выбрать всех пользователей в диапазоне 30 км с заданной широтой и долготой. Любой плагин для расчета расстояния, используя широту и долготу из таблицы.


id   name   latitude  longitude

 1   abc    43.56     56.34

 2   xyz    46.34     57.87

 3   mno    50.34     23.56

Предположим, что это мои табличные значения (это просто пример данных). Я хочу выбрать всех пользователей в диапазоне 30 км с заданной высоты, например (34.89, 56.45)

Ответы [ 4 ]

3 голосов
/ 13 июня 2011

Существует прекрасный Geokit драгоценный камень, который добавляет этот метод к вашим моделям:

Store.find(:all, :origin =>[37.792,-122.393], :within=>10)

или даже

Store.find(:all, :origin=>'100 Spear st, San Francisco, CA', :within=>10)
1 голос
/ 02 августа 2011

С помощью справки из Скриптов подвижного типа , опубликованных Wicked, я сделал это для вычисления расстояния между 2 точками (используйте метод в активной записи с атрибутами 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 требует non sqlite db

1 голос
/ 12 июня 2011

Мозговой сфинкс имеет поиск, сортировку и фильтрацию по расстоянию от широты и долготы: http://freelancing -god.github.com / ts / en / geosearching.html

0 голосов
/ 12 июня 2011

Попробуйте эту ссылку.Существует подробное объяснение этого подхода.

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;
    }
...