web-dev-qa-db-ja.com

lat / longをJTSに変換しますか?

ジオ検索のためにHibernateSpatialをJPAと統合しようとしています。私は公式サイトで tutorial を参照しています(私はhibernatespatialとは関係ありません)。

残念ながら、このチュートリアルでは、緯度と経度のペアからPointインスタンスを作成する方法については説明していません。ここでこれを実行しようとしていますが、これが緯度と経度のペアをJTSポイントインスタンスに変換する正しい方法であるかどうかはまだわかりません。

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.hibernate.annotations.Type;
import javax.persistence.*;

@Entity
public class Location {

    private Double latitude;

    private Double longitude;

    @Type(type = "org.hibernatespatial.GeometryUserType")
    private Point coordinates;

    private final GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);

    @PrePersist
    @PreUpdate
    public void updateCoordinate() {
        if (this.latitude == null || this.longitude == null) {
            this.coordinates = null;
        } else {
            this.coordinates = geometryFactory.createPoint(new Coordinate(latitude, longitude));
        }
    }

    public Double getLatitude() {
        return latitude;
    }

    public void setLatitude(Double latitude) {
        this.latitude = latitude;
    }

    public Double getLongitude() {
        return longitude;
    }

    public void setLongitude(Double longitude) {
        this.longitude = longitude;
    }
}
21

JTSは、ポイントの単位や座標系が何であるかを気にしません。

ただし、 座標がデカルト平面上にあることを前提としています であるため、距離計算などの一部のジオメトリ操作は、長距離では不正確になる可能性があります。 (測地計算はまだサポートされていません。)

単純なストレージの使用には問題ないはずです。

ただし、注意すべき重要な点は、経度がX値であり、緯度がY値であるということです。したがって、「lat/long」と言いますが、JTSは「long/lat」の順序でそれを予期します。したがって、geometryFactory.createPoint(new Coordinate(longitude, latitude))を使用する必要があります

28
Gnat

WGS-84で座標を作成する方法は次のとおりです。

    double EARTH_RADIUS = 6378137.0;
    double x = longitude * EARTH_RADIUS * Math.PI / 180.;
    double y = EARTH_RADIUS * Math.sin(Math.toRadians(latitude));
    return new Coordinate(x,y,0.);

乾杯

2
David

他の人が言ったことを要約すると、Coordinateに変換するときは、3つの主な注意事項があります。

  • 投影。JTSはデカルト平面で機能するため、たとえば、 Mercatorは計算に反映されます。したがって、非常に短距離の領域でのみ使用する必要があります。正確な大きさはわかりませんが、ある程度の膨張以下はすべて問題ないと思います。 0.1度未満にとどまると、間違いなく安全です。
  • ユニット。どのユニットでも完全にJTSに入れることができます。問題は、メートル、度、またはその他のものを使用しているかどうかをJTSに伝えることができないことです。したがって、1つのユニットに固執するか、必要に応じて変換するように注意する必要があります。
  • 標準。ISO標準では、地理空間座標が最初に提供されると規定されています。ただし、どちらも最初にlonと記載されているGeoJSON/WKT標準と競合するため、逆になります。どちらの標準グループにもアプリケーションが固定されており(たとえば、Apache Luceneはメソッドの署名を変更せずにリリース間で標準を切り替えたため、マップが突然反転した理由を疑問に思う何百人ものユーザーに頭痛の種を引き起こしました)、JTSはGeoJSONを保持しています/ WKTバージョン。別のライブラリからデータを渡す場合は常に注意してください。GeoJSONとWKT、またはISOに従う場合があるため、事前に通知する必要があります。 (私を信じてください。私はすでにこれに問題を抱えていました、そしてそれはコード全体を調べて順序を逆にすることは本当に迷惑かもしれません。)

だから、それは正しくありません。あなたは3番目の問題にまっすぐ歩いています。 JTSが最初です。

また、休止状態の代わりに Neo4j Spatial の使用を検討することもできます。 Neo4jのグラフクエリ速度を使用し、JTSサポートが組み込まれています。また、IMHOの周りで最も快適なJava APIの1つがあります。

2
Egor Hans

ここでも同じ問題が発生し、座標をLat/LongからUTMに変換しました( http://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system を参照)。

基本的にはLat/Longから(X、Y)ペアに変換しますが、興味深いことに、これらのXとYは実数メートルであるため、距離に応じて正確な計算を行うことができます。 (実際には、小さな歪みを考慮する必要がありますが、メートルスケールの精度について話すときは無視できます)。

既存のJavaフレームワークが提供するLatLong2UTM関数に本当に満足していなかったので、自分でロールアウトしました。オンラインのjavascriptコンバーターから問題なく移植しました。

0
mdup