Sqlite:根据距离(纬度和经度)选择项目

时间:2015-07-21 15:57:15

标签: android sqlite google-maps

我有一张桌子,根据纬度和经度使用地理位置存储物品。有一次,我想只检索数据库中当前位置的特定范围(距离或半径)内的那些项目。

  

项目(纬度,经度)

所以我真的跟着这个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);
    }
}

1 个答案:

答案 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;
}