在index.html文件中导入腾讯地图的组件api
<script src="https://map.qq.com/api/gljs?v=1.exp&key=<输入你的KEY>"></script>
创建文件components/map/index.vue
<template>
<div style="position: relative;">
<div
v-if="!mapLoaded"
class="loadingPage"
>
<div class="loading loader" />
</div>
<!-- 控制台 -->
<div
v-if="searchShow && mapLoaded"
class="control"
>
<el-autocomplete
v-model="searchAddress"
class="inline-input"
:fetch-suggestions="querySearch"
placeholder="请输入市区名+地名"
clearable
:trigger-on-focus="false"
@input="inputAddress"
@select="search"
@click.native.stop
/>
<el-button
:disabled="isDisabled"
@click.stop="search"
>搜索地址</el-button>
</div>
<div
v-if="mapType === 'route' && mapLoaded"
class="control"
>
<div class="item">
<div class="label">播放速度:</div>
<el-input-number
v-model="speedNum"
:min="1"
:max="999"
label="播放速度"
@change="speedChange"
/>
<el-button
style="margin-left: 20px;"
@click.stop="speedChange(10)"
>10倍速</el-button>
<el-button @click.stop="speedChange(100)">100倍速</el-button>
<el-button @click.stop="speedChange(999)">1000倍速</el-button>
</div>
</div>
<!-- 地图容器 -->
<div
id="qqmap"
:style="'width:' + width + ';height:' + height + ';'"
/>
</div>
</template>
<script>
import { addressResolution, addressInverseResolution, keywordAssociation } from './mapApi'
export default {
props: {
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '100%'
},
// 启用点击事件
clickEvent: {
type: Boolean,
default: false
},
// 启用搜索功能
searchShow: {
type: Boolean,
default: false
}
},
data() {
return {
mapType: null,
mapLoaded: false, // 地图是否加载完成
map: null, // 地图对象实例
center: null, // 地图中心点
maker: null, // 标记点实例
markGeo: [], // 点标记列表
polylineLayer: null,
path: [],
// 初始化地图数据
location: {
lng: undefined, // 经度
lat: undefined // 纬度
},
// 轨迹开始坐标
startLocation: {
lng: undefined, // 经度
lat: undefined // 纬度
},
// 轨迹结束坐标
endLocation: {
lng: undefined, // 经度
lat: undefined // 纬度
},
searchAddress: '', // 地址搜索数据
searchList: undefined, // 地址搜索结果
isDisabled: true, // 搜索按钮是否禁用
province: undefined, // 省
city: undefined, // 市
district: undefined, // 区
addressValue: undefined, // 详细地址
speedNum: 1
}
},
created() {
},
methods: {
launch(res, type) {
if (type === 'point') {
this.mapType = 'point'
this.getLocation(res) // 初始化经纬度
} else if (type === 'route') {
this.mapType = 'route'
this.getLocationRoute(res) // 初始化经纬度
}
if (!this.mapLoaded) {
this.initMap() // 初始化地图
}
},
devastate() {
this.speedNum = 1
this.map.destroy()
this.mapLoaded = false
},
// 地图初始化
initMap() {
// 定义地图中心点坐标
this.center = new window.TMap.LatLng(
this.location.lat,
this.location.lng
)
// 定义map变量,调用 TMap.Map() 构造函数创建地图
this.map = new window.TMap.Map(document.getElementById('qqmap'), {
center: this.center, // 设置地图中心点坐标
zoom: 17.2, // 设置地图缩放级别
pitch: 43.5, // 设置俯仰角
rotation: 45, // 设置地图旋转角度
viewMode: '3D' // 设置地图展示形式 默认3D
})
if (this.$props.clickEvent) {
this.map.on('click', this.clickHandler) // 添加地图点击事件
}
// 创建点标记
if (this.mapType === 'point') {
this.markGeo = [
{
id: '1', // 点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
styleId: 'myStyle', // 指定样式id
position: new window.TMap.LatLng(
this.location.lat,
this.location.lng
)
}
]
} else if (this.mapType === 'route') {
this.markGeo = [
{
id: 'car',
styleId: 'car-down',
position: new window.TMap.LatLng(
this.location.lat,
this.location.lng
)
}, {
id: 'start',
styleId: 'start',
position: new TMap.LatLng(
this.startLocation.lat,
this.startLocation.lng
)
}, {
id: 'end',
styleId: 'end',
position: new TMap.LatLng(
this.endLocation.lat,
this.endLocation.lng
)
}
]
}
this.maker = new window.TMap.MultiMarker({
map: this.map, // 绑定地图对象
styles: {
'car-down': new TMap.MarkerStyle({
'width': 40,
'height': 40,
'anchor': {
x: 20,
y: 20
},
'faceTo': 'map',
'rotate': 0,
'src': 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/car.png'
}),
'start': new TMap.MarkerStyle({
'width': 25,
'height': 35,
'anchor': { x: 16, y: 32 },
'src': 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/start.png'
}),
'end': new TMap.MarkerStyle({
'width': 25,
'height': 35,
'anchor': { x: 16, y: 32 },
'src': 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/end.png'
})
},
geometries: this.markGeo // 点标记数据
})
// 添加路线轨迹
if (this.mapType === 'route') {
this.polylineLayer = new TMap.MultiPolyline({
map: this.map, // 绘制到目标地图
// 折线样式定义
styles: {
'style_route': new TMap.PolylineStyle({
'color': '#3777FF', // 线填充色
'width': 5, // 折线宽度
'borderWidth': 1, // 边线宽度
'borderColor': '#eee', // 边线颜色
'lineCap': 'round' // 线端头方式
})
},
geometries: [{
styleId: 'style_route',
paths: this.path
}]
})
this.maker.moveAlong({
'car': {
path: this.path,
speed: 888 * this.speedNum
}
}, {
autoRotation: true
})
}
this.mapLoaded = true
console.log('地图加载完成')
},
// 单点地图数据初始化
getLocation(res) {
this.location.lng = res.longitudeX
this.location.lat = res.latitubeY
if (this.mapLoaded) {
// 设置标记点
this.setMaker(this.location.lat, this.location.lng)
// 移动地图中心点
this.map.setCenter(new TMap.LatLng(this.location.lat, this.location.lng))
}
},
// 地图点击事件
clickHandler(evt) {
this.location.lat = evt.latLng.getLat().toFixed(6) // 获取纬度
this.location.lng = evt.latLng.getLng().toFixed(6) // 获取经度
// 设置标记点
this.setMaker(this.location.lat, this.location.lng)
// 地址逆解析
addressInverseResolution(this.location.lat + ',' + this.location.lng).then(res => {
this.addressValue = res.result.address
this.province = res.result.address_component.province
this.city = res.result.address_component.city
this.district = res.result.address_component.district
// 传递地址数据
this.postAddressData()
})
},
// 设置标记点
setMaker(latitude, longitude) {
// 修改标记点
this.maker.updateGeometries({
id: '1', // 点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
styleId: 'myStyle', // 指定样式id
position: new window.TMap.LatLng(
latitude, longitude
)
})
},
// 搜索地址
search() {
// 地址解析
addressResolution(this.searchAddress).then(res => {
const searchOption = this.searchList.find(f => f.result.title === this.searchAddress)
if (res.message !== 'Success') {
if (searchOption && searchOption.result.title !== this.searchAddress) {
this.$message({
message: '请注意搜索格式是否正确',
type: 'error',
duration: 2000,
offset: 70
})
return
} else if (searchOption && searchOption.result.title) {
res = searchOption
}
}
// 设置标记点
this.setMaker(res.result.location.lat, res.result.location.lng)
// 移动地图中心点
this.map.setCenter(new TMap.LatLng(res.result.location.lat, res.result.location.lng))
// 获取详细地址信息
this.addressValue = res.result.title
this.province = res.result.address_components.province
this.city = res.result.address_components.city
this.district = res.result.address_components.district
// 传递地址数据
this.postAddressData()
})
},
// 查询联想词
querySearch(queryString, cb) {
keywordAssociation(queryString).then(({ data }) => {
for (var i = 0; i < data.length; i++) {
data[i].value = data[i].title
}
this.searchList = data.map(m => {
const location = m.location
const title = m.title
const province = m.province
const district = m.district
const city = m.city
const address_components = { province, district, city }
const searchOption = { result: { title, location, address_components }}
return searchOption
})
cb(data)
})
},
// 判断输入地址是否为空
inputAddress(value) {
if (value) {
this.isDisabled = false
} else {
this.isDisabled = true
}
},
// 传递地址数据
postAddressData() {
// this.$emit('postAddress', {
// province: this.province,
// city: this.city,
// district: this.district,
// addressValue: this.addressValue,
// latitubeY: this.location.lat,
// longitudeX: this.location.lng
// })
},
// 路径地图数据初始化
getLocationRoute(res) {
// 获取起点坐标信息
this.startLocation.lng = res[0].longitudeX
this.startLocation.lat = res[0].latitudeY
// 获取终点坐标信息
this.endLocation.lng = res[res.length - 1].longitudeX
this.endLocation.lat = res[res.length - 1].latitudeY
const LastPosition = res[0]// 最新的坐标信息
this.location.lng = LastPosition.longitudeX
this.location.lat = LastPosition.latitudeY
console.log(this.endLocation);
console.log(this.startLocation);
res.forEach(item => {
this.path.push(new TMap.LatLng(item.latitudeY, item.longitudeX))
})
if (this.mapLoaded) {
// 移动地图中心点
this.map.setCenter(new TMap.LatLng(this.location.lat, this.location.lng))
}
},
speedChange(num) {
if (num) {
this.speedNum = num
}
this.maker.moveAlong({
'car': {
path: this.path,
speed: 800 * this.speedNum
}
}, {
autoRotation: true
})
}
}
}
</script>
<style lang="scss" scoped>
.control {
position: absolute;
top: 10px;
left: 10px;
z-index: 1999;
.item {
display: flex;
align-items: center;
.label {
font-size: 16px;
color: #666;
margin-right: 10px;
}
}
}
.loadingPage {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 3999;
.loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
@keyframes rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.loader {
width: 48px;
height: 48px;
border: 5px solid #00afee;
border-bottom-color: #90cf5b;
border-radius: 50%;
-webkit-animation: rotation 1s linear infinite;
animation: rotation 1s linear infinite;
}
</style>
创建文件components/map/map_api.js
// 地址解析
export function addressResolution(address) {
return new Promise(function(resolve, reject) {
window.handleResponse = function(data) {
resolve(data)
}
const url = 'https://apis.map.qq.com/ws/geocoder/v1/?address=' + address + '&key=<输入你的KEY>&output=jsonp&callback=handleResponse'
var script = document.createElement('script')
script.src = url
document.body.appendChild(script)
})
}
// 地址逆解析
export function addressInverseResolution(location) {
return new Promise(function(resolve, reject) {
window.handleResponse = function(data) {
resolve(data)
}
const url = 'https://apis.map.qq.com/ws/geocoder/v1/?location=' + location + '&key=<输入你的KEY>&output=jsonp&callback=handleResponse'
var script = document.createElement('script')
script.src = url
document.body.appendChild(script)
})
}
// 关键词联想
export function keywordAssociation(keyword) {
return new Promise(function(resolve, reject) {
window.handleResponse = function(data) {
resolve(data)
}
const url = 'https://apis.map.qq.com/ws/place/v1/suggestion?keyword=' + keyword + '&key=<输入你的KEY>&output=jsonp&callback=handleResponse&policy=1'
var script = document.createElement('script')
script.src = url
document.body.appendChild(script)
})
}
调用方式:
<template>
<div>
<el-button type="primary" @click="handleOpen">打开地图</el-button>
<el-button type="primary" @click="handlePlay">播放轨迹</el-button>
<el-drawer
:visible.sync="drawerShow"
direction="btt"
:before-close="handleClose"
wrapperClosable
size="800px"
:with-header="false"
>
<TXmap ref="TXmapRef" :height="'797px'" :clickEvent="true" :searchShow="true" />
</el-drawer>
</div>
</template>
<script>
// 引入地图组件
import TXmap from "@/components/TXmap";
export default {
components: {
TXmap,
},
data() {
return {
// 是否显示弹出层
drawerShow: false,
};
},
methods: {
async handleOpen() {
// 打开弹窗
this.drawerShow = true;
// 加载地图数据
const data = {
longitudeX: "116.397477",
latitubeY: "39.908692",
};
this.$nextTick(() => {
this.$refs.TXmapRef.launch(data, "point"); //加载地图数据 单点标记
});
},
handlePlay() {
// 打开弹窗
this.drawerShow = true;
// 加载地图数据
const data = [
{longitudeX:116.30571126937866,latitudeY:39.98481500648338},
{longitudeX:116.30596876144409,latitudeY:39.982266575222155},
{longitudeX:116.3111400604248,latitudeY:39.982348784165886},
{longitudeX:116.3111400604248,latitudeY:39.978813710266024},
{longitudeX:116.31699800491333,latitudeY:39.978813710266024},
];
this.$nextTick(() => {
this.$refs.TXmapRef.launch(data, "route"); //加载地图数据 播放轨迹
});
},
handleClose() {
// 关闭弹窗
this.drawerShow = false;
this.$refs.TXmapRef.devastate(); //销毁地图
},
},
};
</script>