源码附件已更新,贴上了可以使用的密钥以及所需js文件 2020.4.14 下载
这周使用到了百度地图api进行网页开发,主要涉及了marker点的文字标注,即label结合echarts使用;绘制热力图以及对不同的地图缩放级别显示不同的marker点;
最终效果图如下:
使用百度地图创建热力图首先需要在
内引入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);
});
定义样式:
.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}
{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 = "";
var spanA="";
//创建标注
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就可以正确的显示饼图信息,成果图如下:
这个问题解决起来也很简单,即给地图添加监听事件
BaiduMap.addEventListener("zoomend", zoomedFun);
function zoomedFun(){
var ZoomNum = BaiduMap.getZoom();
if(ZoomNum<=14){
alert("获取marker1进行展示");
}else{
alert("获取marker2进行展示");
}
}
当然如果你的marker数据是放在数据库中,那么这个方式可能或涉及到多次请求数据库的问题。不妨使用缓存来解决多次请求数据库的问题,当然也可以使用其他更好的方式来解决;
如果下载积分足够,并且有需要的读者,可以进行下载>>点我下载