使用 Hibernate Spatial 查询 n 公里半径内的所有对象?

con*_*ile 5 java hibernate jts geospatial hibernate-spatial

我使用休眠空间将地理位置附加到汽车上。我的卡域类如下所示:

import com.vividsolutions.jts.geom.Point
class Card {
  String name
  Point location 
}
Run Code Online (Sandbox Code Playgroud)

我的程序是用 Grails 编写的,所以我给出的示例是用 Groovy 编写的。我在这里找到了一篇类似的文章,它并没有真正回答关于如何正确指定半径以设置 n 公里的半径的最重要问题。

这是我计算圆几何形状的方法:

  private static Geometry createCircle(double x, double y, final double RADIUS) {
    GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
    shapeFactory.setNumPoints(1000);
    shapeFactory.setCentre(new Coordinate(x, y))
    shapeFactory.setSize( (RADIUS * 2)/88.1)

    return shapeFactory.createCircle().getBoundary()
  }
Run Code Online (Sandbox Code Playgroud)

圆的大小除以 88.1,这只是一个肮脏的修正来获得近似尺寸,但它仍然是错误的。

我的查询是这样完成的:

double radius = 40
Geometry filter = createCircle(car.location.x, car.location.y, radius)
Session session = sessionFactory.currentSession
Query q = session.createQuery("select c from Car c where within(c.location, ?) = true")
q.setParameter(0, filter, GeometryUserType.TYPE) 
q.list()
Run Code Online (Sandbox Code Playgroud)

这工作得不太准确。该查询返回了一些应该在圆圈之外的汽车。

这是一个例子。我的中心是汉堡,半径是40公里。我做了一个谷歌地图可视化。

这是我设置时的情况radius = 40

在此输入图像描述

您可以看到,在左上角仍然绘制了一辆位置在圆圈之外的汽车。情况不应该如此。在我看来,我用谷歌地图绘制的圆圈不等于我在查询代码中绘制的圆圈几何形状。

这是我设置时的情况radius = 30

在此输入图像描述

您会看到右下角的汽车消失了,这是正确的,但左上角的汽车仍然保留在查询中。

当我绘制用我创建的圆时,createCircle我得到以下结果(用于getCoordinates()获取圆的坐标):

在此输入图像描述

如何查询40公里半径内的所有车辆?

jmv*_*ivo 1

尝试计算几何图形之间的距离。您可以使用dwithin函数(请参阅Hibernate 空间文档):

select c from Car c where dwithin(c.location, :geom, :dist) = true
Run Code Online (Sandbox Code Playgroud)

要不就distance

select c from Car c where distance(c.location, :geom) < :dist
Run Code Online (Sandbox Code Playgroud)

另外,不要忘记将距离测量转换为度数(对于 WGS84 SRS)。

编辑

使用geom作为假想圆的中心,这样您就不必生成几何图形,只需按距离进行过滤即可。

PD:在这篇文章中你可以找到关于度和米转换问题的描述

祝你好运!。切玛。