我正在尝试在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,并且我使用了树上的KDtree并且它有效。
我想要做的是使用这个库在kd树中构造一系列lat lngs,然后查询另一组lat lngs以查看KD树中最近的邻居。
我对Ruby很好 - 但我很擅长Java。我正在使用Jruby来利用这些更快的库。
答案 0 :(得分:2)
api documentation for NearestNeighbor#get()表示该方法采用KDTree,P,int,boolean类型的四个参数,它们都是Java类型。
您的错误消息表明您传入了KDTree,RubyArray,RubyFixnum,RubyBoolean。所以,KDTree看起来不错。我相信JRuby会自动将Fixnum和Boolean强制转换为适当的Java类型。这使得第二个arg传递给RubyArray,方法需要P。
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>
是另一种通用类型int
。在Java中,有两种类型,基本类型java.lang.Integer
(快速)和“盒装”对象Integer
。 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)
需要该接口。运行以下内容时没有出现任何错误:
Integer
关于上述内容的说明,通常在Java中创建一个盒装int
,其中一个使用java.lang.Integer.valueOf(int)
。出于我之外的原因,这导致了使用NativeException: java.lang.ClassCastException: org.jruby.RubyFixnum cannot be cast to java.lang.Number
:java.lang.Integer.new
时出现的相同错误。所以我改为使用构造函数{{1}}。