4

休止状態の空間を使用して、ジオロケーションを車に接続します。私のカード ドメイン クラスは次のようになります。

import com.vividsolutions.jts.geom.Point
class Card {
  String name
  Point location 
}

私のプログラムは Grails にあるので、私が提供したサンプルは Groovy にあります。ここで、半径を正しく指定して半径に n キロメートルを設定する方法に関する最も重要な質問に実際には答えていない同様の投稿を見つけました。

円ジオメトリを計算する方法は次のとおりです。

  private static Geometry createCircle(double x, double y, final double RADIUS) {
    GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
    shapeFactory.setNumPoints(1000);
    shapeFactory.setCentre(new Coordinate(x, y))
    shapeFactory.setSize( (RADIUS * 2)/88.1)

    return shapeFactory.createCircle().getBoundary()
  }

円のサイズは 88.1 で除算されます。これは、おおよその寸法を取得するための単なる汚い修正ですが、それでも間違っています。

私のクエリは次のように行われます:

double radius = 40
Geometry filter = createCircle(car.location.x, car.location.y, radius)
Session session = sessionFactory.currentSession
Query q = session.createQuery("select c from Car c where within(c.location, ?) = true")
q.setParameter(0, filter, GeometryUserType.TYPE) 
q.list()

これはあまり正確ではありません。円の外にあるはずの車の一部が、このクエリから返されます。

ここに例があります。私のセンターはハンブルグで、半径は 40km です。Google マップのビジュアライゼーションを作成しました。

これが私が設定したときですradius = 40

ここに画像の説明を入力

左上に、円の外側に位置する 1 台の車がまだ描かれていることがわかります。これは当てはまりません。Googleマップで描いた円は、クエリのコードで描いた円ジオメトリと等しくないようです。

これが私が設定したときですradius = 30

ここに画像の説明を入力

右下の車が消えていることがわかりますが、これは正しいですが、左上の車はクエリに残っています。

作成した円を描くとcreateCircle、次のようになります(getCoordinates()円の座標を取得するために使用します):

ここに画像の説明を入力

半径 40km 以内のすべての車を照会するにはどうすればよいですか?

4

1 に答える 1

0

代わりに、ジオメトリ間の距離を計算してみてください。関数を使用できdwithinます ( Hibernate 空間ドキュメントを参照):

select c from Car c where dwithin(c.location, :geom, :dist) = true

または単にdistance

select c from Car c where distance(c.location, :geom) < :dist

また、距離測定を度に変換することを忘れないでください (WGS84 SRS の場合)。

編集

架空の円の中心にgeomを使用するため、ジオメトリを生成する必要はなく、距離でフィルタリングするだけです。

PD: この投稿では、度とメートルの変換の問題についての説明を見つけることができます

幸運を!。化学。

于 2015-07-28T06:23:19.560 に答える