关于腾讯地图gl版在react+ts中的使用

4,521 阅读2分钟

近期项目中有地图的需求,以及需要实现图标在地图上面的定位和移动,还有地图区域的规划框选,地图上线路的规划,综合考虑使用了腾讯地图gl版。

为了实现地图js的按需加载,将腾讯地图gl的链接封装成一个Promise,封装后如下

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)
  })
}

这里的逻辑是,先验证腾讯地图js是否已经加载过(window中是否有TMap这个属性),如果有则直接resolve,否则开始加载,并在scripte.onload回调一个resolve。使用如下

import React, { useEffect, useRef } from 'react'
import * as mapUtils from '@/utils/TMap/index'

const mapId = useRef() //  地图实例

useEffect(() => {
    mapUtils
      .TMapGL() // 开始加载腾讯地图gl文件
      .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' }, //设置矢量底图
              // { type: 'traffic' }, //设置路况底图
            ],
          })
          mapId.current = map //存储当前的map
      })
  }, [])

地图加载效果图

由于实时路况消耗资源较大,初始地图时避免设置较好,当初始化地图后如果想再切换到实时路况地图的话,通过查询文档发现给了setBaseMap这个方法来设置地图底图,使用如下

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

对于点位在地图上的移动,我们的需求是多个点在地图上同时定位并且移动,由于没有使用websocket,所以就定时请求接口获取数据后再进行渲染,获取到新数据后,与前一组数组进行对比,如果同一个点位的经纬度发生了变化,那么就生成路径并且移动(如果没有判断直接使用相同的坐标点作为路径去移动,会报错),否则不变,效果图如下

多点位实时坐标

线条绘制的话使用了使用了地图提供的几何绘制,绘制器初始化参考官方文档 点/线/面(围栏)编辑绘制

其中有一点值得注意,官方文档只提到了可以在编辑中选中后对图形进行删除,却没有给出在绘制结束后如何对所画图形进行删除,参考和对比了以普通方式生成线后所返回的对象和绘制对象editor的属性后发现了一个方法,如下

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

以往清除标记点或线可以使用setMap(null),但在此处不行,会引起报错。推测是因为初始化时传入的overlayList不允许被完全清除。

本文使用 mdnice 排版