第一步
登陆腾讯地图开放平台,申请密钥
第二步
在index.html中引入
<!-- 腾讯地图 -->
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=你的密钥&libraries=service"></script>
第三步
基本使用
<script lang="ts" setup>
import { onMounted, reactive } from 'vue'
let map: any = null
const state = reactive<any>({
markerLayer: '',
marker: null,
infoWindow: null,
value: 1,
})
const TMap = (window as any).TMap
onMounted(() => {
init()
})
/**
* 初始化地图
*/
const init = () => {
const center = new TMap.LatLng(39.910506, 116.39926431433355)
map = new TMap.Map(document.getElementById('container'), {
center: center, // 设置地图中心点坐标
zoom: 11, // 设置地图缩放级别
viewMode: '2D',
})
addImgMarker(center)
// 监听地图点击事件
map.on('click', (e: any) => {
// 清除点标记
state.marker.setMap(null)
// 关闭信息窗关闭
state.infoWindow.close()
state.marker = null
// 添加点标记
addImgMarker(e.latLng)
// 地址解析
getAddress(e)
})
// 初始化infoWindow
state.infoWindow = new TMap.InfoWindow({
map: map,
position: center,
offset: { x: 0, y: -32 }, // 设置信息窗相对position偏移像素
})
// 初始关闭信息窗关闭
state.infoWindow.close()
}
/**
* 添加点标记
* @param data data
*/
const addImgMarker = (data: any) => {
state.marker = new TMap.MultiMarker({
map: map,
geometries: [{ position: new TMap.LatLng(data.lat, data.lng) }],
})
}
/**
* 逆地址解析
* @param e 待解析经纬度
*/
const getAddress = (e: any) => {
const geocoder = new TMap.service.Geocoder() // 新建一个正逆地址解析类
const location = new TMap.LatLng(e.latLng.lat, e.latLng.lng)
geocoder.getAddress({ location: location }).then((res: any) => {
if (res.status === 0) {
state.infoWindow.open()
state.infoWindow.setPosition(e.latLng) // 设置信息窗位置
state.infoWindow.setContent(res.result.address) // 设置信息窗内容
}
})
}
/**
* 修改地图类型
* @param e e
*/
const changebasemap = (e: any) => {
if (e.target.value === 1) {
map.setBaseMap({ type: 'vector' })
} else if (e.target.value === 2) {
map.setBaseMap({ type: 'satellite' })
}
}
</script>
<template>
<div id="container" class="container"></div>
<div class="map">
<a-radio-group
v-model:value="state.value"
button-style="solid"
@change="changebasemap"
>
<a-radio-button :value="1">地图</a-radio-button>
<a-radio-button :value="2">卫星</a-radio-button>
</a-radio-group>
</div>
</template>
<style lang="less" scoped>
.container {
width: 100%;
height: 100%;
border: 10px solid #ececec;
position: relative;
}
.map {
position: absolute;
top: 70px;
margin: 10px 50px;
z-index: 9999;
}
</style>
效果如下:
地图控件
<script lang="ts" setup>
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
import { Modal, message } from 'ant-design-vue'
import { onMounted, reactive } from 'vue'
import { createVNode } from 'vue'
const state = reactive<any>({
map: null,
scale: null,
toolBar: null,
controlBar: null,
scaleStatus: true, // 比例尺
toolBarStatus: true, // 工具条
controlBarStatus: false, // 3D控制罗盘
value: 1,
})
const radioStyle = reactive({
display: 'flex',
height: '30px',
lineHeight: '30px',
})
const TMap = (window as any).TMap
onMounted(() => {
init()
})
/**
* 初始化地图
*/
const init = () => {
const center = new TMap.LatLng('39.910506', '116.39652')
state.map = new TMap.Map(document.getElementById('container'), {
center: center, // 设置地图中心点坐标
zoom: 11, // 设置地图缩放级别
viewMode: '2D',
})
// 比例尺
state.scale = state.map.getControl(TMap.constants.DEFAULT_CONTROL_ID.SCALE)
// 工具条
state.toolBar = state.map.getControl(TMap.constants.DEFAULT_CONTROL_ID.ZOOM)
// 3D控制罗盘
state.controlBar = state.map.getControl(
TMap.constants.DEFAULT_CONTROL_ID.ROTATION,
)
// 添加比例尺
state.map.addControl(state.scale)
// 显示工具条缩放比例
state.toolBar.setNumVisible(true)
// 添加工具条
state.map.addControl(state.toolBar)
// 移除3D控制罗盘
state.map.removeControl(TMap.constants.DEFAULT_CONTROL_ID.ROTATION)
}
/**
* 比例尺
*/
const changeScaleStatus = () => {
if (state.scaleStatus) {
state.map.addControl(state.scale)
} else {
state.map.removeControl(TMap.constants.DEFAULT_CONTROL_ID.SCALE)
}
}
/**
* 工具条
*/
const changeToolBarStatus = () => {
if (state.toolBarStatus) {
state.map.addControl(state.toolBar)
} else {
state.map.removeControl(TMap.constants.DEFAULT_CONTROL_ID.ZOOM)
}
}
/**
* 3D控制罗盘
*/
const changeControlBarStatus = () => {
if (state.value === 1) {
Modal.confirm({
title: '请先切换3D地图',
icon: createVNode(ExclamationCircleOutlined),
okText: '确定',
cancelText: '取消',
/**
* 确定的回调
*/
onOk() {
change3D()
},
})
} else {
if (state.controlBarStatus) {
state.map.addControl(state.controlBar)
} else {
state.map.removeControl(TMap.constants.DEFAULT_CONTROL_ID.ROTATION)
}
}
}
/**
* 切换2D地图
*/
const change2D = () => {
// 切换2D地图
state.map.setViewMode('2D')
state.value = 1
// 隐藏3D控制罗盘
state.controlBarStatus = false
// 移除3D控制罗盘
state.map.removeControl(TMap.constants.DEFAULT_CONTROL_ID.ROTATION)
message.success('已切换2D地图')
}
/**
* 切换3D地图
*/
const change3D = () => {
// 切换3D地图
state.map.setViewMode('3D')
// 设置倾斜角度
state.map.setPitch(70)
state.value = 2
// 显示3D控制罗盘
state.controlBarStatus = true
// 添加3D控制罗盘
state.map.addControl(state.controlBar)
message.success('已切换3D地图')
}
</script>
<template>
<div id="container" class="container"></div>
<div class="control-item">
<a-card title="地图控件">
<div class="control">
<a-checkbox
v-model:checked="state.scaleStatus"
@change="changeScaleStatus"
>
比例尺
</a-checkbox>
<a-checkbox
v-model:checked="state.toolBarStatus"
@change="changeToolBarStatus"
>
工具条
</a-checkbox>
<a-checkbox
v-model:checked="state.controlBarStatus"
@change="changeControlBarStatus"
>
3D控制罗盘
</a-checkbox>
<a-radio-group v-model:value="state.value">
<a-radio :style="radioStyle" :value="1" @change="change2D">
2D地图
</a-radio>
<a-radio :style="radioStyle" :value="2" @change="change3D">
3D地图
</a-radio>
</a-radio-group>
</div>
</a-card>
</div>
</template>
<style lang="less" scoped>
.container {
width: 100%;
height: 100%;
border: 10px solid #ececec;
}
.control-item {
position: absolute;
top: 70px;
margin: 10px 50px 10px;
padding: 10px 5px;
z-index: 9999;
.control {
display: flex;
flex-direction: column;
:deep(.ant-checkbox-wrapper) {
margin-bottom: 10px;
}
}
}
</style>
效果图如下: