Geokit дальность расчета странности

Я использую плагин Geokit для вычисления расстояния между current_user и другими пользователями (геокодирование фактически хранится в модели профиля).

Для целей тестирования я создал двух пользователей, одного в Миннеаполисе, Миннесота, и одного в Сент-Пол, Миннесота. Я использовал Geokit gem для геокодирования пары профилей lat/lng в сеансе IRB.

Я изменил представление "Индекс", чтобы отобразить имя каждого профиля, местоположение и пару широта / долгота. Эти значения соответствуют значениям в базе данных.

Я изменил представление Index для отображения пары lat/lng current_user. Я прошел проверку подлинности каждого пользователя, чтобы убедиться, что пара lat/lng текущего_пользователя соответствует ожиданиям. Это сделал.

Я добавил метод экземпляра в модель профиля с именем ll, чтобы возвращать поля lat/lng как объект LatLng:

def ll
  #if lat and lng fields aren't empty
  LatLng.new(self.lat,self.lng) if (!self.lat.nil? && !self.lng.nil?)
end

Я изменил запрос в действии Index в ProfileController, чтобы вычислить расстояния между каждым пользователем и current_user:

@profiles = Profile.find(:all,
  :conditions => conditions,  # set WHERE clause
  :order => order_by, # set ORDER BY clause
  :origin => current_user.profile.ll,  # calculate distance based on current_user's location
  :units => :miles  # use miles

Наконец, я изменил представление Index для отображения расстояния между current_user и каждым отдельным пользователем:

<%=h profile.location %> (<%= profile.ll %>) -
<%= profile.distance.to_f.round(1) %> mi

Когда я аутентифицировался как пользователь A (44.9799654,-93.2638361), вычисления расстояния были правильными:

A (44,9799654, -93,2638361) - 0,0 миль B (44,9444101,-93,0932742) - 8,7 м

Однако, когда я аутентифицировался как пользователь B (44.9444101,-93.0932742), вычисления расстояния были неверны:

A (44,9799654, -93,2638361) - 32,8 миль B (44,9444101,-93,0932742) - 41,1 миль

Мне удалось проверить расчеты расстояния между "необработанными" парами lat/lng:

a = LatLng.new(44.9799654,-93.2638361)
=> #<Geokit::LatLng:0x1034af778 @lat=44.9799654, @lng=-93.2638361>
>> b = LatLng.new(44.9444101,-93.0932742)
=> #<Geokit::LatLng:0x1034aab88 @lat=44.9444101, @lng=-93.0932742>
>> a.distance_to(b)
=> 8.70261379563918
>> b.distance_to(a)
=> 8.70261379563918

Я затрудняюсь объяснить, что происходит. Любые идеи были бы хорошы.

1 ответ

Решение

Что произойдет, если вы сделаете:

 @profiles = Profile.find(:all,
  :conditions => conditions,  # set WHERE clause
  :order => order_by, # set ORDER BY clause
  :origin => current_user.profile, # .ll # calculate distance based on current_user's location
  :units => :miles  # use miles

Ваша ошибка заставляет меня подозревать, что происходят проблемы с округлением / преобразованием данных и что: origin должен иметь возможность напрямую определять lat и lng. Вы также можете проверить (logger.debug) все задействованные типы непосредственно перед вызовом Profile.find (...)

Я не смог придумать простое преобразование, которое дает эти конкретные ошибки, но это мое подозрение. Если это не поможет, можете ли вы добавить свой сгенерированный sql к выводу? На этом основании можно выяснить, что пошло не так.

Отредактировано, чтобы добавить:

Крейг, чтобы делать отладку типов, выдает:

logger.debug("lat: #{current_user.profile.lat}  #{current_user.profile.lat.class.to_s} lng: #{current_user.profile.lng} #{current_user.profile.lng.class.to_s}")
logger.debug("lat: #{current_user.profile.ll.lat}  #{current_user.profile.ll.lat.class.to_s} lng: #{current_user.profile.ll.lng} #{current_user.profile.ll.lng.class.to_s}")

Попробуйте, когда вы действительно столкнулись с ошибкой, а затем посмотрите на ваш файл development.log. (примечание: в этом коде может быть ошибка, потому что я просто набираю его в окне, но вы поймете, что вам нужно.) В противном случае вам, вероятно, следует проверить, что отображается в запросе SQL, так как при этом будет отображаться числа преобразования строки.

Другие вопросы по тегам