使用 Haversine 公式计算位置之间距离的问题

Problem with the calculating distance between locations using Haversine formula

我正在计算 Android 11 应用程序中 Yandex.Maps 的历史记录中的两点之间的距离。在 getPoints 方法中一切正常。我们将它们在我们数据库中的所有坐标写入数组列表。我什至实现了溢出、退出和数组检查。同样,到目前为止,一切都按预期进行得很好。

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

然而,当我试图用距离法计算长度时,SQLite数据库中存储的几个经纬度错误地计算了总距离,例如450公里,根据我们的数据,我们应该得到230公里。出现计算错误。

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);
}

我尝试使用半正弦公式计算距离。我还编写了将弧度转换为度数的函数,反之亦然。在距离法中,我使用haversine公式计算距离。我怀疑是计算距离的错误,也就是haversine公式的实现。

对于距离,您需要反向 Haversine 公式:

dlon = lon2 - lon1
dlat = lat2 - lat1
a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
c = 2 * atan2(sqrt(a), sqrt(1-a)) 
d = R * c

R = 6371 # mean radius of the Earth in km

(公式来源:link

在 Java 中的实现如下所示:

private double distance(double lat1, double lon1, double lat2, double lon2) {
    final int R = 6371;
    double latDistance = Math.toRadians(lat2 - lat1);
    double lonDistance = Math.toRadians(lon2 - lon1);
    double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) +
            Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                    Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    return R * c;
}
     /**
     * Calculate the distance between two points in meters using the Haversine formula
     *
     * @param lat latitude of the first point
     * @param lon longitude of the first point
     * @param lat2 latitude of the second point
     * @param lon2 longitude of the second point
     * @return the distance between the two points in meters            
     **/
    public static double distance(double lat, double lon, double lat2, double lon2) {
        final double R = 6371e3;
        final double la = lat * java.lang.Math.PI / 180;
        final double laa = lat2 * java.lang.Math.PI / 180;
        final double lo = (lat2 - lat) * java.lang.Math.PI / 180;
        final double loo = (lon2 - lon) * java.lang.Math.PI / 180;
        final double a = java.lang.Math.sin(lo / 2) * java.lang.Math.sin(lo / 2) + java.lang.Math.cos(la) * java.lang.Math.cos(laa) * java.lang.Math.sin(loo / 2) * java.lang.Math.sin(loo / 2);
        final double c = 2 * java.lang.Math.atan2(java.lang.Math.sqrt(a), java.lang.Math.sqrt(1 - a));
        return R * c;
    }