Implementing Map Routes and Trajectory Tracking with vue-baidu-map in Vue.js

Overview

This guide covers embedding Baidu Maps in a Vue.js application with features including route planning, trajectory tracking, markers, and map type switching.

Prerequisites

Install the vue-baidu-map package:

npm install vue-baidu-map --save

Configuration

Obtain a API key (AK) from the Baidu Maps API platform. Register your application and note the generated AK.

Project Setup

Register the plugin in main.js:

import BaiduMap from 'vue-baidu-map'

Vue.use(BaiduMap, {
  ak: 'YOUR_BAIDU_MAP_API_KEY'
})

Map Component Implemantation

Create a map component with trajectory and routing capabilities:

<template>
  <div class="map-container">
    <el-card style="height: 60vh">
      <baidu-map
        class="bm-view"
        :zoom="15"
        :center="mapCenter"
        inertial-dragging
        @ready="onMapReady"
        :scroll-wheel-zoom="true"
      >
        <!-- Geolocation Control -->
        <bm-geolocation 
          anchor="BMAP_ANCHOR_BOTTOM_RIGHT" 
          :showAddressBar="true"
          :autoLocation="true"
        />
        
        <!-- Map Type Switcher -->
        <bm-map-type 
          :map-types="['BMAP_NORMAL_MAP', 'BMAP_HYBRID_MAP']"
          anchor="BMAP_ANCHOR_TOP_LEFT"
        />
        
        <!-- Navigation Controls -->
        <bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT" />
        
        <!-- Trajectory Polyline -->
        <new-polyline 
          :path="trajectoryPath" 
          :editing="false" 
          :icons="directionIcons" 
          stroke-color="#8ba0fb"
          :stroke-opacity="1" 
          :stroke-weight="8"
        />
        
        <!-- Start Marker -->
        <bm-marker :position="originPoint" :dragging="true">
          <bm-label 
            content="Start" 
            :labelStyle="{ color: 'black', fontSize: '16px' }"
            :offset="{ width: -35, height: 30 }" 
          />
        </bm-marker>
        
        <!-- End Marker -->
        <bm-marker :position="destinationPoint" :dragging="true">
          <bm-label 
            content="End" 
            :labelStyle="{ color: 'black', fontSize: '16px' }"
            :offset="{ width: -35, height: 30 }" 
          />
        </bm-marker>
      </baidu-map>
    </el-card>
  </div>
</template>

<script>
import {
  BaiduMap,
  BmControl,
  BmView,
  BmAutoComplete,
  BmLocalSearch,
  BmMarker,
  BmGeolocation,
  BmlLushu
} from "vue-baidu-map";

import newPolyline from "./new_polyline.vue";

export default {
  components: {
    BaiduMap,
    BmControl,
    BmView,
    BmAutoComplete,
    BmLocalSearch,
    BmMarker,
    BmGeolocation,
    newPolyline,
    BmlLushu,
  },
  data() {
    return {
      mapCenter: {
        lng: 116.404,
        lat: 39.915
      },
      trajectoryPath: [
        { lng: 116.404, lat: 39.915 },
        { lng: 116.405, lat: 39.920 },
        { lng: 116.423493, lat: 39.907445 }
      ],
      vehiclePath: [],
      originPoint: { lng: 116.404, lat: 39.915 },
      destinationPoint: { lng: 116.423493, lat: 39.907445 },
      directionIcons: [],
      icon: {
        url: "https://s1.ax1x.com/2023/06/20/pC80IAJ.png",
        size: {
          width: 52,
          height: 52,
        },
        labelText: "Vehicle",
        color: "",
        start: "",
        end: "",
        speed: 20,
        showPath: false,
        enableRotation: true,
        BMaps: undefined
      },
    };
  },
  methods: {
    fetchRouteData() {
      fetchRouteDetails(this.routeId).then(response => {
        if (response.status === 200) {
          this.routeData = response.data;
          const waypoints = JSON.parse(response.data.path).map(point => ({
            lng: point.longitude,
            lat: point.latitude,
          }));
          this.trajectoryPath = waypoints;
          this.updateTrajectory();
        }
      });
    },
    onMapReady({ BMap, map }) {
      this.fetchRouteData();
      this.vehiclePath = [];
      
      const app = this;
      
      // Convert trajectory points to BMap coordinates
      this.trajectoryPath.forEach(point => {
        this.vehiclePath.push(
          new BMap.Point(point.lng, point.lat)
        );
      });

      // Configure direction arrow symbols
      const arrowSymbol = new BMap.Symbol(BMap_Symbol_SHAPE_FORWARD_OPEN_ARROW, {
        scale: 1,
        strokeColor: "#fff",
        strokeWeight: "2"
      });
      
      const arrowIcon = new BMap.IconSequence(arrowSymbol, "10", "30");
      app.directionIcons.push(arrowIcon);
    },
    resetPlayback() {
      this.isPlaying = false;
    },
    updateTrajectory() {
      this.startPoint = this.trajectoryPath[0];
      this.endPoint = this.trajectoryPath[this.trajectoryPath.length - 1];
      this.isPlaying = true;
    },
  },
  created() {
    if (this.routeId) {
      this.fetchRouteData();
    }
  },
};
</script>

<style>
.bm-view {
  height: 500px;
  margin-top: 20px;
  width: 100%;
}

.map-container {
  float: left;
  width: 100%;
}
</style>

Custom Polyline Component

To render polylines with directional arrows, create a custom component:

<template>
  <div></div>
</template>

<script>
import commonMixin from "vue-baidu-map/components/base/mixins/common.js";
import bindEvents from "vue-baidu-map/components/base/bindEvent.js";
import { createPoint } from "vue-baidu-map/components/base/factory.js";

export default {
  name: "new-polyline",
  render() {},
  mixins: [commonMixin("overlay")],
  props: {
    path: {
      type: Array
    },
    icons: {
      type: Array
    },
    strokeColor: {
      type: String
    },
    strokeWeight: {
      type: Number
    },
    strokeOpacity: {
      type: Number
    },
    strokeStyle: {
      type: String
    },
    massClear: {
      type: Boolean,
      default: true
    },
    clicking: {
      type: Boolean,
      default: true
    },
    editing: {
      type: Boolean,
      default: false
    }
  },
  watch: {
    path: {
      handler(val, oldVal) {
        this.reload();
      },
      deep: true
    },
    strokeColor(val) {
      this.originInstance.setStrokeColor(val);
    },
    strokeOpacity(val) {
      this.originInstance.setStrokeOpacity(val);
    },
    strokeWeight(val) {
      this.originInstance.setStrokeWeight(val);
    },
    strokeStyle(val) {
      this.originInstance.setStrokeStyle(val);
    },
    editing(val) {
      val
        ? this.originInstance.enableEditing()
        : this.originInstance.disableEditing();
    },
    massClear(val) {
      val
        ? this.originInstance.enableMassClear()
        : this.originInstance.disableMassClear();
    },
    clicking(val) {
      this.reload();
    }
  },
  methods: {
    load() {
      const {
        BMap,
        map,
        path,
        icons,
        strokeColor,
        strokeWeight,
        strokeOpacity,
        strokeStyle,
        editing,
        massClear,
        clicking
      } = this;
      
      const overlay = new BMap.Polyline(
        path.map(item =>
          createPoint(BMap, {
            lng: parseFloat(item.lng),
            lat: parseFloat(item.lat)
          })
        ),
        {
          strokeColor,
          strokeWeight,
          strokeOpacity,
          strokeStyle,
          icons,
          enableEditing: editing,
          enableMassClear: massClear,
          enableClicking: clicking
        }
      );
      
      this.originInstance = overlay;
      map.addOverlay(overlay);
      bindEvents.call(this, overlay);
    }
  }
};
</script>

Key Components

Component Purpose
BaiduMap Main map container
BmGeolocation User location detection
BmMapType Switch between map types
BmNavigation Zoom controls
BmMarker Location markers
BmlLushu Enimated marker movement
Custom Polyline Trajectory visualization

Available Map Types

  • BMAP_NORMAL_MAP - Standard map view
  • BMAP_HYBRID_MAP - Satellite view with labels

Tags: Vue.js baidu-maps vue-baidu-map maps trajectory

Posted on Fri, 15 May 2026 06:33:07 +0000 by alexislalas