Calculate distance between two points directly in SQLite
Insert cos_lat_rad,sin_lat_rad,cos_lon_rad,sin_lon_rad in to your table
contentValues.put("cos_lat_rad", Math.cos(deg2rad(latitude)));
contentValues.put("sin_lat_rad", Math.sin(deg2rad(latitude)));
contentValues.put("cos_lon_rad", Math.cos(deg2rad(longitude)));
contentValues.put("sin_lon_rad", Math.sin(deg2rad(longitude)));
degree to radian
public static double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}
query , distance in km
Cursor c=database.dis(String.valueOf(Math.cos((double) distance / (double) 6380)), Math.cos(deg2rad(latitude)), Math.sin(deg2rad(latitude)), Math.cos(deg2rad(longitude)), Math.sin(deg2rad(longitude)));
query
public Cursor dis(String dis, double cos_lat_rad, double sin_lat_rad, double cos_lon_rad, double sin_lon_rad) {
Cursor cursor = sqLiteDatabase.rawQuery("SELECT * ,(" + sin_lat_rad + "*\"sin_lat_rad\"+" + cos_lat_rad + "*\"cos_lat_rad\"*(" + sin_lon_rad + "*\"sin_lon_rad\"+" + cos_lon_rad + "*\"cos_lon_rad\")) AS \"distance_acos\" FROM parish WHERE ("+sin_lat_rad+" * \"sin_lat_rad\" +"+ cos_lat_rad +"* \"cos_lat_rad\" * (+"+sin_lon_rad +"* \"sin_lon_rad\" + "+cos_lon_rad +"* \"cos_lon_rad\")) >"+dis+ " ORDER BY \"distance_acos\" DESC ", null);
return cursor;
}
convert distance_acos to km
if(c.moveToFirst())
do {
double distance_acos= c.getDouble(c.getColumnIndex("distance_acos"));
String Distance=String.valueOf(Math.acos(distance_acos) * 6380);
}while (c.moveToNext());
Here is what I would do:
Take your given point. Measure a (that is an arbitrary value to be refined) ~2km wide square around it and take the values for the east/west/north/south bounds.
Make a query for elements inside this square. This one is easy, you just have to
select * from points where lat between ? and ? and lon between ? and ?
Count your result. Not enough result (less than 5, obviously, but I would say twice that to be sure), retry with a larger radius. Too much (say, more than 100), try again with a smaller radius.
Once you have enough, load them, make sure all 5 elements you need are not only in the Xkm wide square, but also in the Xkm radius circle (to avoid having a potential closer element not detected by the previous approximation).
Another approach
Valid only if your given point is relatively close to those you are searching.
Measure a local approximation of a flat earth. Close to your point, you can consider a linear relation between lat, lon, and distance. That allows you to make a request sorted by a simple calculus. (multiplication and addition). Again, select a little more points in order to make the proper calculation after the SQLite request.