4

试图了解如何使用 Geokit Rails 来让所有覆盖某个点的用户在他们的覆盖范围内。

例如,用户 A、B、C 和 D 的半径为 i > 0 km。现在假设我要查找覆盖使用 lat 和 lng 创建的地图上选定点的所有用户。因此,当我想查找某个范围内的所有记录时,这不是问题,而是我想查找在其范围内包含我的位置的所有记录

来自图像:应该返回用户 A、B、C 而不是 D,因为红点不在他的范围内。

我已经尝试过:我从上到下查看了文档,搜索了示例,但所有这些都导致在一个范围内查找记录,所以这不是我的情况。如果有人有同样的问题要解决,请分享。谢谢你。

问题的图形描述

4

2 回答 2

2

我现在有效的解决方案可能不是最好的,只是找不到其他解决方案:

  address = [lat, long]
  users.each do |u|
    if u.distance_to(address, :units => :kms) < u.distance
      tutors << t
    end
  end 

它是如何工作的:用户表有一个名为距离的字段,我在其中保留一个整数,显示用户覆盖的半径,例如:20。在进行搜索时,我从表单发送纬度和长参数以查找位置map,然后只是循环遍历用户以查找他们与该点之间的距离小于距离值的所有用户。

例如:用户 1 的范围是 20 公里,因此距离值为 20,然后检查用户 1 与地图上的点之间的距离是否小于 20,将他加载到数组中。

我不需要太多的用户来循环,因为我在之前的代码中限制了他们的数量,所以我只得到其中的几个......最大在 1 到 40 之间。

现在它有效,如果有人有更好的解决方案,请分享。

更好的解决方案:

  def find_tutors
    lat_d = Geokit::Mappable::LATITUDE_DEGREES
    km_lat = Geokit::Mappable::KMS_PER_LATITUDE_DEGREE
    kms_per_mile = Geokit::Mappable::KMS_PER_MILE

    users = User.joins(:courses).where("courses.lesson ILIKE ?", "%#{lesson}%")

    if long.present?
      users = users.where("pow((longitude - ?) * (#{lat_d} * #{kms_per_mile} * abs(cos(0.0174 * longitude))), 2) +
      pow((latitude  - ?) * #{km_lat}, 2) < pow(distance, 2)",
      long, lat)
    end

    users
  end

在上述情况下,longitudelatitude是搜索模型的属性,但也可以是任何其他属性。

于 2013-11-12T23:51:32.103 回答
2

尝试使用distance_sql方法。

我们假设问题中的 User 模型已经使用acts_as_mappable定义,并且有一个名为range的列定义了用户的范围(以公里为单位)。假设您查询中的选定位置由一个名为 Location 的模型定义,该模型也是act_as_mappable

如果您有一个名为my_location的 Location 实例,那么您可以找到范围包括该位置的所有用户,如下所示:

User.where( User.distance_sql( my_location, :kms ) + " < range" )

distance_sql方法期望其第一个参数响应latlng方法,因此acts_as_mappable的模型是理想的。如果您选择的位置只是 [lat,lng] 的数组,那么很遗憾,该方法不适用于此方法 - 您必须将其包装在一个首先响应latlng方法的类中。

于 2015-06-24T15:43:43.587 回答