区域内点的Hibernate-Spatial查询

Wou*_*ter 5 postgresql hibernate 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;
Run Code Online (Sandbox Code Playgroud)

最初我以为我可以创建一个Circle并基本上查询位于圆圈中的每个点.但这似乎比我想象的更难.我开始认为我在使用Hibernate-Spatial时做出了错误的选择.

我的问题是,是否可以通过使用Hibernate-Spatial查询特定边界内的每个点(从那里坐标x和y km).

我也对解决我的要求的其他可能性感兴趣.我一直在考虑以下可能性:

  • 只需在PostgreSQL上使用Native查询,将这些结果映射到实体并在应用程序的其他部分中使用它们(基本上删除Hibernate-Spatial并使用本机查询).
  • 切换到Hibernate-Search并使用Lucene完成我的任务.
  • 完全不同的东西

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

lre*_*der 6

对于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);
...
Run Code Online (Sandbox Code Playgroud)

这将返回距离中心点15个单位内的所有事件.

但是,给定的距离dwithin将与基础数据集具有相同的单位,不一定是千米. 如果数据集单位是米,则距离将被视为米.

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

另一种方法是将数据集重新投影并存储在PostgreSQL中,作为以米为单位的投影数据集.如果大规模地显示在地图上,这会扭曲您的数据,但您的搜索将按预期工作.

  • 这就是为什么我通常使人们远离MySQL进行空间使用的原因之一。最好的选择是使用类似以下的方法来计算自己到要素的距离:http://gis.stackexchange.com/questions/31628/find-points-within-a-distance-using-mysql (2认同)