【问题标题】:Converting lat/long to JTS?将纬度/经度转换为 JTS?
【发布时间】:2012-01-14 07:14:27
【问题描述】:

我正在尝试将休眠空间与 JPA 集成以进行地理搜索。我一直在官方网站上引用tutorial(我与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;
    }
}

【问题讨论】:

  • 我不知道;您可能会在Geographic Information Systems 获得更多关注。另外,请尽量不要在每个帖子中提出一个以上的问题;这里的第一点已经够复杂了!
  • 不幸的是,该问题的教程链接现已失效。

标签: java hibernate jpa geolocation geospatial


【解决方案1】:

JTS 不关心您的点的单位或坐标系是什么。

但是,it does assume that the coordinates are on a Cartesian plane,因此某些几何运算(例如距离计算)在长距离上可能不准确。 (它们还不支持大地测量。)

对于简单的存储使用应该没问题。

但是,需要注意的重要一点是,经度是 X 值,纬度是 Y 值。所以我们说“纬度/纬度”,但 JTS 会期望它按“经度/纬度”的顺序。所以你应该使用geometryFactory.createPoint(new Coordinate(longitude, latitude))

【讨论】:

  • Gnat 是对的!请记住,“经度”对应于一般使用的“X 轴”。
  • 如果使用long/lat来创建Coordinate,缓冲区需要采用什么单位?
  • @eych 缓冲需要使用与坐标相同的单位。如果您的坐标以度为单位,您可以使用度来缓冲,或者先投影到米(例如使用 Proj4)
【解决方案2】:

我在这里遇到了同样的问题,我将坐标从 Lat/Long 翻译成 UTM(参见 http://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system)。

基本上,您可以从纬度/经度转换为 (X,Y) 对,但有趣的事实是,这些 X 和 Y 是真正的米,因此您可以根据距离进行准确的计算。 (实际上,您必须考虑一个小的失真,但在谈论米级精度时可以忽略不计)。

我对现有 Java 框架提供的 LatLong2UTM 函数并不满意,所以我推出了自己的。我从一些在线 javascript 转换器中移植了一个,没有太多麻烦。

【讨论】:

    【解决方案3】:

    这是在 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.);
    

    干杯

    【讨论】:

      【解决方案4】:

      总结其他人所说的,在转换为坐标时,需要注意 3 个主要事项:

      • 投影。 JTS 在笛卡尔平面中工作,因此所有失真都来自例如墨卡托传播到您的计算中。因此,您应该只在相当短的范围内使用它。我不确定确切的大小,但我认为低于扩张程度的一切都应该没问题。保持在 0.1 度以下,绝对安全。
      • 单位。您可以完美地将任何单位放入 JTS。问题是您无法告诉 JTS 您使用的是米、度还是其他任何东西。因此,您必须注意自己,要么坚持使用一个单元,要么在必要时进行转换。
      • 标准。 ISO 标准规定首先提供地理空间坐标。但是,它与首先声明 lon 的 GeoJSON/WKT 标准竞争,所以反过来。两个标准组都有应用程序坚持使用它们(例如,Apache Lucene 在版本之间切换标准而不更改方法签名,从而导致数百名用户感到头疼,想知道为什么他们的地图突然被翻转),而 JTS 坚持使用 GeoJSON /WKT 版本。请注意,无论您从哪里传递来自另一个库的数据 - 它可能遵循 GeoJSON 和 WKT 或 ISO,您应该提前通知自己。 (相信我。我已经遇到了麻烦,而且遍历整个代码并颠倒顺序真的很烦人。)

      所以,不,这是不对的。你直接进入第三个问题。 JTS 首先是 lon。

      另外,您可以考虑使用Neo4j Spatial 代替休眠。它使用 Neo4j 的图形查询速度,并具有内置的 JTS 支持。它还拥有围绕 IMHO 的最舒适的 Java API 之一。

      【讨论】:

        【解决方案5】:

        这是一个复制粘贴解决方案,用于创建具有给定纬度和经度值的 JTS 点。

        import com.vividsolutions.jts.geom.Coordinate;
        import com.vividsolutions.jts.geom.GeometryFactory;
        import com.vividsolutions.jts.geom.LineString;
        import com.vividsolutions.jts.geom.Point;
        import com.vividsolutions.jts.geom.PrecisionModel;
        
        public class GeometriesFactory {
        
            private static GeometryFactory factory4326 
                = new GeometryFactory(new PrecisionModel(PrecisionModel.FLOATING), 4326);
        
            public static Point createPoint(Double pLatitude, Double pLongitude){
                // inverted parameters are OK
                return factory4326.createPoint(new Coordinate(pLongitude, pLatitude));
            }
            
            public static LineString createLineString(Coordinate[] pCoordsArray){
                return factory4326.createLineString(pCoordsArray);
            }
            
        }
        
        

        Source

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-20
          • 2016-08-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多