百度地图api绘制热力图以及Label和Echarts组合对marker进行自定义提示

源码附件已更新,贴上了可以使用的密钥以及所需js文件 2020.4.14 下载

最终成果图

这周使用到了百度地图api进行网页开发,主要涉及了marker点的文字标注,即label结合echarts使用;绘制热力图以及对不同的地图缩放级别显示不同的marker点;
最终效果图如下:
在这里插入图片描述

1.使用百度地图的准备

  1. 如果想要使用百度地图,第一步要做的就是申请百度地图api的开发者密钥; 在点击提交之后会发送一封激活邮件到所填的邮箱,点击激活链接之后,返会会员中心显示激活成功。
    在这里插入图片描述

  2. 然后按照自己应用的需求选择应用类型和相应的服务。在点击提交之后就会看到你的密钥了。
    在这里插入图片描述

2.使用百度地图创建热力图

使用百度地图创建热力图首先需要在<head></head>内引入api接口和热力图的js,即

<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=您的密钥"></script>
<script type="text/javascript" src="//api.map.baidu.com/library/Heatmap/2.0/src/Heatmap_min.js"></script>

创建地图显示区域

<div id="container"></div>

创建地图标注点以及添加热力图;
其中points作为热力图所需的数据:(lng,lat) 热力图每个热点(即,marker)的位置,count代表热点的权重。

<script type="text/javascript">
    var BaiduMap= new BMap.Map("container");          // 创建地图实例
	
	//特别注意此处centerAndZoom 的设置 本人建议一定是定义point设置 原因稍后讲解
    var point = new BMap.Point(116.418261, 39.921984);
    BaiduMap.centerAndZoom(point, 15);             // 初始化地图,设置中心点坐标和地图级别
    BaiduMap.enableScrollWheelZoom(); // 允许滚轮缩放
  
    var points =[
    {"lng":116.424579,"lat":39.914987,"count":57},
    {"lng":116.42076,"lat":39.915251,"count":70},
    {"lng":116.425867,"lat":39.918989,"count":8}];
   
   //循环添加标注点
 	for(var i=0;i<points.length; i++){
    	var point = new BMap.Point(points[i].lng,points[i].lat);
		var marker = new BMap.Marker(point);
    	BaiduMap.addOverlay(marker);
 	}
    if(!isSupportCanvas()){
    	alert('热力图目前只支持有canvas支持的浏览器,您所使用的浏览器不能使用热力图功能~')
    }
	//创建热力图
	var heatmapOverlay = new BMapLib.HeatmapOverlay({"radius":20});
	BaiduMap.addOverlay(heatmapOverlay);
	heatmapOverlay.setDataSet({data:points,max:100});
	heatmapOverlay.show();
	//heatmapOverlay.hide()
    //设置热力图显示的样式
    function setGradient(){
     	var gradient = {};
     	var colors = document.querySelectorAll("input[type='color']");
     	colors = [].slice.call(colors,0);
     	colors.forEach(function(ele){
			gradient[ele.getAttribute("data-key")] = ele.value; 
     	});
        heatmapOverlay.setOptions({"gradient":gradient});
    }
	//判断浏览区是否支持canvas
    function isSupportCanvas(){
        var elem = document.createElement('canvas');
        return !!(elem.getContext && elem.getContext('2d'));
    }
</script>

到此就能看到如下热力图了。
在这里插入图片描述

热力图无法显示,控制台出现错误

本人最开始是如下对百度地进行实例化的:

BaiduMap.centerAndZoom("山东省滨州市",11); 
var bs = new BMap.Bounds(new BMap.Point(119.316379,37.999476),new BMap.Point(116.641871, 37.999476));
BMapLib.AreaRestriction.setBounds(BaiduMap, bs);
Cannot read property 'y' of undefined

经过排查发现如果使用以上方式定义实例化地图之后,在获取可视地图的中心和边界时得到如下所示数据:

	console.log(BaiduMap.getCenter());
	console.log(BaiduMap.getBounds());

在这里插入图片描述

可以发现这样设置根本没有对可视中心和边界数据进行设置。就导致了在使用热力图时报错。
如何解决此方式的问题,暂未找到,若有读者了解,还请不吝赐教,十分感谢!

再来看一下能够正确显示热力图的point 方式所得数据:

var point = new BMap.Point(117.979125,37.389114);
BaiduMap.centerAndZoom(point, 10);

在这里插入图片描述

由此可得,使用point点设置百度地图初始化可以省去很多麻烦
给百度地图添加点击监听事件可以得到点击地图位置的坐标

BaiduMap.addEventListener("click",function(e){
	console.log(e.point.lng + "," + e.point.lat);
});

3.使用label结合echarts对marker进行标注

定义样式:

.angle{
	    display: inline-block;
	    width: 0px;
	    height: 0px;
	    position: absolute;
	    border: 18px solid;
	    left: 20px;
	    bottom: -36px;
	    opacity: 0.5;
	    border-color: #333333 transparent transparent transparent;
	}

定义必要的js变量

	var lastMarker;
	//label样式
	var labelStyle = { 
		width:"450px",
		height:"300px",
		border: "none",
		borderRadius:"15px",
		backgroundColor: "rgba(50,50,50,0.5)",
		color: "#fff",
		fontSize : "18px",
		verticalAlign:"center",
		whiteSpace:"normal",
		wordWrap:"break-word",
		padding:"7px"
     };
  	//pie option
	var option = {
		title : {
			text: '某站点用户访问来源',
			subtext: '纯属虚构',
			x:'center'
		},
		tooltip : {
			trigger: 'item',
			formatter: "{a} <br/>{b} : {c} ({d}%)"
		},
		legend: {
			orient: 'vertical',
			left: 'left',
			data: ['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']
		},
		series : [
			{
				name: '访问来源',
				type: 'pie',
				radius : '55%',
				center: ['50%', '60%'],
				data:[
					{value:335, name:'直接访问'},
					{value:310, name:'邮件营销'},
					{value:234, name:'联盟广告'},
					{value:135, name:'视频广告'},
					{value:1548, name:'搜索引擎'}
				],
				itemStyle: {
					emphasis: {
						shadowBlur: 10,
						shadowOffsetX: 0,
						shadowColor: 'rgba(0, 0, 0, 0.5)'
					}
				}
			}
		]
	};

	//points为marker点数据    pieInfo 为不同饼图信息
	for(var i=0;i<points.length; i++){
    	var point = new BMap.Point(points[i].lng,points[i].lat);
		addMarker(point,i,pieInfo[i]);
	}

定义js函数

	//添加标注点和饼图
	function addMarker(point, index, pieData) {
		var content = "<div id='pie"+index+"' style='height: 100%'></div>";
		var spanA="<span class='angle'><span>";
		//创建标注
        var marker = new BMap.Marker(point);
		//创建文本说明
        var label = new BMap.Label();
        label.setStyle(labelStyle);
        label.setContent(content+spanA);
        label.setOffset(new BMap.Size(-29, -325));
       	//添加标注事件
        marker.addEventListener("click",function(){
        	this.setTop(true);//置顶 解决其他marker显示在label之上的问题
        	if(this.getLabel()==null){
        		if(lastMarker!=undefined && lastMarker.getLabel() != null){//关闭上一个打开的label
	        		lastMarker.setTop(false);
	        		BaiduMap.removeOverlay(lastMarker.getLabel());
        		}
	        	this.setLabel(label);
	        	openIPie("pie"+index,pieData);//显示饼图
        	}else{
	    		BaiduMap.removeOverlay(this.getLabel());
        	}
        	lastMarker=this;
        });
		
        BaiduMap.addOverlay(marker);//将标注添加到地图上
    }
  //显示饼图
	function openIPie(id,pieData){
		var piediv = document.getElementById(id);
		var myChart = echarts.init(piediv);
		option.title.text = pieData.label+"社保卡发卡银行分布(卡数量)";
		option.series[0].data = pieData.seriesData;
		if (option && typeof option === "object") {
		    myChart.setOption(option, true);
		}
	}

数据格式说明:

	points = [
		{"lng":117.418261,"count":1700,"lat":37.921984},
		{"lng":117.518261,"count":650,"lat":37.321984}]
	pieInfo = [
	{"seriesData":[ {"name":"农业银行","value":200},
					{"name":"中国银行","value":1500}],
	"label":"大道王村"},
	{"seriesData":[ {"name":"工商银行","value":340},
					{"name":"农商银行","value":310}],
	"label":"小道王村"}]

到此为止,点击marker就可以正确的显示饼图信息,成果图如下:
在这里插入图片描述

4.不同的地图缩放级别显示不同的marker

这个问题解决起来也很简单,即给地图添加监听事件

BaiduMap.addEventListener("zoomend", zoomedFun);
function zoomedFun(){
	var ZoomNum = BaiduMap.getZoom();
	if(ZoomNum<=14){
		alert("获取marker1进行展示");
	}else{
		alert("获取marker2进行展示");
	}
}

当然如果你的marker数据是放在数据库中,那么这个方式可能或涉及到多次请求数据库的问题。不妨使用缓存来解决多次请求数据库的问题,当然也可以使用其他更好的方式来解决;

5.本文完整代码

如果下载积分足够,并且有需要的读者,可以进行下载>>点我下载

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值