You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

路线近似距离计算异常:Haversine公式实现问题排查求助

问题排查与修复方案

1. 数据库列名不匹配的潜在问题

你的getPoints方法中存在SQL查询字段与游标获取字段不匹配的问题:

Cursor cursor = db.rawQuery("select latitude,longitude from " + Table_Name_Location, null);
// 游标获取时用的是"Lat"和"Longi",与查询的字段名不一致
Double latitude = cursor.getDouble(cursor.getColumnIndex("Lat"));
Double longitude = cursor.getDouble(cursor.getColumnIndex("Longi"));

如果数据库表的实际列名是latitude和longitude,getColumnIndex("Lat")会返回-1,调用getDouble(-1)会读取错误值或抛出异常。请根据数据库实际列名修正:

  • 若表列名为Lat、Longi,修改SQL语句为select Lat, Longi from ...
  • 若表列名为latitude、longitude,修改游标获取参数为"latitude"和"longitude"

2. Haversine公式的单位转换问题

当前distance方法返回的是英里(* 60 * 1.1515是海里转 statute miles的系数),如果预期结果是公里,需调整单位转换逻辑:

// 转换为公里:1海里 = 1.852公里
dist = dist * 60 * 1.852;

若确实需要英里,此部分无需修改,但单位误解是结果“不正确”的常见原因。

3. Haversine公式的精度优化(可选)

使用acos的实现在两点极近时会有浮点精度问题,建议改用更稳定的半正矢公式:

private double distance(double lat1, double lon1, double lat2, double lon2) {
    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));
    double dist = 6371 * c; // 地球半径(公里),需英里则替换为3956
    return dist;
}

4. 路线点遍历逻辑验证

确认调用distance时,正确遍历ArrayList中的相邻点:

ArrayList<Double> points = getPoints();
double totalDistance = 0;
// 每次步进2,确保取到相邻的[lat, lon]对
for (int i = 0; i < points.size() - 2; i += 2) {
    double lat1 = points.get(i);
    double lon1 = points.get(i+1);
    double lat2 = points.get(i+2);
    double lon2 = points.get(i+3);
    totalDistance += distance(lat1, lon1, lat2, lon2);
}

若遍历索引错误(如每次i++),会导致把经度和下一个纬度当作一组点计算,结果完全错误。

内容的提问来源于stack exchange,提问作者Eex1e

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:25:21