4

我正在使用 SQLITE 数据库来存储位置的纬度和经度。

我希望能够按与当前位置的粗略距离对结果进行排序。我已经将设备的当前位置作为双精度(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

4 回答 4

4

这不会完全有帮助,但是对于这种情况,请认真考虑使用rawQuery()而不是query(),这样您就可以传入完整的 SQL 语句,而不必将其切成碎片。


你更大的问题是我没有看到 SQLite 有三角函数。

您没有说明您是如何使用Cursor从查询中返回的。例如,如果您将Cursor放入某种 中CursorAdapter,您可以:

  • 将 转换Cursor为,您使用数据定义的一些 Java 类ArrayList<Position>在哪里Position
  • 关闭Cursor, 释放它占用的 RAM
  • 排序ArrayList<Position>使用Arrays.sort()
  • 将其包裹起来ArrayList<Position>ArrayAdapter<Position>使用您一直在使用的地方CursorAdapter
于 2010-01-09T19:08:22.147 回答
3

是的,这很完美。

它可以做成这样的存储过程:

http://www.thissuchiknow.co.uk/?p=71 [sqlite 的距离函数]

还有非常棒的适用于 android 的 Perst 空间数据库,以及也很棒的SpatiaLite空间数据库,您可以在应用程序中链接到它们。

不使用专门的库,您可以通过几种方式近似距离(计算它就像它是平面(矩形)然后使用Haversine公式稍后对子集进行排序,使用近似cos,sin等的查找表,将位置分组到 5 平方英里的区域中,并搜索相邻单元格,直至最大,等等...)

于 2010-01-09T18:16:54.683 回答
3

在我的应用程序 BostonBusMap 中,我使用了一个近似值来加快计算最接近某个点的对象。您可以按比例缩放经度cos(latitude),然后只需使用毕达哥拉斯公式来计算排序距离(省略方形路线,因为比较距离不是必需的)。它适用于小距离。

资料来源:http ://en.wikipedia.org/wiki/Geographical_distance#Spherical_Earth_projected_to_a_plane

于 2012-09-17T00:48:40.650 回答
0

我刚刚编写了一个需要根据距离对一组坐标进行排序的应用程序。我所做的是创建一个 ID 和距离数组,然后在 Java 中对它们进行排序。然后我可以找到最近的位置并从数据库中选择它们。当然,这种方法可能对您不起作用,具体取决于您拥有多少点以及您访问数据库的方式。在我的 Nando's Finder 应用程序中,这对大约 350 点效果很好。

此外,我使用 SDK 中的 Location.distanceBetween(..) 为我计算距离。我希望这个方法可以用 C 来实现,以确保它很快,但是,快速查看SDK 源代码会发现它是用 Java 编写的 :(。

于 2010-01-09T19:52:49.247 回答