区域内点的 Hibernate-Spatial 查询

标签 hibernate postgresql postgis spatial hibernate-spatial

亲爱的 stackoverflow 读者,

我目前正在开发一个需要根据其坐标加载特定项目的应用程序。示例:我想要坐标 x 或其 15 公里以内的所有商店。

我一直在 Java EE 6 中构建此 Web 应用程序,并使用 Hibernate 3.3 将数据持久保存到我的 Postgres 数据库中。经过一番研究后,我发现 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 上使用 native 查询,将这些结果映射到实体并在应用程序的其他部分使用它们(基本上删除 Hibernate-Spatial 并使用 native 查询)。
  • 切换到 Hibernate-Search 并使用 Lucene 来完成我的任务。
  • 完全不同的东西

任何人都可以提供一个示例,说明我如何在 Hibernate-Spatial 中实现我的愿望,或者我如何以其他方式实现我的要求。

最佳答案

对于 PostgreSQL/PostGIS 方言,Hibernate Spatial 支持 dwithin 函数。

boolean dwithin(Geometry, Geometry, double) - Returns true if the geometries are within the specified distance of one another

解释 Hibernate Spatial tutorial ,查询看起来像这样:

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 中给出的距离将与基础数据集具有相同的单位,不一定是千米。如果数据集单位是米,则距离将被视为米。

如果数据集是 lat-lng,则距离将是度数。如果是这种情况,并且您的搜索距离很小(15 Km 很小),并且您处于低纬度,则可以将 Km 近似为 0.009。这将在赤道处为您提供一个完美的搜索圆,但是当您向北或向南移动时,该圆将变成一个长轴指向南北的椭圆。在 +/- 60 度纬度处,椭圆的高度将是宽度的两倍。显然不理想,但它可能适用于您的情况。

另一种方法是将您的数据集重新投影并存储在 PostgreSQL 中,作为以米为单位的投影数据集。如果在 map 上以大比例显示,这会扭曲您的数据,但您的搜索将按预期进行。

关于区域内点的 Hibernate-Spatial 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16333811/

相关文章:

php - 在单个 mysql 查询中,从一个表中选择多行,每行包含来自链接表的多行

postgresql - 找出连续聚合的大小

postgresql - “LANGUAGE ' plpgsql'VOLATILE”是什么意思?

postgresql - 需要帮助编写 PostgreSQL 触发器函数

java - 对象枚举总是返回空值

java - org.hibernate.HibernateException : Unable to instantiate default tuplizer [org. hibernate.tuple.entity.PojoEntityTuplizer]

java - 如何在项目中使用 2 个 RDBMS

java - Hibernate 搜索 4.4.2 按日期排序不起作用

python - 通过 Binary Copy 将包含 PostGis 字段的数据批量加载到 PostgreSQL

sql - 如何递归查找两个表之间的相交地理