Geokit距离计算奇怪

发布于 2024-09-02 07:35:13 字数 1796 浏览 5 评论 0原文

我正在使用 Geokit 插件来计算 current_user 和其他用户之间的距离(地理编码实际上存储在配置文件模型中)。

出于测试目的,我创建了两名用户,一名位于明尼苏达州明尼阿波利斯,另一名位于明尼苏达州圣保罗。我在 IRB 会话中使用 Geokit gem 对配置文件的纬度/经度对进行地理编码。

我更改了索引视图以列出每个配置文件的名称、位置和纬度/经度对。这些值与数据库中的值匹配。

我更改了索引视图以显示 current_user 的纬度/经度对。我以每个用户身份进行身份验证,以确保 current_user 的 lat/lng 对符合预期。确实如此。

我向 Profile 模型添加了一个名为 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

我更改了 ProfileController 的 Index 操作中的查询以计算每个用户与 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 mi B (44.9444101,-93.0932742) - 8.7 m

但是,当我以用户 B (44.9444101,-93.0932742) 身份进行身份验证时,距离计算不正确:

A (44.9799654,-93.2638361) - 32.8 mi B (44.9444101,-93.0932742) - 41.1 mi

我能够验证“原始”纬度/经度对之间的距离计算:

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

我无法解释正在发生的事情。任何想法将不胜感激。

I'm using the Geokit plugin to calculate the distance between the current_user and other users (geocoding actually stored in Profile model).

For testing purpose, I created two Users, one in Minneapolis, MN and one in St. Paul, MN. I used the Geokit gem to geocode the Profiles' lat/lng pair in an IRB session.

I changed the Index view to list each Profile's name, location, and lat/lng pair. These values match the values in the database.

I changed the Index view to display the current_user's lat/lng pair. I authenticated as each User to ensure that the current_user's lat/lng pair matched expectations. It did.

I added an instance method to the Profile model, named ll, to return the lat/lng fields as LatLng object:

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

I changed the query in the ProfileController's Index action to calculate distances between each user and the 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

Finally, I changed the Index view to display the distance between the current_user and each individual user:

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

When I authenticated as user A (44.9799654,-93.2638361), the distance calculations were correct:

A (44.9799654,-93.2638361) - 0.0 mi
B (44.9444101,-93.0932742) - 8.7 m

However, when I authenticated as user B (44.9444101,-93.0932742), the distance calculations were incorrect:

A (44.9799654,-93.2638361) - 32.8 mi
B (44.9444101,-93.0932742) - 41.1 mi

I was able to verify the distance calculations between the 'raw' lat/lng pairs:

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

I'm at a loss to explain what is happening. Any ideas would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

樱花细雨 2024-09-09 07:35:13

如果你这样做会发生什么:

 @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 应该能够直接获取纬度和经度。您可能还想在调用 Profile.find(...) 之前检查 (logger.debug) 所有涉及的类型

我无法想出一个简单的转换来给出这些特定的错误,但这是我的怀疑。如果这没有帮助,您可以将生成的 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 查询中显示的内容,因为这将显示后期处理字符串转换数字。

What happens if you do:

 @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

Your error makes me suspicious that there is data rounding/conversion issues going on and the :origin should be capable of picking up the lat and lng directly. You might also want to check (logger.debug) all the types involved right before calling Profile.find(...)

I haven't been able to come up with a simple conversion that gives those particular errors, but that is my suspicion. If that doesn't help, can you add your generated sql to the output? It might be possible to figure it out what's gone wrong based on that.

Edited to add:

Craig, to do debugging of types, give:

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}")

a try when you are actually experiencing the error and then look at your development.log. (note: there might be a bug in that code because i'm just typing it into the window, but you get the idea.) Otherwise, you probably should check out what's getting displayed in the SQL query as that would show the post-string conversion numbers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文