java 在SQLite数据库中计算经纬度值之间的距离

z0qdvdin  于 2023-11-15  发布在  Java
关注(0)|答案(2)|浏览(164)

免责声明这是一个家庭作业。请不要认真对待或思考这个问题超过2秒。这只是不值得的。对不起.

你好啊!我正在处理一个Android项目,我需要计算存储在SQLite数据库中的纬度和经度值之间的距离。我怀疑我的计算可能有问题。我想检索这些位置并计算它们之间的距离。

public ArrayList<Double> getPoints(){

    ArrayList<Double> location = new ArrayList<>();

    SQLiteDatabase db = this.getReadableDatabase();

    Cursor cursor = db.rawQuery("select latitude,longitude from " + Table_Name_Location, null);

    if(cursor.getCount() > 0){

        while(cursor.moveToNext()) {

            Double latitude = cursor.getDouble(cursor.getColumnIndex("Lat"));

            Double longitude = cursor.getDouble(cursor.getColumnIndex("Longi"));

            location.add(latitude);

            location.add(longitude);

        }

    }

    cursor.close();

    return location;

}

字符串
我一直在尝试使用半正矢公式计算距离。下面是我的代码的简化版本:

private double distance(double lat1, double lon1, double lat2, double lon2) {

    double theta = lon1 - lon2;

    double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))

                + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));

    dist = Math.acos(dist);

    dist = rad2deg(dist);

    dist = dist * 60 * 1.1515;

    return (dist);

}

private double deg2rad(double deg) {

    return (deg * Math.PI / 180.0);

}

private double rad2deg(double rad) {

    return (rad * 180.0 / Math.PI);

}


问题是我的代码没有返回预期的结果。我怀疑这个问题可能与半正矢公式有关,但我不完全确定。有人能帮助我确定问题或建议改进以正确计算距离吗?

drkbr07n

drkbr07n1#

我相信这几乎是正确的,只是半正矢公式假设纬度和经度的值是弧度。
因此,在公式中使用之前,只需将纬度和弧度转换为弧度。
你可以这样修改你的distance方法:

private double distance(double lat1, double lon1, double lat2, double lon2) {
   lat1 = deg2rad(lat1);
   lon1 = deg2rad(lon1);
   lat2 = deg2rad(lat2);
   lon2 = deg2rad(lon2);
   // rest of the code to be filled accordingly
}

字符串
现在,输入值以弧度为单位,这是半正矢公式正确工作所必需的。
请尝试一下。

l7mqbcuq

l7mqbcuq2#

好吧,我设置了一个小的env来测试,正如我所怀疑的那样,问题不在于公式本身,而在于测量系统。这个dist = dist * 60 * 1.1515;将返回以英里为单位的距离,所以如果你期望公里,它当然会关闭。要从英里转换,你需要乘以1.609344。
试试这个:

private double distance(double lat1, double lon1, double lat2, double lon2, bool kmConv) {

    double theta = lon1 - lon2;

    double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))

                + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));

    dist = Math.acos(dist);
    dist = rad2deg(dist);

    dist = dist * 60 * 1.1515;

    if (kmConv)
        dist *= 1.609344;

    return (dist);
}

字符串
我测试了一些值与Distance Calculator,它给了我(几乎)相同的结果(当然,除了一些舍入)。
还有,你有这个

Double latitude = cursor.getDouble(cursor.getColumnIndex("Lat"));

           Double longitude = cursor.getDouble(cursor.getColumnIndex("Longi"));


他们不是应该...

Double latitude = cursor.getDouble(cursor.getColumnIndex("latitude"));

           Double longitude = cursor.getDouble(cursor.getColumnIndex("longitude"));


.既然这些是列名?请仔细检查我提到的两种情况(错误的转换或错误的列名)。

**小提示:**我知道你说这不应该被认真对待,所以关于使用DB或选择什么类型的DB的讨论是不相关的。但是,我会强调你需要避免这种类型的编码:Cursor cursor = db.rawQuery("select latitude,longitude from " + Table_Name_Location, null); .虽然这是家庭作业,在任何正常的应用程序,这种风格(连接SQL语句)是一个主要的安全问题,因为它允许SQL注入。攻击向量是当在应用程序或网站的登录表单中使用这种类型的连接时。只是要记住未来的事情:)

相关问题