簡體   English   中英

將lat / long轉換為JTS?

[英]Converting lat/long to JTS?

我正在嘗試將hibernate空間與JPA集成以進行地理搜索。 我一直在官方網站上引用該教程 (我與hibernatespatial無關)。

遺憾的是,本教程未介紹如何從緯度/經度對創建Point實例。 我試圖在這里這樣做,但我仍然不確定這是否是將緯度/經度對轉換為JTS Point實例的正確方法:

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;
    }
}

JTS並不關心你的點的單位或坐標系是什么。

但是, 它確實假設坐標位於笛卡爾平面上 ,因此一些幾何操作(例如距離計算)可能在長距離上不准確。 (他們還不支持大地測量計算。)

對於簡單的存儲用途應該沒問題。

但是,需要注意的一點是,經度是X值,緯度是Y值。 所以我們說“lat / long”,但是JTS會按照“long / lat”的順序來預期它。 所以你應該使用geometryFactory.createPoint(new Coordinate(longitude, latitude))

總結其他人所說的,轉換為坐標時,有三個主要方面需要注意:

  • 投影。 JTS在笛卡爾平面上工作,因此來自墨卡托的所有失真都會傳播到您的計算中。 因此,您應該只在非常短距離的區域使用它。 我不確定精確的幅度,但我認為低於擴展程度的一切都應該沒問題。 保持在0.1度以下,你肯定是安全的。
  • 單位。 你可以將任何單位完美地放入JTS。 麻煩的是你不能告訴JTS你是使用米,度,還是其他任何東西。 所以你必須要小心自己要么堅持一個單位,要么在必要時進行轉換。
  • 標准。 ISO標准規定首先提供地理空間坐標。 然而,它與GeoJSON / WKT標准競爭,這兩個標准都是第一個,所以反過來。 兩個標准組都有應用程序(例如,Apache Lucene在不改變方法簽名的情況下在版本之間切換標准,因此引起數百名用戶的疑慮,他們想知道為什么他們的地圖突然被翻轉),並且JTS持有GeoJSON / WKT版。 注意,無論您從另一個庫傳遞數據 - 它可能遵循GeoJSON和WKT,或ISO,您應該提前通知自己。 (相信我。我已經遇到了這個麻煩,整個代碼和翻轉順序真的很煩人。)

所以,不,這不對。 你直接陷入了第三個問題。 JTS是第一個。

此外,您可能會考慮使用Neo4j Spatial而不是hibernate。 它使用Neo4j的圖形查詢速度,並具有內置的JTS支持。 它還擁有恕我直言的最舒適的Java API之一。

以下是如何在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.);

干杯

我在這里遇到了同樣的問題,我將來自Lat / Long的坐標轉換為UTM(參見http://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system )。

基本上你從Lat / Long轉換為(X,Y)對,但有趣的是,那些X和Y是真實的米,因此你可以進行精確的計算,這取決於距離。 (實際上,你必須考慮到一個小的失真,但在談論米級精度時可以忽略不計)。

我對現有Java框架提供的LatLong2UTM函數並不滿意,所以我推出了自己的。 我從一些在線JavaScript轉換器中移植了一個沒有太多麻煩。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM