5

stackoverflow の読者の皆様へ

現在、座標に基づいて特定のアイテムをロードする必要があるアプリケーションに取り組んでいます。例: 座標 x またはその 15 km 以内にあるすべてのショップが必要です。

私はこの Web アプリケーションを Java EE 6 で構築しており、Postgres データベースへのデータ永続化のために Hibernate 3.3 を使用しました。いくつかの調査の後、Hibernate-Spatial が私の目標を達成する可能性があることを発見しました。Postgis をインストールし、Hibernate-Spatial を実行しています。

私は Hibernate 3.3、Hibernate-Spatial 1.0、PostgreSQL 9.2、および postgis-jdbc 1.3.3 を使用しています。

場所フィールドを持つエンティティを作成しました:

@Column(columnDefinition = "Geometry", nullable = true) 
@Type(type = "org.hibernatespatial.GeometryUserType")
private Point location;

最初は、円を作成し、基本的に円内にあるすべての点を照会できると考えていました。でもこれが思ったより難しそうです。Hibernate-Spatial を使用するという間違った選択をしたと思い始めているほど難しいです。

私の質問は、Hibernate-Spatial を使用して特定の境界内のすべてのポイントを照会することが可能かどうかです (座標 x と y はそこから km です)。

私の要件を解決する他の可能性にも興味があります。以下の可能性を考えてみました。

  • PostgreSQL でネイティブ クエリを使用し、それらの結果をエンティティにマップして、アプリケーションの他の部分で使用します (基本的に Hibernate-Spatial を削除し、ネイティブ クエリを使用します)。
  • Hibernate-Search に切り替え、Lucene を使用してタスクを実行します。
  • まったく別のもの

Hibernate-Spatial で自分の希望を達成する方法、または別の方法で要件を達成する方法の例を教えてください。

4

3 に答える 3

7

PostgreSQL/PostGIS ダイアレクトの場合、Hibernate Spatial はこのdwithin機能をサポートしています。

boolean dwithin(Geometry, Geometry, double)- ジオメトリが互いに指定された距離内にある場合は true を返します

Hibernate Spatial チュートリアルを言い換えると、クエリは次のようになります。

String wktCenterPoint = "POINT(10 15)"
Geometry centerPoint = wktToGeometry(wktCenterPoint);    
...
Query query = em.createQuery("select e from Event e where dwithin(e.location, :centerPoint, 15) = true", Event.class);
...

これにより、中心点から 15 単位以内のすべてのイベントが返されます。

ただし、で指定された距離dwithinは、必ずしもキロメートルではなく、基礎となるデータセットと同じ単位になります。 データセットの単位がメートルの場合、距離はメートルとして扱われます。

データセットが緯度経度の場合、距離は度になります。この場合、検索距離が短く (15 Km は小さい)、低緯度にいる場合は、Km を 0.009 と近似できます。これにより、赤道で完全な検索円が得られますが、北または南に移動すると、この円は長軸が南北を指す楕円に変わります。+/- 60 度の緯度では、楕円は幅の 2 倍の高さになります。明らかに理想的ではありませんが、あなたの状況ではうまくいくかもしれません。

もう 1 つの方法は、データセットを再投影し、メートル単位の投影されたデータセットとして PostgreSQL に保存することです。大縮尺でマップに表示すると、データが歪められますが、検索は期待どおりに機能します。

于 2013-05-18T16:14:22.800 に答える
3

上記の答えは正しくありません。その引数で表される距離はキロメートル単位ではありません (十分に高い緯度で作業を行っている場合、正確にメートルまたはキロメートルに変換することはできません)。経度緯度座標で空間関数を使用すると、マップを正距円筒図法に効果的に押しつぶしてから、そこで計算を行うことになります。

DWITHIN は球体の計算を行うことができますが、地理データを提供する場合に限り、測定単位としてメートルを受け入れます。

Hibernate Spatial は地理的タイプをサポートしていません(このバグは 3 年間解決されていないため、息を止めないでください)。

多角形の領域を使用している場合、現在地 (赤道に近いほど良い) とチェックしている領域のサイズに応じて、座標の計算方法による歪みは、幾何学でかなり最小限になります。座標。

したがって、多角形の領域は、多少の歪みがあれば多かれ少なかれ問題なく機能します。

簡単に言うと、Hibernate Spatial は、地理データを保存して操作を実行する簡単な方法をサポートしていません。データをプロジェクションとして保存し、その上で基本的なデカルト計算を行う、より高度で難しい方法をサポートしています。

編集:明確化された@lreederの更新された回答を参照してください。

于 2013-12-13T23:51:37.783 に答える