Ibernazione spaziale - query all'interno di un raggio di x chilometro?
-
21-12-2019 - |
Domanda
Sono nuovo per ibernazione spaziale e sto cercando di eseguire una semplice query di oggetti all'interno di un determinato raggio.Ho creato un numero di voci nel mio database con proprietà corrispondenti a una latitudine e longitudine, utilizzando i dati da Google Maps e altre fonti.Questa proprietà è definita come questa nella mia classe di entità:
@Column
@Type(type = "org.hibernate.spatial.GeometryType")
private Point coordinates = null;
.
Sto ora cercando di capire come fare una ricerca di tutti gli oggetti di entità che hanno coordinate che rientrano in un raggio di x chilometri da un determinato punto.Ad esempio, vorrei trovare oggetti che rientrano in un raggio di 50 chilometri del punto (12.34567, -76.54321).Tuttavia, non riesco a trovare alcun esempio o tutorial che spiegherebbero come farlo in ibernazione spaziale.
Qualcuno può darmi qualsiasi informazione su come una query come questa può essere costruita?
Soluzione
Vedi Questa risorsa per un tutorial con "spaziale Query ", che un dialetto speciale e il Libreria JTS (open source). Fondamentalmente fai quanto segue (copia / incolla dalla pagina di riferimento):
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;
}
.
Per generare un cerchio, vedere Questa risorsa (ricerca Per "archi, cerchi e curve"). Di nuovo una copia / incolla da lì:
//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();
}
.
Inoltre hai sempre la soluzione alternativa, in cui aggiungere alcuni campi aggiuntivi (mappati coninsertable=false, updatable=false
) per mappare le stesse colonne utilizzate da org.hibernate.spatial.GeometryType
e quindi utilizzarle nella tua query. Per calcolare la distanza, controlla il euclidian Distance Formula .