openlayers+高德地图驾车规划 实现路况实现信息和驾车路径

358 阅读2分钟

效果展示

palen.gif

HTML 结构

 <div class="path_plane">
    <div class="btns">
      <el-button size="mini" type="primary" @click="Setup('start')"
        >设置起点</el-button
      >
      <el-button size="mini" type="success" @click="Setup('end')"
        >设置终点</el-button
      >
      <el-select v-model="type" style="padding: 0 10px">
        <el-option
          v-for="item in Options"
          :key="item.code"
          :label="item.name"
          :value="item.code"
        >
        </el-option>
      </el-select>
      <el-button size="mini" type="primary" @click="search">搜索</el-button>
      <el-button size="mini" type="info" @click="Setup('clear')"
        >清除路径</el-button
      >
    </div>
    <div id="pathPlane" class="dynamic-component-demo"></div>
  </div>

起点、终点图标样式生产函数

function MarkStyleFn(feature) {
    return new Style({
      image: new Icon({
        src: mark,
        scale: 1,
      }),
      text: new Text({
        textAlign: "center",
        textBaseline: "middle",
        font: "normal 12px 微软雅黑",
        text: feature.get("name"),
        fill: new Fill({ color: "#aa3300" }),
        stroke: new Stroke({ color: "#ffcc33", width: 1 }),
        offsetY: 0,
      }),
    });
}
function showMark(point, name) {
    return new VectorLayer({
      style: MarkStyleFn,
      source: new VectorSource({
        features: [
          new Feature({
            geometry: new Point(point),
            name,
          }),
        ],
      }),
      zIndex: 1000000000000,
    });
}

路径样式

function palneLineStyle(featrue, resolution) {
  var status = featrue.get("status"),_color = "#8f8f8f";
  if (status === "拥堵"){ _color = "red"}
  else if (status === "缓行"){ _color = "yellow"}
  else if (status === "畅通") {_color = "green"};
  return new Style({
    stroke: new Stroke({
      color: _color,
      width: 10,
    }),
  });
}

vue 初始化数据

 data() {
    return {
      map: null,
      result: "",
      startLngLat: null,
      endLngLat: null,
      startVector: null,
      endVector: null,
      planeVector: null,
      type: "LEAST_TIME",
      Options: [
        { code: "LEAST_TIME", name: "最快捷模式" },
        { code: "LEAST_FEE", name: "最经济模式" },
        { code: "LEAST_DISTANCE", name: "最短距离模式" },
        { code: "REAL_TRAFFI", name: "考虑实时路况" },
      ],
    };
  },

地图初始化

mounted() {
    let map = new Map({
      // 设置地图图层
      layers: [gaodeMapLayer],
      // 设置显示地图的视图
      view: new View({
        center: CD,
        zoom: 9,
        projection: "EPSG:4326",
        //rotation: 0,
      }),
      target: "pathPlane",
      interactions: defaultInteractions({
        doubleClickZoom: false, // 取消双击放大功能交互
        // mouseWheelZoom: false, // 取消滚动鼠标中间的滑轮交互
        // shiftDragZoom: false, // 取消shift+wheel左键拖动交互
      }),
    });
    this.clickMap(map);
    this.map = map;
  },
 methods: {
    clickMap(map) {
      map.on("click", (evt) => {
        var coordate = evt.coordinate,
          { result, startLngLat, endLngLat } = this;
        switch (result) {
          case 1:
            if (!startLngLat) {
              this.startLngLat = coordate;
              let startVector = showMark(coordate, "起");
              this.startVector = startVector;
              map.addLayer(startVector);
            }
            break;
          case 2:
            if (!endLngLat && startLngLat) {
              this.endLngLat = coordate;
              let endVector = showMark(coordate, "终");
              this.endVector = endVector;
              map.addLayer(endVector);
            }
            break;
        }
      });
    }, 
 }

按钮功能实现

 methods: {
    search() {
      let { startLngLat, endLngLat, type, planeVector, map } = this;
      map.removeLayer(planeVector);
      this.getAMapLoader(startLngLat, endLngLat, type);
    },
  Setup(code) {
      let { map, planeVector, startVector, endVector } = this;
      switch (code) {
        case "start":
          this.result = 1;
          break;
        case "end":
          this.result = 2;
          break;
        case "clear":
          this.result = 0;
          this.startLngLat = null;
          this.endLngLat = null;
          this.endVector = null;
          this.startVector = null;
          this.planeVector = null;
          map.removeLayer(planeVector);
          map.removeLayer(startVector);
          map.removeLayer(endVector);
          break;
      }
  },
}    

高德api实现驾车路径规划和openlayers渲染

methods: {
  getAMapLoader(startLngLat, endLngLat, type) {
      let _this = this;
      AMapLoader.load({
        key: "xxxx", // 申请好的Web端开发者Key,首次调用 load 时必填
        version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
        plugins: ["AMap.Driving"], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
      })
        .then((AMap) => {
          var driving = new AMap.Driving({
            // AMap.DrivingPolicy.LEAST_TIME
            // 最快捷模式
            // AMap.DrivingPolicy.LEAST_FEE
            // 最经济模式
            // AMap.DrivingPolicy.LEAST_DISTANCE
            // 最短距离模式
            // AMap.DrivingPolicy.REAL_TRAFFI
            // 考虑实时路况
            policy: AMap.DrivingPolicy[type],
          });
          // console.log(driving.search, "driving");
          let a = driving.search(
            startLngLat,
            endLngLat,
            {},
            function (stute, result) {
              _this.initFeature(result);
            }
          );
        })
        .catch((e) => {
          console.error(e);
        });
    },
    initFeature(result) {
      let { map } = this;
      var routes = result["routes"][0];
      var steps = routes["steps"];
      var features = [];
      for (var i = 0; i < steps.length; i++) {
        var route = steps[i];
        var path = route["tmcs"];
        for (var k = 0; k < path.length; k++) {
          var routePath = path[k];
          var distance = routePath["distance"];
          var polyline = routePath["polyline"].toString().split(";");
          var status = routePath["status"];
          var polylineData = [];
          for (var j = 0; j < polyline.length; j++) {
            //将字符串拆成数组
            var realData = polyline[j].split(",");
            var coordinate = [realData[0], realData[1]];
            polylineData.push(coordinate);
          }
          //线要素类
          var feature = new Feature({
            attr: { distance },
            status: status,
            geometryName: "centerMark",
            geometry: new LineString(polylineData),
          });
          //线此处注意一定要是坐标数组
          features.push(feature);
        }
      }
      this.palneLine(features);
    },
    palneLine(features) {
      let { map } = this;
      const vector = new VectorLayer({
        style: palneLineStyle,
        source: new VectorSource({
          features: features,
        }),
      });
      this.planeVector = vector;
      map.addLayer(vector);
    },
  },
}

温馨提示:路径有偏差可以使用高德路径纠偏进行路径修正