In the recent project, Tencent MAP GL version was used to meet the requirements of map, and the positioning and movement of ICONS on the map, as well as the selection of planning boxes for map areas and the planning of routes on the map.

In order to realize the on-demand loading of map JS, the link of Tencent map GL is encapsulated into a Promise, which is as follows

export function TMapGL(): Promise<void> {
  if (window.TMap) return Promise.resolve()
  return new Promise(function(resolve, reject) {
    var script = document.createElement('script')
    script.type = 'text/javascript'
    script.src = 'https://map.qq.com/api/gljs?v=1.exp&libraries=tools&key=' + MapKey
    script.onerror = () => reject()
    script.onload = () => resolve()
    document.head.appendChild(script)
  })
}
Copy the code

The logic here is to verify that the js of Tencent map has been loaded (whether the window has the TMap attribute), if so, resolve, otherwise start loading, and call a resolve in scripte.onload. Use the following

import React, { useEffect, UseRef} from 'react' import * as mapUtils from '@/utils/TMap/index' const mapId = useRef() useEffect() => { Maputils.tmapgl () // start loading Tencent map GL file. Then () => { Let center = new window.tmap.latLNG (initpoint.lat, InitPoint. LNG) let map = new window.tmap. map (document.querySelector('#container'), {center, zoom: 16.2, baseMap: [{type: 'vector'}, vector reproduction / / / / set {type: "traffic"}, / / set the road map],}) mapId. Current = map / / store the current map})}, [])Copy the code

Map loading effect drawing

Since real-time road conditions consume large resources, it is better to avoid setting the initial map. If you want to switch to the real-time road map after initialization, setBaseMap is given to set the map base map by querying the document, as follows

let map = mapId.current
map.setBaseMap([
  { type: 'traffic' }
])
Copy the code

For the movement of points on the map, our requirement is that multiple points locate and move simultaneously on the map. Since websocket is not used, we regularly request the interface to obtain data before rendering. After obtaining new data, we compare it with the previous array. Then generate the path and move (if there is no judgment to directly use the same coordinate point as the path to move, will report an error), otherwise unchanged, the effect picture is as follows

Multi-point real-time coordinates

Lines are drawn using the geometry provided by the map, and the renderer initializes the drawing by referring to the official document point/line/surface (fence) edit

One point worth noting is that the official document only mentions that the graph can be deleted after being selected in editing, but it does not give how to delete the graph after drawing. After referring to and comparing the object returned after generating the line in normal way with the attribute of drawing the object editor, a method is found as follows

let list: Array<any> = editor.getOverlayList() if (! list.length) return list.map(item => item.overlay.setGeometries([]))Copy the code

In the past, you could use setMap(NULL) to clear points or lines, but this will not work and will cause an error. Presumably because the overlayList passed in during initialization is not allowed to be cleared completely.

This article is formatted using MDNICE