这是我参与更文挑战的第9天,活动详情查看: 更文挑战 !
👽 概论
昨天和大家分享了《百度地图热力图开发及区域边界线的实现》,今天就趁热打铁,再和大家分享下地图上自定义标注的方法,先上完成后的效果图。
👻 开发准备
开发准备与之前基本一样,只是去掉了暂时用不到的热力图库及数据。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>百度热力地图</title>
<style>
html,
body {
height: 100%;
padding: 0;
}
#map {
height: 1200px;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
</body>
<!-- 百度地图API -->
<script
type="text/javascript"
src="http://api.map.baidu.com/api?v=3.0&ak=xxxxxxxxx"
></script>
<!-- 区块边界数据 -->
<script type="text/javascript" src="./data/features.js"></script>
<!-- 逻辑JS -->
<script type="text/javascript" src="index.js"></script>
</html>
👽 初始化百度地图
这块不多说了,有疑惑的请看我概论提到的那篇文章。
👽 自定义标注的实现
这里的自定义标注有两层含义:一是在任意位置上实现标注;二是自定义标注的样式。百度地图上的标注类型有很多,但其实用起来都差不多。我们此次选用其中的Label类型来实现(主要是看重该类型可以添加文本内容,如不需要也可以使用其他类型的标注)。
下面我们就通过一个例子来同时实现。
function initMap(domID, centerPoint, styleId) {
let mapInstance = new BMap.Map(domID); // 创建地图实例
mapInstance.centerAndZoom(centerPoint, 13); //设置中心点及缩放级别
mapInstance.setMapStyleV2({ styleId }); //设置样式ID
mapInstance.enableScrollWheelZoom();
mapInstance.enableDragging();
mapInstance.disableDoubleClickZoom();
return mapInstance;
}
function generateDistrictBoundary(mapInstance, districtName, style) {
let bdary = new BMap.Boundary();
bdary.get(districtName, function (res) {
let boundaries = res.boundaries;
let points = [];
//之所以用循环,是因为部分行政区存在飞地,区划会分为多块,所以需要遍历生成
boundaries.forEach(boundary => {
let polygon = generateBoundary(mapInstance, boundary, style);
let path = polygon.getPath();
points = points.concat(path);
});
});
}
function generateBoundary(mapInstance, points, style) {
let polygon = new BMap.Polygon(points, style); //创建多边形
// 添加覆盖物
mapInstance.addOverlay(polygon); //增加多边形
return polygon;
}
const iconList = [
'url(./icon/五角星.png)',
'url(./icon/正方形.png)',
'url(./icon/圆形.png)',
'url(./icon/三角形.png)',
'url(./icon/六边形.png)',
'url(./icon/五边形.png)',
];
function generateLabel(point) {
/** 第一步 定义label实体 */
const label = new BMap.Label();
/** 第二步 定义label的样式及位置 */
label.setPosition(point.position); //自定义label的坐标
//值得注意的是,position应该是百度的Point类实例,而不是见得经纬数值
label.setContent(point.content); //设置label的文本内容
//自定义label样式(这一块可发挥的空间非常大,基本上所有css属性都可在此使用
//只需注意将原本的连字符属性名换为小驼峰即可
label.setStyle({
width: '8px',
height: '8px',
lineHeight: '8px',
textAlign: 'center',
backgroundImage: iconList[point.type], //最最关键的就是背景图片属性,据此我们可以实现任意样式
backgroundSize: 'contain',
backgroundPosition: 'center center',
backgroundRepeat: 'no-repeat',
backgroundColor: 'transparent',
color: '#000',
borderColor: 'transparent',
});
/** 第三步 将label实体添加到图上 */
mapInstance.addOverlay(label);
}
window.onload = function () {
let centerPoint = new BMap.Point(104.084207, 30.695243);
let styleId = '02f2d7d1f52e7261479d4a9755a8485e';
let mapInstance = initMap('map', centerPoint, styleId);
let style = {
strokeWeight: 3,
strokeColor: '#2c2a2a',
strokeStyle: 'dashed',
fillColor: '#fff',
};
generateDistrictBoundary(mapInstance, '金牛区', style);
/** data数据结构
* data = [
* ···
* { posotion: new BMap.Point(104.068551, 30.723895), type: 1,content:1, }
* ···
* ]
*/
data.forEach(point => generateLabel(point));
};
最终效果如下:
👽 结语
有一说一,百度地图做图还是挺好用的。大家快尝试起来。