Tencent map api, draw customized arrows according to the route

What I encountered:

1. Use Tencent map to draw the path and indicate the direction on the map (that is, the arrow points)

I checked a lot of information, but there was no detailed conclusion. I customized the effect according to the method given by the api
vue+element+ Tencent map API, (for reference only)
The renderings are as follows:


1. First, check whether it is the same as the method I use to declare the method of Map. Tencent maps' JavaScript api and GL api (if different, you can see the logic. The logic is the same, but you need to study the code yourself)
2. If you see this, let me talk about the logic first. I have considered the scheme before:
(1) The arrow of the line segment in the map points to (inconsistent with the actual demand), and the arrow cannot be larger than the specific width, so we can't expand it. We really gave up. (I hope Tencent map api can be improved here.)

Example address:
This is the api address:

(2) Custom DOM overlay is the most searched scheme in Baidu, but I have seen it. It can be achieved by declaring the IMG structure (IMG is the picture of the arrow) and rotating it from different angles according to the img. However, a bug will appear, that is, it will not change with the zoom of the map. This is very annoying, so I didn't consider it (the test will definitely give me a bug)
(3) The one I currently use is to judge the angle according to the coordinates of two points, get the triangle coordinates of the arrow and draw two lines, which are combined into an arrow shape (white point: the arrow drawn is the same as the line drawn)
(4) Draw according to the polygon drawing, but the principle is the same. First find the triangle coordinates of the arrow, and then process it. It depends on the specific needs. (if the arrow is covered with color, get the coordinates first, and draw the polygon. The effect can also be achieved.). Key point: get the coordinates of the three corners of the arrow!!!
(5) Other schemes are similar in that they are drawn according to requirements and coordinates.

Now let me talk about the third one

1. Declare the map and polylineLayer (the map in front and the line in the back). I will not paste the declaration of points. I should sprinkle points at any point

<div class="echarts_heating" id="map"></div> //html

var map = new TMap.Map(document.getElementById("map"), {
    zoom: 11, //Set map zoom level
    center: center, //Set coordinates of map center point
    mapStyleId: "style1", //Personalized style default style
    disableDefaultUI: true,
    showControl: false,
    baseMap: {
      type: "vector",
      features: ["base", "building3d", "point"], // Hidden vector text can be configured as required
    // mapStyleId: "style1", / / set the style ID. in this example, the style1 bound by the key is a classic map style
    //(if an unbound style or invalid ID is used, an error will be prompted and displayed in the map default style)

Declaration of polylineLayer and style of line segment

var polylineLayer = new TMap.MultiPolyline({
    map, // Draw to target map
    // Polyline style definition
    styles: {
      style_blue: new TMap.PolylineStyle({
        color: "#F15E59 ", / / line fill color
        width: 3, // Polyline width
        lineCap: "round", // Wire end mode
      style_dash: new TMap.PolylineStyle({
        color: "#F15E59 ", / / line fill color
        width: 3, // Polyline width
        lineCap: "butt", // Wire end mode
        dashArray: [6, 5], // Dotted line display mode
    geometries: [],

In the methods of vue

 //arr refers to the coordinates of points. The [start point and end point] index and indexli are generated for different IDs. They are convenient for different naming and can be cancelled
computeHeading(arr, index, indexli) {
  // Query the distance before two points according to computeDistance
  let computeDistance = TMap.geometry.computeDistance(arr);
  // Query the distance between two points. If the distance is too short, no processing will be performed
  if (computeDistance > 1500) {
    let computeHeading = TMap.geometry.computeHeading(arr[0], arr[1]);
    // Obtain the angle of the current point according to computeHeading

    let du; //This variable is only the reverse angle declared so that the top of the arrow does not overlap the icon
    if (computeHeading > 0) {
      du = computeHeading - 180;
      // Because there is only [180, -180] in the coordinate system of the map, the counterclockwise conversion is performed
    } else {
      du = computeHeading + 180;
    // path0 is the coordinate of the new arrow vertex obtained in reverse according to computeDestination
    // Where 200 is the distance between icon and vertex, which can be adjusted
    let path0 = TMap.geometry.computeDestination(arr[1], du, 200);
    // top1 and top2 are obtained from the angle at which the arrow is drawn,
    // Because there is only [180, -180] in the coordinate system of the map, the counterclockwise conversion is performed
    // I got an offset of 40 degrees, 140220, adjustable
    let top1 = this.computeRotaion(computeHeading + 140);
    let top2 = this.computeRotaion(computeHeading + 220);
    // path1 and path2 are used to obtain the coordinates of points on both sides of the arrow according to the coordinates of the arrow, the length and angle of the drawn line segment
    let path1 = TMap.geometry.computeDestination(path0, top1, 1200);
    let path2 = TMap.geometry.computeDestination(path0, top2, 1200);
    // console.log("path1", path1);
    // Draw according to the left of the three points of the arrow. You can also draw coverage polygons index and indexli here. They can be modified or cancelled as long as they are different IDs
      styleId: "style_blue",
      id: "pl1_" + index + "_" + indexli,
      paths: [path0, path1],
      styleId: "style_blue",
      id: "pl2_" + index + "_" + indexli,
      paths: [path0, path2],
    // Make different plans according to different lengths. For those with a length of more than 10000 meters, I will make the arrow in the middle. The principle is the same as above//
    if (computeDistance > 10000) {
      // Get the coordinates of the middle point first
      let pathzhong = TMap.geometry.computeDestination(
        computeDistance / 2
      // path3 and path4 are the coordinates of points on both sides of the middle arrow,
      let path3 = TMap.geometry.computeDestination(pathzhong, top1, 1200);
      let path4 = TMap.geometry.computeDestination(pathzhong, top2, 1200);
      // Draw lines according to the three-point coordinates, and make arrows index and indexli, which can be modified or cancelled, as long as they are different IDS
        styleId: "style_blue",
        id: "pl3_" + index + "_" + indexli,
        paths: [pathzhong, path3],
        styleId: "style_blue",
        id: "pl4_" + index + "_" + indexli,
        paths: [pathzhong, path4],
// Because the range of map coordinates is [180, -180], it is converted
computeRotaion(heading) {
  let rotation;
  if (heading > 180) {
    rotation = heading - 360;
  } else {
    rotation = heading;
  return rotation;

There are complete explanations in the notes. You need to be patient to read them, or you can modify them according to your own situation. I haven't encapsulated it here, but it can be used normally. If you need to encapsulate multiple component calls, I won't take out what I need to encapsulate here. After all, the requirements are different


Hope to give more comments and have better suggestions. You can leave a message and learn with an open mind!

Humble Xiao Liu!

Tags: Vue.js html5 Front-end

Posted by kimbeejo on Tue, 31 May 2022 20:48:49 +0530