gpt4 book ai didi

mysql - 从数据库中带有纬度/经度的邮政编码进行地理搜索

转载 作者:行者123 更新时间:2023-11-29 03:03:15 25 4
gpt4 key购买 nike

我很难理解如何实现这一点,似乎有很多人问这个问题却没有答案。我有一个带有邮政编码的用户表。我创建了一个 zips 表,其中包含美国的每个邮政编码和纬度/经度。

我想做的是将两者连接起来,以便用户可以搜索其他用户。我有 Thinking Sphinx,我希望继续使用它。我想为用户提供一个用于搜索距离的复选框(5、10、25、50、100、500 英里)。结果应始终返回最近的用户。

我认为这不需要来自 Controller 或模型的代码,但是如果需要请询问,我会提供。

搜索表单:

<%= form_tag searches_path, method: :get do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= button_tag "Search", name: nil %>
</p>
<% end %>

<P><%= link_to "Advanced Search", new_search_path %><p>

<%= form_tag users_path, method: :get do %>
<%= label :zip_code, "Enter zip code: " %>
<%= text_field_tag :zip_code, params[:zip_code] %>
<% end %>

/indices/user_index.rb:

     ThinkingSphinx::Index.define :user, :with => :active_record do
# fields
indexes name, :as => :user, :sortable => true
indexes religion, zip_code, about_me, career, sexuality, children, user_smoke, user_drink, gender, ethnicity, education


# attributes
has id, created_at, updated_at
has zips.city, :as => :zip_city

has "RADIANS(zips.lat)", :as => :latitude, :type => :float
has "RADIANS(zips.lon)", :as => :longitude, :type => :float


end

用户模型:

  has_and_belongs_to_many :zips

zip 模型:

class Zip < ActiveRecord::Base
attr_accessible :city, :lat, :lon, :code, :zipcode
has_and_belongs_to_many :users

validates :code, uniqueness: true

self.primary_key = 'code'

def self.code(code)
find_by(:code => code)
end


end

用户表包含以下列:zip_code

邮政编码表包含以下列:codecitystatelatlon

最佳答案

第一步是在用户与其位置之间创建关联,以便可以从用户的位置引用该位置的 ActiveRecord。

class User < ActiveRecord::Base
belongs_to :location
attr_accessible :name
end

class Location < ActiveRecord::Base
attr_accessible :city, :latitude, :longitude, :zipcode
end

接下来,在您的索引中使用关联。

您必须为 Location 模型上的字段创建别名,以确保连接位置表。并且您必须为位置的纬度和经度添加属性:

ThinkingSphinx::Index.define :user, :with => :active_record do
# fields
indexes name

# attributes
has created_at, updated_at
has location.city, :as => :location_city
has "RADIANS(locations.latitude)", :as => :latitude, :type => :float
has "RADIANS(locations.longitude)", :as => :longitude, :type => :float

end

正如其他人已经提到的,由于地球不是平的,因此在计算位置之间的距离时需要考虑到这一点。 Haversine 函数对此很有帮助。 Thinking Sphinx 内置了它,您可以使用 :geo 对其进行过滤和排序。

例如,要查找 lat/lng 参数(以度为单位)200 公里以内的所有用户,按最近的顺序排列:

class DistanceController < ApplicationController
def search
@lat = params[:lat].to_f * Math::PI / 180
@lng = params[:lng].to_f * Math::PI / 180
@users = User.search :geo => [@lat, @lng], :with => {:geodist => 0.0..200_000.0}, :order => "geodist ASC"
end
end

对于调试,很高兴知道在 View 中您也可以引用计算的距离:

  <% @users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.location.zipcode %></td>
<td><%= user.location.city %></td>
<td><%= user.distance %></td>
</tr>

编辑:添加了有关我的工作版本的更多详细信息,为了完整起见还添加了表定义。 (MySQL,使用 db:migrate 生成,这些是 MySQL Workbench 生成的创建脚本):

CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`location_id` int(11) DEFAULT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `index_users_on_location_id` (`location_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;


CREATE TABLE `locations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`zipcode` varchar(255) DEFAULT NULL,
`latitude` float DEFAULT NULL,
`longitude` float DEFAULT NULL,
`city` varchar(255) DEFAULT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

关于mysql - 从数据库中带有纬度/经度的邮政编码进行地理搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19868384/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com