Haversine公式实现异常:路线距离计算结果不准确求助
免责声明:此为家庭作业,请不要认真对待,也请勿为该问题花费超过2秒时间,不值得为此费心,抱歉。
问题:Haversine公式计算路线距离结果不准确
我正尝试计算路线的近似距离。getPoints方法负责从SQLite数据库中获取所有路线点并写入ArrayList数组,该部分运行符合预期。但在执行距离计算时出现问题,Haversine公式计算出的距离结果不准确。我推测问题出在distance方法中,但无法自行定位问题,对比原版Haversine公式实现也未发现差异。
代码片段如下:
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); }
问题排查及修复方案
数据库字段名不匹配
SQL查询的字段是latitude和longitude,但取字段值时用的是"Lat"和"Longi",如果数据库实际字段名是前者,会导致获取到错误的经纬度值,直接影响距离计算结果。修改getColumnIndex的参数为查询的字段名:Double latitude = cursor.getDouble(cursor.getColumnIndex("latitude")); Double longitude = cursor.getDouble(cursor.getColumnIndex("longitude"));余弦定理版本的精度缺陷
当前distance方法用的是余弦定理实现,当两点距离极近时,Math.acos容易因浮点精度问题出现误差。改用标准Haversine公式实现,近距离计算精度更稳定:private double distance(double lat1, double lon1, double lat2, double lon2) { final int EARTH_RADIUS_KM = 6371; // 地球半径(公里),要英里则改为3956 double dLat = deg2rad(lat2 - lat1); double dLon = deg2rad(lon2 - lon1); double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return EARTH_RADIUS_KM * c; }缺失路线距离累加逻辑
如果要计算整条路线的总距离,需要遍历getPoints返回的列表,依次计算相邻两点的距离并累加:public double getTotalRouteDistance() { ArrayList<Double> points = getPoints(); double total = 0; // 每次取两组经纬度,步进为2 for (int i = 0; i < points.size() - 3; i += 2) { total += distance(points.get(i), points.get(i+1), points.get(i+2), points.get(i+3)); } return total; }
内容的提问来源于stack exchange,提问作者elfxea
相关产品推荐
相关产品推荐

