最近在做有关车辆定位及历史轨迹的项目,需要显示车辆当前位置信息、车辆历史轨迹及行驶公里数,需要这样的效果。

轨迹回放使用的百度的路书功能,包含了开始、暂定、重置功能,但是后台返回的数据只包含了坐标点,

行驶里程数需要前台页面计算。开始查资料,百度提供计算里程的api,提供开始和结束的几个坐标点,再选择是骑车、步行、驾车、是否走高速之类的条件,百度自动计算行车里程,但是这种误差相对比较大,于是放弃。换了另一种方案,根据两个坐标点计算段之间的距离,再累加,这种计算的是实际行驶的里程,开始coding。
先找到计算两个坐标点之间距离的方法
// 计算两个坐标点距离 | |
getFlatternDistance(lon1, lat1, lon2, lat2) { | |
var DEF_PI = 3.14159265359; // PI | |
var DEF_2PI = 6.28318530712; // 2*PI | |
var DEF_PI180 = 0.01745329252; // PI/180.0 | |
var DEF_R = 6370693.5; // radius of earth | |
var ew1, ns1, ew2, ns2; var dx, dy, dew; var distance; // 角度转换为弧度 | |
ew1 = lon1 * DEF_PI180; | |
ns1 = lat1 * DEF_PI180; | |
ew2 = lon2 * DEF_PI180; | |
ns2 = lat2 * DEF_PI180; | |
// 经度差 | |
dew = ew1 - ew2; // 若跨东经和西经180 度,进行调整 | |
if (dew > DEF_PI) dew = DEF_2PI - dew; | |
else if (dew < -DEF_PI) dew = DEF_2PI + dew; | |
dx = DEF_R * Math.cos(ns1) * dew; // 东西方向长度(在纬度圈上的投影长度) | |
dy = DEF_R * (ns1 - ns2); // 南北方向长度(在经度圈上的投影长度) | |
// 勾股定理求斜边长 | |
distance = Math.sqrt(dx * dx + dy * dy).toFixed(0); | |
return distance; | |
} |
获取坐标集合,调用计算公式
// 计算里程数 | |
calculateMileage(history) { | |
let mileage = 0; | |
for (let i = 0; i < history.length - 1; i++) { | |
mileage += parseInt( this.getFlatternDistance( history[i].longitude, | |
history[i].latitude, | |
history[i + 1].longitude, | |
history[i + 1].latitude | |
) ); } this.mileage = mileage == 0 ? "--:--" : (mileage / 1000).toFixed(2) + "公里"; | |
} |
mileage就是最后的里程数。看下计算时间
749个坐标点,用时1.39501953125ms,对页面显示影响不大。至此结束。
获取更多优质内容,请关注【青年码农】
正文完