海量点标记 最后更新时间: 2022年05月13日
本章介绍在图面添加数量为万级以上的点标记的解决方案。包括:
1. 海量标注 LabelMarker
2. 海量点标记 MassMarks
3. 点聚合 MarkerCluster
海量标注 LabelMarker
当需要在地图添加千级以上的点标记时,LabelMarker 是代替 Marker 的更好选择。不同于 MassMarks ,LabelMarker 不仅可以绘制图标,还可以为图标添加文字信息,且万级以上数据也具有较好性能,配置也更加灵活。
另外,LabelMarker 之间还支持避让功能,JSAPI 2.0 版本还支持地图标注避让 LabelMarker,可以让您的 marker 更加明显。
一. 创建 LabelMarker
创建一个标注对象,首先要设置标注的位置,同时还可以通过 icon 和 text 属性设置图标和文字(也可以缺省)。
- 设置一个图标对象
var icon = {
// 图标类型,现阶段只支持 image 类型
type: 'image',
// 图片 url
image: 'https://a.amap.com/jsapi_demos/static/demo-center/marker/express2.png',
// 图片尺寸
size: [64, 30],
// 图片相对 position 的锚点,默认为 bottom-center
anchor: 'center',
};
2. 设置文字对象
var text = {
// 要展示的文字内容
content: '中邮速递易',
// 文字方向,有 icon 时为围绕文字的方向,没有 icon 时,则为相对 position 的位置
direction: 'right',
// 在 direction 基础上的偏移量
offset: [-20, -5],
// 文字样式
style: {
// 字体大小
fontSize: 12,
// 字体颜色
fillColor: '#22886f',
// 描边颜色
strokeColor: '#fff',
// 描边宽度
strokeWidth: 2,
}
};
3. 创建 LabelMarker 实例
var labelMarker = new AMap.LabelMarker({
name: '标注2', // 此属性非绘制文字内容,仅最为标识使用
position: [116.466994, 39.984904],
zIndex: 16,
// 将第一步创建的 icon 对象传给 icon 属性
icon: icon,
// 将第二步创建的 text 对象传给 text 属性
text: text,
});
二. 创建 LabelsLayer
LabelsLayer 图层是承载 LabelMarker 的图层,所有创建的 LabelMarker 需要添加到 LabelsLayer 图层上才能最终展示在地图上。
- 创建 LabelsLayer
var labelsLayer = new AMap.LabelsLayer({
zooms: [3, 20],
zIndex: 1000,
// 该层内标注是否避让
collision: true,
// 设置 allowCollision:true,可以让标注避让用户的标注
allowCollision: true,
});
2. 将已创建的 LabelMarker 添加到 LabelsLayer 上
// 添加一个 labelMarker
labelsLayer.add(labelsMarker);
// 批量添加 labelMarker
labelsLayer.add([labelsMarker1, labelsMarker2]);
3. 移除 LabelMarker
// 移除一个 labelMarker
labelsLayer.remove(labelsMarker);
// 批量移除 labelMarker
labelsLayer.remove([labelsMarker1, labelsMarker2]);
三. 将 LabelsLayer 添加到地图实例
map.add(labelsLayer);
四. 为 LabelMarker 添加事件
LabelMarker 与其它覆盖物添加事件的方式一致,例如:
// 为 labelMarker 绑定事件
labelMarker.on('click', function(e){
labelMarker.setOpacity(0.5);
});
通过以上几个步骤就可以成功在地图上添加高性能且支持避让的 LabelMarker 啦!
如果想添加海量的标记数据,可参考示例 标注与标注图层-海量点
海量点标记 MassMarks
当需要在地图展示数量为十万以内的点并且需要较好的性能表现时,可以使用 AMap.MassMarks 类。AMap.MassMarks 并不是普通的覆盖物,它实际上是由海量点组成的一个地图图层, 目前仅适用于html5浏览器。创建方式如下:
1. 创建海量点对象,设置点样式:
// 创建样式对象
var styleObject = {
url: '//vdata.amap.com/icons/b18/1/2.png', // 图标地址
size: new AMap.Size(11,11), // 图标大小
anchor: new AMap.Pixel(5,5) // 图标显示位置偏移量,基准点为图标左上角
}
var massMarks = new AMap.MassMarks({
zIndex: 5, // 海量点图层叠加的顺序
zooms: [3, 19], // 在指定地图缩放级别范围内展示海量点图层
style: styleObject // 设置样式对象
});
2. 设置 MassMarks 展现的数据集:
var data = [{
lnglat: [116.405285, 39.904989], //点标记位置
name: 'beijing',
id:1
}, // {}, …,{}, …
];
massMarks.setData(data);
// 将海量点添加至地图实例
massMarks.setMap(map);
如果想为海量点添加多种点样式,可以创建多个 AMap.StyleObject 对象, 以数组的方式添加到 massMarks 中。
// 创建样式对象, JSAPI 2.0 支持显示设置 zIndex, zIndex 越大约靠前,默认按顺序排列
var style = [{
url: 'https://a.amap.com/jsapi_demos/static/images/mass0.png',
anchor: new AMap.Pixel(6, 6),
size: new AMap.Size(11, 11),
// zIndex: 每种样式图标的叠加顺序,数字越大越靠前
zIndex: 3,
}, {
url: 'https://a.amap.com/jsapi_demos/static/images/mass1.png',
anchor: new AMap.Pixel(4, 4),
size: new AMap.Size(7, 7),
zIndex: 2,
}, {
url: 'https://a.amap.com/jsapi_demos/static/images/mass2.png',
anchor: new AMap.Pixel(3, 3),
size: new AMap.Size(5, 5),
zIndex: 1,
}];
// 实例化 AMap.MassMarks
var massMarks = new AMap.MassMarks({
zIndex: 5, // 海量点图层叠加的顺序
zooms: [3, 19], // 在指定地图缩放级别范围内展示海量点图层
style: style, //多种样式对象的数组
});
// 设置了样式索引的点标记数组
var data = [{
lnglat: [116.405285, 39.904989],
name: 'beijing',
id:1,
style: 0 // 该数据的样式取值styleObjectArr对应的样式索引
},{
lnglat: [116.405285, 39.904989],
name: 'beijing',
id:1,
style: 1
} //, …,{}, …
];
// 将数组设置到 massMarks 图层
massMarks.setData(data);
// 将 massMarks 添加到地图实例
massMarks.setMap(map);
点聚合 MarkerCluster
在不同的地图缩放级别对海量的数据点进行聚合展示。目前点聚合插件在点的数量在10万以内时可以保持较好的性能。点聚合支持用户自定义点标记。创建方式如下:
/利用styles属性修改点聚合的图标样式
var styles = [{
url:"imgs/1.png",
size:new AMap.Size(32,32),
offset:new AMap.Pixel(-16,-30)
},
{
url:"imgs/2.png",
size:new AMap.Size(32,32),
offset:new AMap.Pixel(-16,-30)
},
{
url:"imgs/3.png",
size:new AMap.Size(48,48),
offset:new AMap.Pixel(-24,-45),
textColor:'#CC0066'
}];
// 聚合点数据应该是一组包含经纬度信息的数组。lnglat 为经纬度信息字段,weight 字段为可选数据,表示权重值,以权重高的点为中心进行聚合。
var points = [
{ weight: 8, lnglat: ["108.939621", "34.343147"] },
{ weight: 1, lnglat: ["113.370643", "22.938827"] },
{ weight: 1, lnglat: ["112.985037", "23.15046"] },
{ weight: 1, lnglat: ["110.361899", "20.026695"] },
{ weight: 1, lnglat: ["121.434529", "31.215641"] },
...
];
//添加聚合组件
map.plugin(["AMap.MarkerClusterer"],function() {
cluster = new AMap.MarkerClusterer(
map, // 地图实例
points, // 海量点数据,数据中需包含经纬度信息字段 lnglat
{
styles: styles
});
});