2015-07-21 81 views
2

我有一个表中的项目存储使用基于经度和纬度的地理位置。在某一点上,我只想从数据库中检索当前位置特定范围(距离或半径)内的项目。Sqlite:选择基于距离的项目(经度和纬度)

项目(纬度,经度)

所以我跟着这真的nice post,并试图实现与得票最高的答案。首先:在存储项目时,我不得不添加更多的列。这使得select语句后面:

项目(LAT,lat_cos,lat_sin,LNG,lng_cos,lng_sin)

到目前为止好,但是当我再尝试构建查询,我疯了。如果我使用较少符号<则检索所有项目(即使太远)。但是,如果我使用更大的符号>,则不会检索任何项目。但我知道我的范围内有物品。

问题:那么我在做什么错了?

WHERE(coslat * LAT_COS *(* LNG_COS + coslng * LNG_SIN sinlng))+ sinlat * LAT_SIN> cos_allowed_distance

下面是我使用的查询我的ContentProvider的代码。该ContentInfo类有中将sortOrder,选择字段和selectionArgs两个:

public static ContentInfo buildDistanceWhereClause(double latitude, double longitude, double distanceInKilometers) { 

     final double coslat = Math.cos(Math.toRadians(latitude)); 
     final double sinlat = Math.sin(Math.toRadians(latitude)); 
     final double coslng = Math.cos(Math.toRadians(longitude)); 
     final double sinlng = Math.sin(Math.toRadians(longitude)); 

     // (coslat * LAT_COS * (LNG_COS * coslng + LNG_SIN * sinlng)) + sinlat * LAT_SIN > cos_allowed_distance 
     final String where = "(? * ? * (? * ? + ? * ?)) + ? * ? > ?"; 
     final String[] whereClause = new String[] { 
       String.valueOf(coslat), 
       ItemTable.COLUMN_LATITUDE_COS, 
       ItemTable.COLUMN_LONGITUDE_COS, 
       String.valueOf(coslng), 
       ItemTable.COLUMN_LONGITUDE_SIN, 
       String.valueOf(sinlng), 
       String.valueOf(sinlat), 
       ItemTable.COLUMN_LATITUDE_SIN, 
       String.valueOf(Math.cos(distanceInKilometers/6371.0)) 
     }; 

     return new ContentInfo(null, where, whereClause); 
    } 
} 

回答

2

我没有真正看到问题,但我重新设计了选择/在那里,以便更容易阅读。现在它起作用了。您还可以结账this fiddle

public static String buildDistanceWhereClause(double latitude, double longitude, double distanceInKilometers) { 

    // see: http://stackoverflow.com/questions/3126830/query-to-get-records-based-on-radius-in-sqlite 

    final double coslat = Math.cos(Math.toRadians(latitude)); 
    final double sinlat = Math.sin(Math.toRadians(latitude)); 
    final double coslng = Math.cos(Math.toRadians(longitude)); 
    final double sinlng = Math.sin(Math.toRadians(longitude)); 

    final String format = "(%1$s * %2$s * (%3$s * %4$s + %5$s * %6$s) + %7$s * %8$s) > %9$s"; 
    final String selection = String.format(format, 
      coslat, COLUMN_LATITUDE_COS, 
      coslng, COLUMN_LONGITUDE_COS, 
      sinlng, COLUMN_LONGITUDE_SIN, 
      sinlat, COLUMN_LATITUDE_SIN, 
      Math.cos(distanceInKilometers/6371.0) 
      ); 

    Log.d(TAG, selection); 
    return selection; 
} 
+0

嗨。我在你的问题中遇到了同样的问题。无值或全部值。这是一个可行的解决方案吗?什么是ContentInfo?请帮助 – Jas

+0

我更改了代码并删除了我的数据结构ContentInfo。你只需要字符串“选择”。代码工作正常,是的。我在我的应用程序中使用它。 – Matthias