【问题标题】:Sqlite: select items based on distance (latitude and longitude)Sqlite:根据距离(经纬度)选择项目
【发布时间】:2015-07-21 15:57:14
【问题描述】:

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

项目(纬度、经度)

所以我真的遵循了nice post 并尝试以最高票数实现答案。第一件事:我必须在存储项目时添加更多列。这将在稍后启用选择语句:

项目(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、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);
    }
}

【问题讨论】:

    标签: android sqlite google-maps


    【解决方案1】:

    我实际上没有发现问题,但我重新设计了选择/位置,以便更容易阅读。现在它可以工作了。您也可以结帐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;
    }
    

    【讨论】:

    • 嗨。我遇到了你在问题中提到的同样的问题。没有值或所有值。这是一个可行的解决方案吗?这里的 ContentInfo 是什么?请帮忙
    • 我更改了代码并删除了我的数据结构 ContentInfo。你只需要字符串“selection”。代码工作正常,是的。我在我的应用程序中使用它。
    猜你喜欢
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 2013-10-25
    相关资源
    最近更新 更多