百度地图自定义多个覆盖物
项目中有个需求是在百度地图中显示附近的人,从设计图上来看第一是要显示多个覆盖物,第二是覆盖物上要有头像,红包之类的,这就注定了要自定义复杂的覆盖物,对于一个没怎么看过百度地图api的小白来说,是一件很扣脑壳的事情,但完成项目后却又觉得原来很简单。
- 先来看看实现后的效果图吧!图中显示了三个坐标点,点击前坐标有头像和红包显示,点击后显示该头像的一些等级和经验值。
- 下面为实现自定义覆盖物的步骤
第一步:在Html中放入一个根标签来存放地图并引入百度地图
<div id="map"></div>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=你的密钥"></script>
第二步:绘制地图
var mp = new BMap.Map("map");
mp.centerAndZoom(new BMap.Point(104.07, 30.67), 19); // 经纬度和放大倍数
mp.enableScrollWheelZoom();
// 假设你已经得到后台返回给你的多个地图坐标点
var markerArr = [{
canPk: "0", // 是否可以进行点击,0否,1是
customerId: "111",
empiricDegree: "",
empiricDegreeDesc: "Lv0",
empiricValue: 0,
locationLat: "30.66315", // 经度
locationLng: "104.114143" // 纬度
},{
canPk: "1",
customerId: "222",
empiricDegree: "",
empiricDegreeDesc: "Lv0",
empiricValue: 0,
locationLat: "30.6634",
locationLng: "104.116"
},{
canPk: "0",
customerId: "333",
empiricDegree: "",
empiricDegreeDesc: "Lv0",
empiricValue: 0,
locationLat: "30.66315",
locationLng: "104.114143"
}];
// 复杂的自定义覆盖物
function ComplexCustomOverlay(point, img, customerId,canPk){
this._point = point; // 经纬度
this._img = img; // 传进来的img头像
this._customerId = customerId; // 对方的经验值
this._canPk = canPk; // 0 不可点击,1 可点击
}
ComplexCustomOverlay.prototype = new BMap.Overlay();
ComplexCustomOverlay.prototype.initialize = function(map){
this._map = map;
var div = this._div = document.createElement("div"); // 创建一个div来存放自定义坐标点
div.style.position = "absolute";
div.style.zIndex = BMap.Overlay.getZIndex(this._point.lat);
div.style.whiteSpace = "nowrap";
div.style.MozUserSelect = "none";
var span = this._span = document.createElement("span");
div.appendChild(span);
span.style.background = "url(img/redTip.png) no-repeat"; // 红包
span.style.position = "absolute";
span.style.width = "20px";
span.style.height = "20px";
span.style.top = "-32px";
span.style.left = "9px";
span.style.marginLeft = "-30px";
span.style.zIndex = "2";
span.style.backgroundSize = "contain";
span.style.display = "block"; // 默认红包显示
var p = this._span = document.createElement("p"); // p标签来存放点击后显示的内容
div.appendChild(p);
p.style.backgroundColor = "#fff";
p.style.position = "absolute";
p.style.width = "68px";
p.style.height = "33px";
p.style.top = "-28px";
p.style.left = "23px";
p.style.marginLeft = "-30px";
p.style.zIndex = "2";
p.style.backgroundSize = "contain";
p.style.borderRadius = "15px";
p.style.padding = "2px 7px";
p.style.boxShadow = "2px 2px 2px #ddd";
p.style.display = "none"; // 默认p标签是隐藏的
var pSpan1 = this._span = document.createElement("span");
p.appendChild(pSpan1);
pSpan1.style.zIndex = "2";
pSpan1.style.backgroundSize = "contain";
pSpan1.style.width = "26px";
pSpan1.style.height = "26px";
pSpan1.style.lineHeight = "26px";
pSpan1.style.fontSize = "10px";
pSpan1.style.backgroundColor = "#FD5A30";
pSpan1.style.borderRadius = "50%";
pSpan1.style.marginTop = "2px";
pSpan1.style.textAlign = "center";
pSpan1.style.cssFloat = "left";
pSpan1.style.display = "inline-block";
var pSpan2 = this._span = document.createElement("span");
p.appendChild(pSpan2);
pSpan2.style.backgroundSize = "contain";
pSpan2.style.width = "20px";
pSpan2.style.height = "20px";
pSpan2.style.lineHeight = "30px";
pSpan2.style.fontSize = "12px";
pSpan2.style.marginLeft = "5px";
pSpan2.style.display = "inline-block";
var i = this._span = document.createElement("i"); // i标签存放坐标点头像
i.style.background = "url("+ this._img + ")"+" "+"no-repeat";
i.style.position = "absolute";
i.style.width = "40px";
i.style.height = "40px";
i.style.top = "-24px";
i.style.left = "-22px";
i.style.marginLeft = "-30px";
i.style.zIndex = "1";
i.style.backgroundSize = "contain";
div.appendChild(i);
// var that = this;
var arrow = this._arrow = document.createElement("div"); // 创建div来存放底部白色坐标点指向
arrow.style.background = "url(img/locationBg.png) no-repeat";
arrow.style.backgroundSize = "contain";
arrow.style.position = "absolute";
arrow.style.width = "56px";
arrow.style.height = "56px";
arrow.style.top = "-28px";
arrow.style.left = "-30px";
arrow.style.marginLeft = "-30px";
arrow.style.overflow = "hidden";
div.appendChild(arrow);
var canPk = this._canPk;
var customerIdClick = this._customerId;
var mapPoint = .this._point;
// 移动端自定义坐标点点击事件开始--这里是移动端的兼容写法
tmpfun = map.onclick;
map.onclick = null;
div.addEventListener("touchstart", function() { //用这种方式绑定点击事件就OK了
map.onclick = tmpfun;
if(canPk == '1' && span.style.display == "block"){ // 可以点击且还未点击过的坐标点
span.style.display = "none"; // 点击过后红包隐藏
//这里可以进行点击时你需要进行的操作,操作完成后p标签展示
alert("点击我了" + mapPoint.lng + "," + mapPoint.lat)
p.style.display = 'block';
}else if(canPk == '1' && span.style.display == "none"){
alert("已经点击过,请重新选择 ")
}
});
// 移动端自定义坐标点点击事件结束--这里是移动端的兼容写法
mp.getPanes().labelPane.appendChild(div);
return div;
}
ComplexCustomOverlay.prototype.draw = function(){
var map = this._map;
var pixel = map.pointToOverlayPixel(this._point);
this._div.style.left = pixel.x - parseInt(this._arrow.style.left) + "px";
this._div.style.top = pixel.y - 30 + "px";
}
ComplexCustomOverlay.prototype.getPosition = function () {
return this._point;
};
// 自定义覆盖物添加事件方法
ComplexCustomOverlay.prototype.addEventListener = function (event, fun) {
this._div['on' + event] = fun;
}
for(var i = 0; i < markerArr.length; i++) {
var p0 = markerArr[i].locationLng;
var p1 = markerArr[i].locationLat;
// canPk 0不可点击,1可以点击;customerId 对方的经验值;
var marker = new ComplexCustomOverlay(new BMap.Point(p0,p1), 'img/phone2.png', markerArr[i].customerId,markerArr[i].canPk); // 我这里传的img为相同的img,可根据自己的需要传不同的img,这里的“img/phone2.png”改成变量形式就可以了
mp.addOverlay(marker);
};
以上就可以实现百度地图自定义覆盖物,其中用到的百度地图的api在百度地图开发文档中都写的很清楚,可对应去查看,http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference_3_0.html#a3b0
在做这个需求时,也在网上看了挺多的自定义覆盖物的文章的,大多都是搬百度地图demo的代码,其实实现这个需求不难,自定义的东西多了就需要自己的代码逻辑和开发思想要清楚一下,以上的代码样式还需要好好优化,其实这里的坐标用百度地图的Canvas更好一些,处理海量的覆盖物要更好,这里项目只会返回几个覆盖物又急于项目演示也就这样了,有空的时候多总结一下,也让自己养成总结输出文档的习惯,以上代码有出入的地方希望大家可以多多指教,谢谢。