使用天地图+openlayers 实现路径导航(驾车)

获取路径数据

axios.get('https://api.tianditu.gov.cn/drive?postStr={orig:"' + start + '",dest:"' + end + '",style:"0"}&type=search&tk=你的token', {})
  .then(res=>{
    if (res?.status == 200){
      let parser = new DOMParser();
      let xmlDoc = parser.parseFromString(res.data, "application/xml");
      let routelatlon = xmlDoc.getElementsByTagName("routelatlon")[0].textContent
      routelatlon = routelatlon.substring(0, routelatlon.length - 1);
      let routes = xmlDoc.getElementsByTagName("routes")[0].getElementsByTagName("item")
      routesTxtList.value = []
      for (let i = 0; i < routes.length; i++) {
        let strguide = routes[i].getElementsByTagName("strguide")[0];
        let text = strguide.textContent;  // 获取文本内容
        routesTxtList.value.push(text)
      }
      let list = routelatlon.split(";").map(e=>{
        return [parseFloat(e.split(",")[0]), parseFloat(e.split(",")[1])]
      })
      addTrack(list);
      lif.value = '20px'
      setTimeout(()=>{
        startMove()
      },2000)
    }
  })

其中addTrack 是画路径

startMove是车辆移动方法

routesTxtList是每段导航的文本信息

//以下是巡查轨迹的代码
function createLuxianLayer(trackLine) {
  const trackFeature = new Feature({
    type: "track",
    geometry: trackLine,
  });
  const geoMarker = new Feature({
    type: "geoMarker",
    geometry: new Point(passCoordinates.value[0]),
  });
  geoMarker.setId("point");
  const startMarker = new Feature({
    type: "iconStart",
    geometry: new Point(passCoordinates.value[0]),
  });
  const endMarker = new Feature({
    type: "iconEnd",
    geometry: new Point(
      passCoordinates.value[passCoordinates.value.length - 1]
    ),
  });
  const styles = {
    track: new Style({ //轨迹样式
      stroke: new Stroke({
        width: 3,
        color: '#54ff9f',
      }),
    }),
    iconEnd: new Style({//终点
      image: new Icon({
        anchor: [0.5, 1],
        scale: 1,
        src: LuxianImg("endMark"),
      }),
    }),
    iconStart: new Style({//起点
      image: new Icon({
        anchor: [0.5, 1],
        src: LuxianImg("start"),
        scale: 1, //设置大小
      }),
    }),
    geoMarker: new Style({ //车标
      image: new Icon({
        src: LuxianImg("trackCar"),
        scale: 1,
        size: [32, 32],
        anchor: [0.5, 1],
        offsetY: "32",
      }),
    }),
  };
  trackLayer.value = new VectorLayer({
    source: new VectorSource({
      features: [trackFeature, geoMarker, startMarker, endMarker],
    }),
    style: (feature) => {
      return styles[feature.get("type")];
    },
    zIndex: 30,
  });
  map.value.addLayer(trackLayer.value);
}
function move(evt) {
  const frameState = evt.frameState;
  // 执行动画已经过了多少时间(秒)
  const timeout = (frameState.time - startTime.value) / 1000;
  let count = Math.round(speed * timeout);

  if (count >= passCoordinates.value.length - 1) {
    // 确保到达最后一个点位,并停止移动动画
    count = passCoordinates.value.length - 1;
    stopMove();
  }
  const point = trackLayer.value.getSource().getFeatureById("point");
  point.getGeometry().setCoordinates(passCoordinates.value[count]);
  map.value.render();
}
function startMove() {
  startTime.value = new Date().getTime();
  map.value.on("postrender", move);
  // 第一次需要手动调用一遍,否则不执行postcompose
  map.value.render();
}

function stopMove() {
  map.value.un("postrender", move);
}
function addTrack(coordinates) {
  const trackLine = new LineString(coordinates);
  // 轨迹在投影平面上的长度
  const trackLineLen = trackLine.getLength();
  // 使用轨迹线计算边界矩形
  var bounds = trackLine.getExtent();
  // 使用`fitBounds`方法应用边界
  map.value.getView().fit(bounds);
  // 当前平面的分辨率
  const resolution = map.value.getView().getResolution();

  // 点有可能是小数,要到终点需要手动添加最后一个点
  const pointCount = trackLineLen / (resolution * particle);
  for (let i = 0; i <= pointCount; i++) {
    passCoordinates.value.push(trackLine.getCoordinateAt(i / pointCount));
  }
  passCoordinates.value.push(coordinates[coordinates.length - 1]);
  map.value.setView(new View({
    center: [(parseFloat(coordinates[0][0]) + 0.03), parseFloat(coordinates[0][1])],
    projection: 'EPSG:4326',
    zoom: 14,
  }))
  createLuxianLayer(trackLine);
}
function removeTrak() {
  if (trackLayer.value && map.value) {
    map.value.removeLayer(trackLayer.value);
    passCoordinates.value = [];
    trackLayer.value = null;
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值