I have a java aplication backed by a mysql database which contains events with locations (latitude/longitude), the location data is saved as POINT data type.
I nead to find the nearest events in some radius. I am already able to do this but the results are innacurate.
I'm also using hibernate spatial to make the query.
I'm using the folowing libraries : 1.) com.vividsolutions.jts ... for creating geometry types 2.) Geotools org.geotools ... for calculating distance between points
First I make a circle Geometry with a center placed in a current location this circle is given some radius. For example 500m if I want to find the events in the distance of 500m. The problem is that the Geometry construct takes neads the radius in degrees. If i'm not mistaken the distance in degrees changes based on a point on earth.
then I query the database with the within hibernate spatial function, but the results are unnacurate.
So I dont know how to calculate the distance in degrees based on location on earth. I think there should already be some library that is doing this, but for now I havent find an example. Can you advise me some code?
My Code:
//calculate the shape where the events should be
Geometry circle = createCircle(currentLongitude,currentLatitude, radiusInKm);
//retrieve the events from database that are within the calculated shape
List<si.arctur.model.Event> seznam = find(circle.toString());
//the methods
private static Geometry createCircle(double x, double y, final double RADIUS) {
double latitude = 110.54;
double longitude = 111.320;
//TODO beter accuracy
double radiusInDegreesLatitude = RADIUS / latitude;
double radiusInDegreesLongitude = RADIUS / Math.abs((longitude * Math.cos(latitude)));
GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
shapeFactory.setNumPoints(1000);
shapeFactory.setHeight(radiusInDegreesLatitude * 2);
shapeFactory.setWidth(radiusInDegreesLongitude * 2);
shapeFactory.setCentre(new Coordinate(x, y));//there are your coordinates
Polygon shape = shapeFactory.createCircle();
return shape;
}
private List find(String wktFilter) {
Geometry filter = wktToGeometry(wktFilter);
Query query = em.createQuery("select e from Event e where within(e.location, :filter) = true", si.arctur.model.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;
}