1

Jruby ファイル内でhttp://www.savarese.com/software/libssrccdtree-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にput on treeを使用すると機能しました。

私がやろうとしているのは、このライブラリを使用して一連の緯度経度を kd ツリーに構築し、別の緯度経度のセットをクエリして、KD ツリー内の最も近い隣人を確認することです。

Ruby は大丈夫ですが、Java は苦手です。これらのより高速なライブラリを利用するために Jruby を使用しています。

4

1 に答える 1

2

NearestNeighbor#get()のAPIドキュメントは、メソッドがKDTree、P、int、boolean型の4つの引数を取ることを示しています。これらはすべてJava型です。

エラーメッセージは、KDTree、RubyArray、RubyFixnum、RubyBooleanを渡したことを示しています。したがって、KDTreeは問題ないように見えます。JRubyはFixnumとBooleanを適切なJavaタイプに自動的に強制変換すると思います。これにより、メソッドがPを期待するRubyArrayを渡す2番目の引数が残ります。

NearestNeighborsのドキュメントには、Pがジェネリック型であることが示されていP extends Point<Coord>ます。 Pointインターフェースです。GenericPointそのインターフェースを実装します。したがって、渡す代わりに、渡すようにして[1,1]くださいJava::com.savarese.spatial.GenericPoint.new(1,1)

編集:

もう少し詳しく見てみると、別のジェネリック型である、GenericPointを使用して作成する必要があります。Javaには、プリミティブ型(fast)と「ボックス化された」オブジェクトの2種類のintがあります。 によって必要とされるインターフェースを実装します。次のコマンドを実行してもエラーは発生しませんでした。CoordCoord extends java.lang.Comparable<? super Coord>intjava.lang.IntegerIntegerComparableGenericPoint

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 に答える