我有一张桌子,根据纬度和经度使用地理位置存储物品。有一次,我想只检索数据库中当前位置的特定范围(距离或半径)内的那些项目。
项目(纬度,经度)
所以我真的跟着这个nice post并尝试以最高票数来实现答案。第一件事:我必须在存储项目时添加更多列。这将在以后启用select语句:
项目(lat,lat_cos,lat_sin,lng,lng_cos,lng_sin)
到目前为止一直很好,但是当我尝试构建查询时,我疯了。如果我使用less-symbol < ,则会检索所有项目(即使距离太远)。但是,如果我使用更大的符号> ,则不会检索任何项目。但我知道我的范围内有物品。
问题:那么这个词我做错了什么?
WHERE(coslat * LAT_COS *(LNG_COS * coslng + LNG_SIN * sinlng))+ sinlat * LAT_SIN> cos_allowed_distance
这是我用来查询ContentProvider的代码。 ContentInfo类包含sortOrder,selection和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);
}
}
答案 0 :(得分:3)
我实际上没有看到问题,但我重新设计了选择/哪里,因此更容易阅读。现在它有效。您也可以结帐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;
}