1

我正在尝试在 Jruby 文件中运行http://www.savarese.com/software/libssrckdtree-j/ 。

我的代码看起来像这样:

require 'java'
require 'libssrckdtree-j-1.0.2.jar'

GenericPoint = Java::com.savarese.spatial.GenericPoint
KDTree = Java::com.savarese.spatial.KDTree
NearestNeighbors = Java::com.savarese.spatial.NearestNeighbors

tree = KDTree.new

def generate_points(tree, size)
  size.times do
    x = rand(100)
    y = rand(100)
    point = GenericPoint.new(x, y)
    tree.put(point, point.to_s)
  end
end

generate_points(tree, 20000)


nearest = NearestNeighbors.new()
point = [1,1]

nearest.get(tree, point, 1, false)

但是,当我运行此代码时,我得到

NameError: no method 'get' for arguments (com.savarese.spatial.KDTree,org.jruby.RubyArray,org.jruby.RubyFixnum,org.jruby.RubyBoolean) on Java::ComSavareseSpatial::NearestNeighbors
  (root) at kdjava.rb:25

我没有得到,因为库的文档说要使用 get,我使用 put on tree 来表示 KDtree,它起作用了。

我想要做的是使用这个库将一系列 lat lngs 构建到一个 kd 树中,然后查询另一组 lat lngs 以查看它们在 KD 树中最近的邻居。

我在 Ruby 上还可以——但我在 Java 上很烂。我正在使用 Jruby 来利用这些更快的库。

4

1 回答 1

2

NearestNeighbor#get()的api 文档表明该方法采用 KDTree、P、int、boolean 类型的四个参数,它们都是 Java 类型。

您的错误消息表明您传入了 KDTree、RubyArray、RubyFixnum、RubyBoolean。所以,KDTree 看起来不错。我相信 JRuby 会自动将 Fixnum 和 Boolean 强制转换为适当的 Java 类型。剩下的第二个参数是你在方法需要 P 的地方传递 RubyArray。

NearestNeighbors 的文档表明 P 是泛型类型,P extends Point<Coord>. Point是一个接口。GenericPoint实现该接口。所以不要通过[1,1],尝试通过Java::com.savarese.spatial.GenericPoint.new(1,1)

编辑:

再进一步看,GenericPoint必须用Coord另一个泛型类型创建Coord extends java.lang.Comparable<? super Coord>。在 Java 中,有两种 int,原始类型int(快速)和“装箱”对象java.lang.IntegerInteger实现Comparable接口,这是GenericPoint. 运行以下命令时我没有收到任何错误:

require 'java'
require 'libssrckdtree-j-1.0.2.jar'

GenericPoint = Java::com.savarese.spatial.GenericPoint
KDTree = Java::com.savarese.spatial.KDTree
NearestNeighbors = Java::com.savarese.spatial.NearestNeighbors

def box(i)
  java.lang.Integer.new(i)
end

tree = KDTree.new

def generate_points(tree, size)
  size.times do
    x = box(rand(100))
    y = box(rand(100))
    point = GenericPoint.new(x, y)
    tree.put(point, point.to_s)
  end
end

generate_points(tree, 20000)


nearest = NearestNeighbors.new()
point = GenericPoint.new(box(1), box(1))

nearest.get(tree, point, 1, false)

关于上面的一个注释,通常在 Java 中创建一个盒装的Integer,一个使用java.lang.Integer.valueOf(int). 由于我以外的原因,这导致了使用int:时遇到的相同错误NativeException: java.lang.ClassCastException: org.jruby.RubyFixnum cannot be cast to java.lang.Number。所以我改为使用构造函数java.lang.Integer.new.

于 2012-04-06T16:55:31.253 回答