从列表中找到最近的Gps指向用户位置

时间:2010-10-21 12:20:20

标签: java android database location

我要做的是:用户在地图上选择开始和目的地,然后从他们的坐标我想要显示地图上的位置列表中最近的点位置。我有一个简单的Sqlite数据库,包含可能位置的经度,纬度和名称。

我做了一些研究,这就是我发现的:

http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL

但这是为了将它与mySql和某种空间搜索扩展一起使用。 有没有可能我可以使用android api或外部库来做类似的事情?

public Point dialogFindClosestLocationToPoint(geometry.Point aStartPoint){
List<PointWithDistance> helperList=new ArrayList<PointWithDistance>();
try {
openDataBase();
Cursor c=getCursorQueryWithAllTheData();
if(c.moveToFirst())
 do{
  PointWithDistance helper=new PointWithDistance(c.getDouble(1),c.getDouble(2),c.getString(3));
  int distance=returnDistanceBetween2Points(aStartPoint, helper);
  if(distance<MAX_SEARCH_DISTANCE){
   helper.setDistance(distance);
   Log.i("values", helper.name);
   helperList.add(helper);
  }
 }while (c.moveToNext());
Collections.sort(helperList,new PointComparator());

if(helperList!=null)
 return helperList.get(0);
else return null;
}catch(SQLException sqle){

throw sqle;

}
finally{
 close();
}

这是PointComparator()类中的代码:

   public int compare(PointWithDistance o1, PointWithDistance o2) {
  return (o1.getDistance()<o2.getDistance() ? -1 : (o1.getDistance()==o2.getDistance() ? 0 : 1));
 }

其中PointWithDistance是一个包含:lat,long,distance,name

的对象

但是这个解决方案没有提供正确的返回信息......我意识到它根本不可扩展且非常慢。我需要一个能够快速执行最多1000行数据库的解决方案。

编辑:我在排序中的代码中出现了错误,现在我已将其更改(应该是&lt;而不是&gt;)

3 个答案:

答案 0 :(得分:3)

使用R-Tree可以最有效地完成此类操作。 JSI library提供了一个Java实现,我已成功使用索引为80.000个位置,每秒处理数千个查找。但是,它可能无法在Android上运行。

答案 1 :(得分:2)

前段时间我正在寻找一些非常相似的东西:

Android sqlite sort on calculated column (co-ordinates distance)

我在我的服务器上使用MySQL查找,MySQL允许您创建虚拟列,执行计算并按距离排序,然后您可以设置返回的最大结果或最大距离 - 它运行良好:< / p>

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

我想在我的应用程序中执行相同的操作 - 拉出所有点以便与用户位置保持距离,以便显示最接近的位置。我最终得到的解决方案与上面链接中提出的解决方案一致,但实现它可能不是最佳解决方案,但可以达到我想要的目的。

答案 2 :(得分:1)

我还没有尝试过运行你的代码,但似乎它会起作用,只是它没有效率。就像你实际上不需要排序一样,你需要提取最小值。

您可以将查询限制为大小为(2 * MAX_SEARCH_DISTANCE)^ 2的平方(您的点在中间。 这样您就可以本地化查询,这样可以减少计算距离的结果。 当然,如果您所有的位置都在本地化的方块中(这可能不太可能?),这将无济于事。

另外,我想你可以使用哈密尔顿距离代替欧几里德。 欧几里德距离= sqrt((lat0 - lat1)^ 2 +(lon0 - lon1)^ 2) hamitonian距离=(lat0 - lat1)+(lon0 - lon1)