这是我第一次写文,文笔不好,凑合看看,有不对的请指正
最近做一个需求,需要在vue3项目中使用腾讯地图的api,也是头一次使用腾讯地图,把我的经验分享一下
地图引入
在系统根目录下的index.html文件中引入 (看有些文档说在public目录下的index.html文件 我的项目中index.html是在根目录下的)
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=申请的key值&libraries=visualization"></script>
页面中html内容
<template>
<div id="container" />
</template>
页面中js内容
function initMap() {
// 定义地图中心点坐标
const center = new window.TMap.LatLng(纬度,经度)
// 定义map变量,调用 TMap.Map() 构造函数创建地图
const map = new window.TMap.Map(document.getElementById('container'), {
center, // 设置地图中心点坐标
zoom: 8.5, // 设置地图缩放级别
mapStyleId: 'style1', // 设置地图样式
})
}
onMounted(() => {
initMap()
})
页面中样式
<style scoped>
#container {
/*地图(容器)显示大小*/
width: 100%;
height: 100%;
}
</style>
好的 目前到这一步 最基础的地图 就引入ok了
下面说说这一次做的功能
案例1 插点画圆
第一版呢 是像图中一样 选中一个位置为圆心,插点并圈出周围一公里地界,而后返回标点的经纬度
实现代码
// 初始中心点
const mapCenter = [40.46, 131.45]
function initMap() {
// 定义地图中心点坐标
const center = new window.TMap.LatLng(...mapCenter)
// 定义map变量,调用 TMap.Map() 构造函数创建地图
const map = new window.TMap.Map(document.getElementById('container'), {
center, // 设置地图中心点坐标
zoom: 8.5, // 设置地图缩放级别
mapStyleId: 'style1', // 设置地图样式
})
//创建圆形
const circle = new window.TMap.MultiCircle({
map,
styles: {
// 设置圆形样式
circle: new window.TMap.CircleStyle({
color: 'rgba(41,91,255,0.16)',
showBorder: true,
borderColor: 'rgba(41,91,255,1)',
borderWidth: 2,
}),
},
//circle配置项
//初始时无选中地点 所以radius为0
geometries: [
{
styleId: 'circle',
center,
radius: 0,//圆的半径 单位为米
},
],
})
let marker
//(回显时触发 在传入的坐标创建点和圆)
if (defaultCenter) {
const defaultPoint = new TMap.LatLng(...defaultCenter)
marker = new TMap.MultiMarker({
id: 'marker-layer',
map,
styles: {
//点的尺寸↓
marker: new TMap.MarkerStyle({
width: 20,
height: 35,
}),
},
geometries: [
{
id: 'mapMarker',
styleId: 'marker',
position: defaultPoint,
properties: {
title: 'marker',
},
},
],
})
//设置圆中心点并修改圆半径为1km
circle.setGeometries([
{
styleId: 'circle',
center: defaultPoint,
radius: 1000,
},
])
}
//监听地图点击事件
map.on('click', (evt) => {
// lat 纬度 lng 经度
const lat = evt.latLng.getLat().toFixed(6)
const lng = evt.latLng.getLng().toFixed(6)
const clickPoint = new window.TMap.LatLng(lat, lng)
//设置圆中心点并修改圆半径
circle.setGeometries([
{
styleId: 'circle',
center: clickPoint,
radius: 1000,
},
])
//如果还未创建插点 则创建一个插点(图中红色指针 样式可以自己调整)
if (!marker) {
marker = new TMap.MultiMarker({
id: 'marker-layer',
map,
styles: {
marker: new TMap.MarkerStyle({
width: 20,
height: 35,
}),
},
geometries: [
{
id: 'mapMarker',
styleId: 'marker',
position: clickPoint,
properties: {
title: 'marker',
},
},
],
})
}
//如果已创建插点 则仅修改插点位置
marker.setGeometries([
{
id: 'mapMarker',
styleId: 'marker',
position: clickPoint,
properties: {
title: 'marker',
},
},
])
console.log('纬度='+lat,'经度='+lng)
})
}
然后呢,经过一番讨论觉得这样不够智能,最终又决定换一个操作方式
案例2 绘制多边形
改版后的地图呢,支持自定义多边形,大概就是这个效果,其具体使用文档附在下方
腾讯地图似乎没写,要使用geometry的话要再额外引入一下 还是在index.html里
<script charset="utf-8" src="https://map.qq.com/api/gljs?libraries=tools&v=1.exp&key=申请到的key值"></script>
实现代码
function initMap() {
// 定义地图中心点坐标
const center = new window.TMap.LatLng(...mapCenter)
// 定义map变量,调用 TMap.Map() 构造函数创建地图
const map = new window.TMap.Map(document.getElementById('container'), {
center, // 设置地图中心点坐标
zoom: 8.5, // 设置地图缩放级别
mapStyleId: 'style1', // 设置地图样式
})
// 多边形初始形状(点坐标)
const simplePath = []
//如果需要回显↓ defaultGeometry的值类似创建图形后返回的paths数组
if (defaultGeometry) {
defaultGeometry.forEach((item) => {
simplePath.push(new TMap.LatLng(item.lat, item.lng))
})
}
// 创建多边形 这里也可以直接放进editor里边创建
const polygon = new TMap.MultiPolygon({
map,
geometries: [
{
paths: simplePath,
},
],
})
// 编辑器工作模式
const actionModeEnum = {
DRAW: TMap.tools.constants.EDITOR_ACTION.DRAW, // 绘制模式,该模式下用户可绘制新图形
INTERACT: TMap.tools.constants.EDITOR_ACTION.INTERACT, // 交互模式,该模式下用户可选中图形进行删除、修改
}
const actionType = simplePath.length ? 'INTERACT' : 'DRAW'
// 创建编辑器
editor = new window.TMap.tools.GeometryEditor({
// TMap.tools.GeometryEditor 文档地址:https://lbs.qq.com/webApi/javascriptGL/glDoc/glDocEditor
map, // 编辑器绑定的地图对象
overlayList: [
// 可编辑图层 文档地址:https://lbs.qq.com/webApi/javascriptGL/glDoc/glDocEditor#4
{
overlay: polygon,
id: 'polygon',
},
],
actionMode: actionModeEnum[actionType],
activeOverlayId: 'polygon', // 激活图层
snappable: true, // 开启吸附
selectable: true, // 开启选中 多边形可以进行操作
})
// 如果有回显多边形 则允许选中进行操作
showDeleteIcon.value = simplePath.length
// 监听绘制结束事件,获取绘制几何图形
editor.on('draw_complete', (geometry) => {
//id是图形创建时自动生成的唯一值
const id = geometry.id
//获取到刚创建的多边形
const geo = polygon.geometries.filter((item) => {
return item.id === id
})
// 绘制完成后不允许绘制第二个多边形 修改为交互模式 允许修改
// 因为我的需求只允许绘制一个多边形 如果允许绘制多个多边形 下边这句不需要写
editor.setActionMode(actionModeEnum.INTERACT)
//多边形的点位数据(经纬度)
console.log(geo[0].paths)
})
// 监听删除
editor.on('delete_complete', (evtResult) => {
//删除后修改模式为绘画
editor.setActionMode(actionModeEnum.DRAW)
//此处可以获取到被删除的多边形的信息
console.log(evtResult)
})
// 编辑多边形
editor.on('adjust_complete', (evtResult) => {
console.log(evtResult.paths)
})
// 选中多边形
editor.on('select', (evtResult) => {
console.log(evtResult)
})
}
因为我的地图是一个组件,需要配合element plus的dialog使用,引用地图组件时发现会报错,而后发现在initMap方法里先用一下await nextTick()就可以了
async function initMap() {
await nextTick()
....功能代码
}
结语
在腾讯地图的使用中我发现api文档似乎有些乱,每次搜索关键字出来的都不是同一个文档地址,也有可能是我不会正确使用腾讯地图的文档.
如果内容有不正确的地方或者有良好的建议请不吝赐教,能多给我点指导是最好了哈哈哈哈
circle文档地址 lbs.qq.com/javascript_…
GeometryEditor 文档地址:lbs.qq.com/webApi/java…
腾讯地图绘制几何图形文档lbs.qq.com/webDemoCent…
腾讯地图演示文档lbs.qq.com/webDemoCent…