我正在使用SQLITE数据库来存储位置的纬度和经度。
我希望能够通过与当前位置的粗略距离对结果进行排序。我已经将设备的当前位置设置为double(lat,lng),数据库中的lat和lng也是双倍的。
我想要的是一个查询,它将创建一个我能够按结果对结果进行排序的虚拟列。
我目前使用一个函数来显示所选记录的距离:
float pk = (float) (180/3.14159);
float a1 = (float) (db_lat / pk);
float a2 = (float) (db_lon / pk);
float b1 = (float) (current_lat / pk);
float b2 = (float) (current_lon / pk);
float t1 = FloatMath.cos(a1)*FloatMath.cos(a2)*FloatMath.cos(b1)*FloatMath.cos(b2);
float t2 = FloatMath.cos(a1)*FloatMath.sin(a2)*FloatMath.cos(b1)*FloatMath.sin(b2);
float t3 = FloatMath.sin(a1)*FloatMath.sin(b1);
double tt = Math.acos(t1 + t2 + t3);
double dist = (6366000*tt);
例如,MySQL选择可以(取自:www.movable-type.co.uk):
Select Lat, Lon, acos(sin($lat)*sin(radians(Lat)) + cos($lat)*cos(radians(Lat))cos(radians(Lon)-$lon))$R As dist
From MyTable
ORDER BY dist DESC
目前,我使用以下方式选择地点:
public Cursor locationGetAllRows(long groupid)
{
try
{
return db.query(LOCATION_DATABASE_TABLE, new String[] {
"_id", "lat","lon","groupid"},
"groupid="+groupid, null, null, null, null);
}
catch (SQLException e)
{
Log.e("Exception on query: ", e.toString());
return null;
}
}
好的,这样可以使用SQLITE数据库吗?如果不是我能想到的唯一选择是有一个额外的列,遍历每行上运行上述函数的行,并在该行上填写一个额外的列,然后对该列进行排序?
答案 0 :(得分:4)
这不会有任何帮助,但对于这种情况,请认真考虑使用rawQuery()
而不是query()
,这样您就可以传入完整的SQL语句而不必将其分成几部分。
你更大的问题是我没有看到SQLite具有三角函数。
您没有说明如何使用从查询中获取的Cursor
。例如,如果您将Cursor
放入某种CursorAdapter
,则可以:
Cursor
转换为ArrayList<Position>
,其中Position
是您使用数据定义的某个Java类Cursor
,以释放占用的内存ArrayList<Position>
Arrays.sort()
进行排序
ArrayList<Position>
打包在ArrayAdapter<Position>
中并使用您CursorAdapter
答案 1 :(得分:3)
它可以像这样存储过程:
http://www.thismuchiknow.co.uk/?p=71 [sqlite的距离函数]
还有Perst spatial database for android非常出色,SpatiaLite空间数据库也非常棒,您可以在应用中链接到该数据库。
w / out使用专门的lib,您可以通过几种方式近似距离(计算它就像它是平面的(矩形)然后使用Haversine公式对子集进行排序,使用近似cos的查找表,罪等,将地点划分为5平方英里的区域,并搜索相邻的单元格,等等...)答案 2 :(得分:3)
在我的应用程序BostonBusMap中,我使用近似来加速计算最接近点的对象。您可以将经度缩放cos(latitude)
,然后使用毕达哥拉斯公式来计算排序距离(省略方形路线,因为它不需要比较距离)。它适用于小距离。
来源:http://en.wikipedia.org/wiki/Geographical_distance#Spherical_Earth_projected_to_a_plane
答案 3 :(得分:0)
我刚刚编写了一个应用程序,需要根据距离对一组坐标进行排序。我所做的是创建一个ID和距离数组,然后在Java中对它们进行排序。然后我可以找到最近的位置并从数据库中选择它们。当然,根据您拥有的点数以及访问数据库的方式,这种方法可能对您无效。在我的Nando的Finder应用程序中,这可以达到约350分。
此外,我使用SDK中的Location.distanceBetween(..)来计算距离。我希望这个方法可以在C中实现,以确保它快速,但是,快速查看SDK source显示它是用Java编写的:(。