2013-11-17 4 views
9

Я новичок в Hibernate Spatial и пытаюсь выполнить простой запрос объектов в пределах заданного радиуса. Я создал несколько записей в моей базе данных со свойствами, соответствующими широте и долготе, используя данные из Карт Google и других источников. Это свойство определяется как это в моем классе Entity:Hibernate Spatial - Запрос в радиусе X километров?

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

Я сейчас пытаюсь выяснить, как сделать поиск всех объектов сущностей, которые имеют координаты, которые находятся в пределах радиуса х километров от данный пункт. Например, я хотел бы найти объекты, которые находятся в радиусе 50 километров от точки (12.34567, -76.54321). Тем не менее, я не могу найти примеров или руководств, которые объясняли бы, как это сделать в Hibernate Spatial.

Может ли кто-нибудь дать мне какую-либо информацию о том, как можно построить такой запрос?

ответ

14

См this resource для учебника с "пространственных запросов", который особый диалект и JTS library (Open Source).

В основном вы следующее (копировать/вставить из указанной страницы):

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; 
} 

Для создания круга, см this resource (поиска «Дуги, круги и кривые»). Опять копировать/вставить оттуда:

//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, а затем использовать их в Ваш запрос. Для вычисления расстояния проверьте euclidian distance formula.

+0

В примере, показанном на этой странице, отображается запрос точки в заданном полигоне. Должен ли я указывать многоугольник в моем запросе? В идеале я мог бы дать ему точку (lat/long) и радиус и использовать это в моем запросе вместо полигона. Как я могу объявить, что геометрия использует JTS/Hibernate Spatial? – Shadowman

+0

Ну, круг - это специальная геометрия, но не многоугольник. См. Мой обновленный пример, чтобы узнать, как вы создаете круг. –

+0

Хорошо, это все имеет смысл. Я сделаю это. К сожалению, я столкнулся с этой ошибкой (http://stackoverflow.com/questions/20079825/hibernate-spatial-invalid-endian-flag-value-encountered-exception), что делает невозможным тестирование до тех пор, пока я его не разрешу. – Shadowman

Смежные вопросы