休止状態の空間を使用して、ジオロケーションを車に接続します。私のカード ドメイン クラスは次のようになります。
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 以内のすべての車を照会するにはどうすればよいですか?