Hibernate Spatial - 在X公里半径内查询?

15

我是Hibernate Spatial的新手,试图在给定半径内执行简单对象的查询。我已经在我的数据库中创建了许多条目,这些条目具有与纬度和经度相对应的属性,使用了来自Google Maps和其他来源的数据。在我的实体类中,该属性定义如下:

@Column
@Type(type = "org.hibernate.spatial.GeometryType")
private Point coordinates = null;

我现在正在尝试找出如何搜索所有实体对象,这些对象的坐标在距离给定点x公里范围内。例如,我想找到那些在距离点(12.34567,-76.54321)50公里半径范围内的对象。然而,我找不到任何在Hibernate Spatial中如何完成此类查询的示例或教程。

有谁能够给我关于如何构建这样一个查询的任何信息吗?

1个回答

16

请参见这个资源,了解使用“空间查询”的教程,其中包含一个特殊方言和JTS库(开源)。

基本上,您需要执行以下操作(从引用页面复制/粘贴):

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import util.JPAUtil;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.Date;
import java.util.List;

.......

private List find(String wktFilter) {
    Geometry filter = wktToGeometry(wktFilter);
    EntityManager em = JPAUtil.createEntityManager();
    em.getTransaction().begin();
    Query query = em.createQuery("select e from Event e where within(e.location, :filter) = true", Event.class);
    query.setParameter("filter", filter);
    return query.getResultList();
}

private Geometry wktToGeometry(String wktPoint) {
    WKTReader fromText = new WKTReader();
    Geometry geom = null;
    try {
        geom = fromText.read(wktPoint);
    } catch (ParseException e) {
        throw new RuntimeException("Not a WKT string:" + wktPoint);
    }
    return geom;
}

生成一个圆形,请参见此资源(搜索“Arcs, Circles and Curves”)。

//this method replaces the above wktToGeometry() method
private static Geometry createCircle(double x, double y, final double RADIUS) {
  GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
  shapeFactory.setNumPoints(32);
  shapeFactory.setCentre(new Coordinate(x, y));//there are your coordinates
  shapeFactory.setSize(RADIUS * 2);//this is how you set the radius
  return shapeFactory.createCircle();
}

此外,您总是可以采取变通措施,在其中添加一些额外字段(与insertable=false, updatable=false映射),以映射到org.hibernate.spatial.GeometryType使用的相同列,并在查询中使用它们。要计算距离,请检查欧几里得距离公式


该页面上展示的示例显示了在给定多边形内查询点的过程。我是否必须在查询中指定一个多边形?理想情况下,我希望能够提供一个点(纬度/经度)和半径,并在查询中使用它,而不是多边形。我如何使用JTS/Hibernate Spatial声明该几何图形? - Shadowman
一个圆是一种特殊的几何形状,但不是多边形。请查看我的更新示例,了解如何创建圆形。 - V G
好的,这一切都很有道理。我会试一试。不幸的是,我遇到了这个错误(https://dev59.com/ynnZa4cB1Zd3GeqPolO4),在解决它之前无法进行测试。 - Shadowman
1
我需要完全相同的东西...你如何确定半径是米/千米等单位? - simonC
1
这个计算欧几里得距离的程序,在地球坐标系下无法工作。 - cdr89
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接