Ruby中两个纬度/长度的距离

时间:2012-03-26 09:08:23

标签: ruby-on-rails ruby

考虑到你有2000个lat / lng需要计算它们与另一个2000纬度/ lng成对距离的问题。即1到1.在ruby中完成这项工作的最快方法是什么。

C扩展能否更快?或者java。目前我正在使用GeoKit宝石,它对于这么多点来说有点慢。

编辑1:

此刻的时间超过30秒。

2 个答案:

答案 0 :(得分:1)

你如何使用GeoKit?在我的机器上计算2000点之间的距离需要0.016秒。

require 'benchmark'
require 'geokit'

ll_arr = 2000.times.map {|i| 
              [Geokit::LatLng.new(rand(-180..180), rand(-180...180)),
               Geokit::LatLng.new(rand(-180..180), rand(-180...180))]}

distances = []

Benchmark.bm do |x|
  x.report do 
    ll_arr.each do |ll|
      distances << ll[0].distance_from(ll[1], :units=>:kms)
    end
  end
end

10.times do |n|
  m = n * 200
  puts "ll #{m} from: #{ll_arr[m][0]} to: #{ll_arr[m][1]} distance: #{distances[m]}"
end

输出:

user     system      total        real
0.016000   0.000000   0.016000 (  0.015624)  

结果似乎合理(以公里为单位):

ll 0 from: -180,71 to: 111,164 distance: 10136.21791028502
ll 200 from: 40,-127 to: -62,-23 distance: 14567.00843599676
ll 400 from: 23,-178 to: -163,-140 distance: 16014.598170496456
ll 600 from: 85,155 to: 25,3 distance: 7727.840511097989
ll 800 from: -26,57 to: 145,-36 distance: 11384.743155770688
ll 1000 from: -111,-137 to: 5,-5 distance: 9007.969496928148
ll 1200 from: 118,-98 to: -153,179 distance: 12295.886774709148
ll 1400 from: 44,-139 to: -91,-134 distance: 15024.485920445308
ll 1600 from: 48,126 to: -37,-92 distance: 16724.015574628884
ll 1800 from: -174,-77 to: -69,75 distance: 7306.820947156828

答案 1 :(得分:0)

如果您使用PostgreSQL作为数据库,可以查看http://postgis.refractions.net/

这需要将Lat / Lng点重新加载到具有PostGIS点数据类型的数据库表中,但作为奖励,数据库现在应该能够处理边界和边界之类的形状文件。

用于查找两个geoms之间距离的SQL函数

http://postgis.refractions.net/documentation/manual-1.5/ST_Distance.html

安装

http://postgis.refractions.net/documentation/manual-1.5/ch02.html

编辑:

如果这些只存储在内存中,我想你可以使用像spawn(或滚动你自己的版本)https://github.com/tra/spawnhttps://github.com/rfc2822/spawn之类的东西将计算分成几组。由于听起来距离计算恰好在匹配对之间,因此在结束时将结果合并在一起应该非常简单(如Karel建议的那样)。

您可以在结束时将结果流回客户端(如果不需要订购 - 尽管最终订购可以在收到最终结果时在客户端完成)。