vue使用百度map,实现点击Marker切换图标,以及展示此Marker信息。
先放效果图,其中每一个点代表了小区的位置,打了贴纸隐藏的地方是小区的名字和地址。见谅。 一、接入百度地图,首先要注册成为百度地图开放平台的开发者,申请百度地图的密钥(ak),web端使用的是JavaScriptAPI,所以我们申请的就是JavaScriptAPI。 二、在你的ak申请好了之后,在public下的index引入。<script type="text/javascript"
先放效果图,其中每一个点代表了小区的位置,打了贴纸隐藏的地方是小区的名字和地址。见谅。
一、接入百度地图,首先要注册成为百度地图开放平台的开发者,申请百度地图的密钥(ak),web端使用的是JavaScriptAPI,所以我们申请的就是JavaScriptAPI。
二、在你的ak申请好了之后,在public下的index引入。
<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=你申请的ak"></script>
三、在你需要引入百度地图的地方定一个盒子,用来存放地图。
<template>
<div class="map" id="map"></div>
<template/>
<script>
export default {
data(){
return{
map:null
}
},
createMap(){
this.map = new BMap.Map("map",{minZoom:6,maxZoom:16})
},
mounted(){
this.createMap()
}
}
<script/>
这样一个简单的地图就出来了,但是需求是不会停止的。
是远远不够产品经理的需求滴,至少是我上边效果的样子。
四、我的需求就是上面效果的样子。
1、先说背景图,在百度地图开放平台个人的控制台,特色服务平台 => 个性化地图,来编辑你的地图样式,编辑完后会生成当前编辑的一个样式ID、样式的json文件。
2、效果图中的点,效果图中的点称为Marker,每一个Marker是UI做的图片,用不同的图片来显示不同的东西。
3、说一下思路
第一步、渲染地图的时候,就要把这些点默认渲染出来,这些点是从后台的返回的
//请求接口获取每一个点
getSiteName(){
this.marketArr = [] //在每次请求前赋空
this.$http.post("接口").then(res => {
var cars = res.data.parse.data
this.siteName = res.data.data;
//需要特定的格式所以处理了一下,point为坐标点
for(let i = 0; i < this.siteName.length; i++){
this.marketArr.push({name:this.siteName[i].siteName, title:this.siteName[i].categoryMessageStr, point:[this.siteName[i].coordinateOne, this.siteName[i].coordinateTwo], status:this.siteName[i].categoryMessageId})
}
// 运输车处理
if(cars){
for(let k = 0; k < cars.length; k++){
this.marketArr.push({name:'运输车', title:cars[k].CarNo, point:[cars[k].X, cars[k].Y], status:4})
}
}
this.createMap(); //获取所有的点之后渲染地图
})
},
第二步渲染地图,设置每一个点的坐标,形成点
//地图渲染
createMap(){
this.map = new BMap.Map("map",{minZoom:6,maxZoom:16}) // 拿到id为map的盒子,把地图挂载到上面,后边是滚轮最小缩放和最大缩放
this.map.centerAndZoom(new window.BMap.Point(this.longitude,this.latitude), 15); //设置地图的中心点,这里是接口返回的,自定义一个数据,赋值,15是默认的缩放大小
this.map.setMapStyleV2({styleJson:this.styleJson}); // 上边说过,设置地图的样式会产生一个样式ID和一个json样式文件,我这里用的是json文件,直接复制放到data里,调用就可以。
this.workingIcon = new BMap.Icon(require("../../assets/images/working.png"), new BMap.Size(30,30));
this.workingIcon2 = new BMap.Icon(require("../../assets/images/working2.png"), new BMap.Size(40,40));
this.nodalIcon2 = new BMap.Icon(require("../../assets/images/laji2.png"), new BMap.Size(40,40));
this.nodalIcon = new BMap.Icon(require("../../assets/images/laji.png"), new BMap.Size(40,40));
this.stationIcon = new BMap.Icon(require("../../assets/images/shan.png"), new BMap.Size(30,30));
this.stationIcon = new BMap.Icon(require("../../assets/images/shan2.png"), new BMap.Size(30,30));
this.carIcon = new BMap.Icon(require("../../assets/images/car.png"), new BMap.Size(30,30));
this.carIcon2 = new BMap.Icon(require("../../assets/images/car2.png"), new BMap.Size(30,30));
//上边这些是我用到的icon,直接引用本地的icon,后面跟的是每一个icon的大小
var point = []; //存放标注点的坐标数组
var marker = []; //存放标注点对象数组
for(var i = 0; i < this.marketArr.length; i++){
var p0 = this.marketArr[i].point[0];
var p1 = this.marketArr[i].point[1];
point[i] = new window.BMap.Point(p0, p1); //拿到接口返回的经纬度放到point里
marker[i] = new window.BMap.Marker(point[i]); //然后放到marker里,BMap.Marker是形成点的
//通过状态判断icon,
if(this.marketArr[i].status == 1){
marker[i] = new window.BMap.Marker(point[i], {icon: this.workingIcon})
}else if(this.marketArr[i].status == 2){
marker[i] = new window.BMap.Marker(point[i], {icon: this.stationIcon})
}else if(this.marketArr[i].status == 3){
marker[i] = new window.BMap.Marker(point[i], {icon: this.nodalIcon})
}else if(this.marketArr[i].status == 4){
marker[i] = new window.BMap.Marker(point[i], {icon: this.carIcon})
}
marker[i].setTitle(this.marketArr[i].name) //设置每一个点的title,鼠标title
this.map.addOverlay(marker[i]); //添加自定义覆盖物 marker里含有每一个点的信息
this.addInfo(marker[i])
}
},
第三步为每一个点添加点击,进行替换
//每一个marker添加点击事件,改变点的样式
addInfo(marker){
var _this = this;
marker.addEventListener("click", function(e){
var carCard = ''; //定义车牌
_this.huifu(); //在改变每一个marker形状之前,都执行一下marker还原的方法
_this.marketArr.forEach(item => {
if(item.point[0] == marker.point.lng && item.point[1] == marker.point.lat){
carCard = item.title
}
}); // 当我点击时,判断是否是运输车,拿到运输车的车牌
//当前点击的是运输车,拿到上边的车牌,返回当前运输车的相关信息
if(marker.K.title === '运输车'){
let params = qs.stringify({'siteName':carCard})
_this.$http.post('接口', params).then( res => {
_this.tipMsg = res.data.data; //tipMsg 弹出的浮窗的信息
_this.toggle = true; //浮窗显示
})
}else{
//否则,就是站点,通过当前点击站点的坐标来返回站点信息
let params = qs.stringify({"coordinateOne": marker.point.lng, "coordinateTwo": marker.point.lat})
_this.$http.post('接口', params).then( res => {
_this.tipMsg = res.data.data[0]; //tipMsg 弹出的浮窗的信息
_this.toggle = true; //浮窗显示
_this.$refs.myChild.$children[0].hitsiteName(_this.tipMsg.id); //我这里还和其他地方进行了联动,不用管这个
_this.saveSiteName = res.data.data[0].siteName //这个是拿到点的名字,在huifu的方法里判断所点击的是否是同一个点
var ptx = marker.point.lng
var pty = marker.point.lat
var smarker = null; //先定义一下添加的覆盖物
var allOverlay = _this.map.getOverlays(); //拿到当前点击覆盖物的信息
//如果这个覆盖物的的getTitle()和上边接口里返回的站点名称一样,则删掉这个marker(即这个站点图标)
for (var i = 0; i < allOverlay.length; i++){
if(allOverlay[i].getTitle() == res.data.data[0].siteName){
_this.map.removeOverlay(allOverlay[i]);
}
}
//根据接口里的每一种marker标识,来判断使用哪一种图标,new BMap.Point(ptx,pty),设置坐标,icon设置图标,这里就使用了新的图标,
if(res.data.data[0].categoryMessageId == 1){
smarker = new window.BMap.Marker(new BMap.Point(ptx,pty), {icon: _this.workingIcon2})
}else if(res.data.data[0].categoryMessageId == 2){
smarker = new window.BMap.Marker(new BMap.Point(ptx,pty), {icon: _this.stationIcon2})
}else if(res.data.data[0].categoryMessageId == 3){
smarker = new window.BMap.Marker(new BMap.Point(ptx,pty), {icon: _this.nodalIcon2})
}else if(res.data.data[0].categoryMessageId == 4){
smarker = new window.BMap.Marker(new BMap.Point(ptx,pty), {icon: _this.carIcon2})
}
smarker.setTitle(res.data.data[0].siteName) //为这个新图标设置title
_this.map.addOverlay(smarker); //添加新覆盖物替换上边删掉的覆盖物(即marker
allOverlay = _this.map.getOverlays();
})
}
})
},
第四步、回复到原先的marker样式
// 回复到原先的marker样式,在每次点击时会先执行一下这个方法
huifu(){
var allOverlay = this.map.getOverlays(); //拿到覆盖物信息
//循环判断我保存的覆盖物名称(即站点名称)是否和allOverlay里的title相同,相同则,通过这个覆盖物的坐标返回其相关信息,替换因点击生成的新图标
for (var i = 0; i < allOverlay.length ; i++){
if(this.saveSiteName != "" && allOverlay[i].getTitle() == this.saveSiteName){
var ptx = allOverlay[i].point.lng
var pty = allOverlay[i].point.lat
var status = ''
let params = qs.stringify({"coordinateOne": ptx, "coordinateTwo": pty})
this.$http.post('接口', params).then( res => {
status = res.data.data[0].categoryMessageId
this.map.removeOverlay(allOverlay[i]); //把点击替换的新的marker删掉
//ADD
var hfmarker = null;
if(status == 1){
hfmarker = new window.BMap.Marker(new BMap.Point(ptx,pty), {icon: this.workingIcon})
}else if(status == 2){
hfmarker = new window.BMap.Marker(new BMap.Point(ptx,pty), {icon: this.stationIcon})
}else if(status == 3){
hfmarker = new window.BMap.Marker(new BMap.Point(ptx,pty), {icon: this.nodalIcon})
}else if(status == 4){
hfmarker = new window.BMap.Marker(new BMap.Point(ptx,pty), {icon: this.carIcon})
}
hfmarker.setTitle(res.data.data[0].siteName)
this.map.addOverlay(hfmarker); //使用原先样式添加覆盖物
})
return false;
}
}
},
说一下整体思路吧,可能上边说的比较散,请求接口返回所有的marker(即所有点)的信息,渲染到地图上,点击每一个marker时把原先的marker删掉,用一个新的marker替换,因为点击之前会先执行回复的方法,所以当点击第二个marker时,会先将上一次替换的新的marker改变成原先的图标,这样就完成了替换。
不注重视觉设计的程序猿不是一个好作家!
更多推荐
所有评论(0)