I am new to Hibernate Spatial, and am trying to perform a simple query of objects within a given radius. I've created a number of entries in my database with properties corresponding to a latitude and longitude, using data from Google Maps and other sources. This property is defined like this in my Entity class:
@Column
@Type(type = "org.hibernate.spatial.GeometryType")
private Point coordinates = null;
I'm now trying to figure out how to do a search of all entity objects that have coordinates that fall within a radius of x kilometers from a given point. For example, I'd like to find objects that fall within a 50 kilometer radius of the point (12.34567, -76.54321). However, I can't find any examples or tutorials that would explain how to do this in Hibernate Spatial.
Can anyone give me any information on how a query like this can be constructed?
See this resource for a tutorial with "Spatial Queries", which a special dialect and the JTS library (Open Source).
Basically you do the following (copy/paste from the referenced page):
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;
}
For generating a circle, see this resource (search for "Arcs, Circles and Curves"). Again a copy/paste from there:
//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();
}
Besides you always have the workaround, in which to add some additional fields ( mapped withinsertable=false, updatable=false
) to map to the same columns used by the org.hibernate.spatial.GeometryType
and then use them in your query. For computing the distance, check the euclidian distance formula.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With