计算列上的Android sqlite排序(坐标距离)

时间:2010-01-09 18:10:42

标签: android sqlite coordinates

我正在使用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数据库吗?如果不是我能想到的唯一选择是有一个额外的列,遍历每行上运行上述函数的行,并在该行上填写一个额外的列,然后对该列进行排序?

4 个答案:

答案 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编写的:(。