地图官网获取服务许可key;国家地理信息公共服务平台 天地图
vue使用天地图报错Error in v-on handler: “TypeError: Cannot read property ‘_tdt_events‘ of null
当我们调用地图时需要使用setTimeout做延迟
mounted() {
// 初始化天地图
setTimeout(()=>{
this.initTdtMap();
},100)
},
或者使用
mounted() {
// 初始化天地图
this.$nextTick(()=>{
this.initTdtMap();
})
},
vue使用天地图实现步骤:
- 创建地图容器元素;
- 引入天地图,tk:在官网申请;
- 初始化地图对象;
- 设置显示地图的中心点和级别;
- 创建地图类型控件;
- 将控件添加到地图,一个控件实例只能向地图中添加一次;
- 创建坐标,通常是调取接口获得经纬度;
- 创建覆盖使用的图标;
- 创建在该坐标上的一个图像标注实例;
- 将覆盖物添加到地图中,一个覆盖物实例只能向地图中添加一次;
全局引入地图 js 库
在Vue项目的index.html 文件中,全局引入天地图js库
<body>
<script src="http://api.tianditu.gov.cn/api?v=4.0&tk=申请的key" type="text/javascript"></script>
</body>
这种方法引入的地图 js,会导致项目的每一个组件都会加载该 js,尤其在不需要加载天地图的页面,会造成很大的性能损耗;而在首页不需要天地图时,天地图加载缓慢,会造成很长的白屏时间,因此需要优化一下引入地图 js 的方法;
创建dom元素并插入
在需要引入 js 的页面,创建script元素,设置 src 属性,并插入;这样就会只在该页面中引入天地图 js;
mounted() {
let script = document.createElement('script')
script.type = 'text/javascript'
script.src = 'http://api.tianditu.gov.cn/api?v=4.0&tk=申请的key'
document.body.appendChild(script)
},
应用天地图
<template>
<div id="map"></div>
</template>
<script>
export default {
data() {
return {
map: {}
}
},
mounted() {
this.load();
},
methods: {
load() {
const init = new Promise((resolve, reject) => {
if(window.T) {
console.log('地图初始化成功')
resolve(window.T)
reject('error')
}
})
init.then(T => {
this.map = new T.Map('map');
this.map.centerAndZoom(new T.LngLat(116.40769, 39.89945), 12);
})
},
}
}
</script>
<style scoped>
#map {
width: 1000px;
height: 300px;
}
</style>
添加标注点,点击标注点出现信息窗口
在上述代码基础上添加一个按钮
<el-button type="primary" @click="handleAddPoint">添加标注点</el-button>
data() {
return {
map: {},
longitude: 116.403963,
latitude: 39.915119
}
},
methods: {
handleAddPoint() {
this.map.clearOverLays(); //清空原来的标注点
let point = new T.LngLat(this.longitude -= 0.01,this.latitude -= 0.01)
let marker = new T.Marker(point)
this.map.addOverLay(marker) //添加标注点
//点击标注点事件,添加信息窗口
let markerInfoWin = new T.InfoWindow("信息窗口");
marker.addEventListener('click', function() {
marker.openInfoWindow(markerInfoWin);
})
},
}
地理编码: 根据地址名称进行坐标解析并标注到地图上
在以上代码基础上添加下面内容
<div style="display: flex">
<el-input style="width: 300px; margin-right: 10px" v-model="inputLocation" @keyup.enter.native="handleFindLocation"></el-input>
<el-button type="primary" @click="handleFindLocation">搜索</el-button>
</div>
data() {
return {
map: {},
inputLocation: ''
}
},
handleFindLocation() {
let geocoder = new T.Geocoder()
let that = this
function searchResult(result){
if(result.getStatus() == 0){
//将地图的中心点变换到输入的地理位置,同时缩放到指定等级
that.map.panTo(result.getLocationPoint(), 16);
//创建标注对象
let marker = new T.Marker(result.getLocationPoint());
//向地图上添加标注
that.map.addOverLay(marker);
}else{
alert(result.getMsg());
}
}
geocoder.getPoint(this.inputLocation, searchResult);
},