东林博客

高速公路公里桩经纬度坐标算法研究心得

最近朋友一个项目,需要得出任意一条高速公路公里桩的经纬度。用来追踪高速公路维护记录。网上找了一下,没有现成的数据源和开放接口。只有自己想办法来解决。

思路:

1、首先得需要知道高速公路的起始坐标和终点坐标。

2、根据百度地图接口算出此高速公路的轨迹。

3、根据轨迹中的轨迹点,平均算出每公里坐标的经纬度。

算法:

<script type="text/javascript">
  var map = new BMap.Map("allmap"); // 创建Map实例
  var point = new BMap.Point(102.604127, 24.976034);
map.centerAndZoom(point, 15);
  map.enableScrollWheelZoom(true);
  function PileToCoordinate(pileNum, startStakeCode,sPoint, nsPoint) {
  length_arr = [];
  if (sPoint == null || nsPoint == null) {
  return null;
  }
  pileNum = pileNum + "";
  //开始桩号
  var sPile = sPoint.stakeName;
  //结束桩号
  var ePile = nsPoint.stakeName;
  sPoint = new BMap.Point(sPoint.lng, sPoint.lat);
  nsPoint = new BMap.Point(nsPoint.lng, nsPoint.lat);
  var driving = new BMap.DrivingRoute(map);
  // 路径规划完回调函数
  driving.setSearchCompleteCallback(function (results) {
  var routePlan = results.getPlan(0);
  //路径规划返回规划点集合
  var pointArr = [];
  //用于存储相邻点间距离
  var len_arr = [];
  //事发起点和路径规划点集合,用于计算个点之间距离
  var tempArr = [];
  tempArr.push(sPoint);
  for (var i = 0; i < routePlan.getNumRoutes(); i++) {
  var route = routePlan.getRoute(i);
  for (j in route.getPath()) {
  pointArr.push(route.getPath()[j]);
  var marker = new BMap.Marker(route.getPath()[j]);
  map.addOverlay(marker);
  tempArr.push(route.getPath()[j]);
  }
  }
  pointArr.push(nsPoint);
  tempArr.push(nsPoint);
  //循环遍历取每相邻2个点距离
  for (var j = 0; j < tempArr.length - 1; j++) {
  len_arr.push(_fnGetDistanceKLD(tempArr[j], tempArr[j + 1]));
  }
  var po = null;
  if (pileNum.indexOf("k") >= 0 || pileNum.indexOf("K") >= 0) {
  pileNum = pileNum.substring(1, pileNum.length);
  }
  // 输入点与最近起点距离 例如 1210.2-1210
  var arr = parseFloat(pileNum) - parseFloat(startStakeCode);
  //单位千米 换算下
  var offSet = 1000 * parseFloat(parseFloat(arr));
  // 看路径规划后离输入点最近的2个点
  var length = 0;
  var index = 0;
  if (pointArr.length > 2 && offSet > 0) {
  for (var i = 0; i < len_arr.length; i++) {
  index = i;
  if (offSet > length && offSet < length + len_arr[i]) {
  break;
  }
  length += len_arr[i];
  }
  if (length == 0)
  {
  po = calculateStakeToPoint((offSet - length), sPoint, pointArr[index]);
  } else {
  po = calculateStakeToPoint((offSet - length), pointArr[index - 1], pointArr[index]);
  }
  } else {
  po = calculateStakeToPoint(offSet, pointArr[0], pointArr[1]);
  }
  if (po != null) {
  console.log(po)
  }
  });
  //路径规划 取最近2点间的所有点
  driving.search(sPoint, nsPoint);
  }
  /**
  * 计算两点间距离
  * @param offSet 离路径规划后最近起始点的距离
  * @param sPoint 离路径规划后最近起始点坐标
  * @param ePoint 离路径规划后最近终止点坐标
  * */
  function calculateStakeToPoint(offSet, sPoint, nsPoint) {
  var _startX = sPoint.lng;
  var _startY = sPoint.lat;
  var _endX = nsPoint.lng;
  var _endY = nsPoint.lat;
  var len = _fnGetDistanceKLD(sPoint, nsPoint);
  if (len == 0) {
  len = offSet;
  }
  // 看成1条直线 因为已经尽肯能精度了
  // 算出对应经纬度
  var ratio = (offSet / len) <= 1 ? (offSet / len) : 0.9;//如果系数大于1则设置为0.9,避免错乱
  var offSetX = parseFloat(parseFloat(ratio * (_endX - _startX)) + parseFloat(_startX));
  var offSetY = parseFloat(parseFloat(ratio * (_endY - _startY)) + parseFloat(_startY));
  var point = new BMap.Point(offSetX, offSetY);
  return point;
  }
  /**
  * 计算两点间距离
  * @param sPoint 起始桩号坐标
  * @param ePoint 终止桩号坐标
  * */
  function _fnGetDistanceKLD(sPoint, ePoint) {
  return map.getDistance(sPoint, ePoint);
  }
  PileToCoordinate('k7',0,{stakeName:"K1",lng:"102.63034",lat:"24.993773"},{stakeName:"K2",lng:"102.52858",lat:"24.942804"},)
</script>


{{tip}}