最近有一些网友问我,聚合显示怎么实现聚合与不聚合之间的切换,有很多方法能够实现,下面是一个示例作为参考。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>加载天地图</title>
<link href="ol/ol.css" rel="stylesheet" type="text/css" />
<script src="ol/ol.js" type="text/javascript"></script>
<style type="text/css">
html,body{
margin:0px;
padding:0px;
}
#mapCon {
width: 100%;
height: 98%;
}
</style>
</head>
<body>
<!-- 地图容器 -->
<div id="mapCon"></div>
<div style="position: absolute;top:10px;left:50px;">
<button onclick="toggleCluster()">切换聚合</button>
</div>
<script type="text/javascript">
var key = "4689fc6b9bc0fdc8c48298f751ebfb41";//天地图密钥
var center = [116.3913,39.9071];
var pointArr = [[116.3913,39.9071],[116.3813,39.9071],[116.3713,39.9071],[116.3613,39.9071],[115.3913,38.9071],[115.3813,38.9071],[115.3613,38.9071],[115.3313,38.9071]];//北京经纬度
//ol.layer.Tile:是一个瓦片图层类,用于显示瓦片资源。
//source是必填项,用于为图层设置来源。
//ol.source.XYZ:
//创建天地图矢量图层
var TiandiMap_vec = new ol.layer.Tile({
title: "天地图矢量图层",
source: new ol.source.XYZ({
url: "http://t{0-7}.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=" + key,
wrapX: false
})
});
//创建天地图矢量注记图层
var TiandiMap_cva = new ol.layer.Tile({
title: "天地图矢量注记图层",
source: new ol.source.XYZ({
url: "http://t{0-7}.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=" + key,
})
});
//1. 实例化Map对象加载地图
var map = new ol.Map({
//地图容器div的ID
target: 'mapCon',
//地图容器中加载的图层
layers: [TiandiMap_vec, TiandiMap_cva],
//地图视图设置
view: new ol.View({
//地图初始中心点(经纬度)
center: center,
//地图初始显示级别
zoom: 8,
projection: "EPSG:4326"
})
});
//2.创建用于放置标注的矢量图层以及图层源
//矢量标注的数据源-非聚合
var vectorSource = new ol.source.Vector();
//3.聚合标注数据源
var clusterSource = new ol.source.Cluster({
distance: 40,
source: vectorSource
});
var styleCache = {};
//矢量标注图层
var vectorLayer = new ol.layer.Vector({
source: clusterSource,//初始设置源为聚合源
zIndex:1000,
style: function (feature, resolution) {
var size = feature.get('features').length;
var style;
//当前的标注仅包含一个feature时,采用该feature的样式显示,而不是统一聚合样式,这个很有用
if (size == 1) {
style = styleCache[feature.get('features')[0].get("name")];
} else {
style = styleCache[size];
}
if (!style) {
style = [
new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: '#fff'
}),
fill: new ol.style.Fill({
color: '#cc4700'
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff'
})
})
})
];
if (size == 1) {
//这里采用那么作为styleCache对象key的值,name是唯一的,
//这样就可以为为每一个feature设置不同的样式,因为起初feature未聚合前,
//可能会使用不同的图标来表示不同的目标
let pkiaa = feature.get('features')[0].get("name");
style = feature.get('features')[0].getStyle();
styleCache[pkiaa] = style;
} else {
styleCache[size] = style;
}
}
return style;
}
});
map.addLayer(vectorLayer);
//4.实例化矢量标注对象并添加到矢量图层源
for (let index = 0; index < pointArr.length; index++) {
const element = pointArr[index];
var markerFeature = new ol.Feature({
geometry: new ol.geom.Point(element),
name:'point_'+index,//保证唯一性,在聚合显示时用于区分独立的 style
});
markerFeature.setStyle(createMarkerStyle(markerFeature));
//将新要素添加到数据源中
vectorSource.addFeature(markerFeature);
}
//切换聚合状态
function toggleCluster(){
//获取当前矢量图层的源
let vecSource = vectorLayer.getSource();
//判断矢量图层的 源 是否 有 distance属性,该属性是聚合矢量源特有,可以根据此来判断当前 矢量图层的源是 聚合源还是非聚合源
//如果有distance属性,则设置矢量图层的源 为 非聚合源
if (vecSource.distance !=undefined){
vectorLayer.setSource(vectorSource);
}
//如果没有distance属性,则设置矢量图层的源 为 聚合源
else{
vectorLayer.setSource(clusterSource);
}
}
//创建矢量标注样式
function createMarkerStyle(feature) {
//获取name,根据不同的name,配置不同的图标
let name = feature.get("name");
let index = name.split('_')[1];
console.log(index);
let imageUrl = 'static/img/hq.png';
if (index%2 == 0) {//与2求余为0的,设置为勋章 标记
imageUrl = "static/img/xz.png";
}
return new ol.style.Style({
/**{olx.style.IconOptions}类型*/
image: new ol.style.Icon(
({
// anchor: [0.5, 0.5],//图标的锚点,经纬度点所对应的图标的位置,默认是[0.5, 0.5],即为标注图标的中心点位置
anchorOrigin: 'top-right',//锚点的偏移位置,默认是top-left,
anchorXUnits: 'fraction',//锚点X的单位,默认为百分比,也可以使用px
anchorYUnits: 'pixels',//锚点Y的单位,默认为百分比,也可以使用px
offsetOrigin: 'top-right',//原点偏移bottom-left, bottom-right, top-left, top-right,默认 top-left
// offset:[0,10],
//图标缩放比例
// scale:0.5,//可以设置该比例实现,图标跟随地图层级缩放
//透明度
opacity: 0.75,//如果想隐藏某个图标,可以单独设置该值,透明度为0时,即可隐藏,此为隐藏元素的方法之一。
//图标的url
src: imageUrl
})
),
text: new ol.style.Text({
//位置
textAlign: 'center',
//基准线
textBaseline: 'middle',
//文字样式
font: '20px 宋体',
//文本内容
text: feature.get('name'),//通过设置的fature的name属性获取,也可以通过参数获取设置,此处接收 字符串 对象
//文本填充样式(即文字颜色),红色
fill: new ol.style.Fill({ color: '#ff002f' }),
//描边颜色,蓝色
stroke: new ol.style.Stroke({ color: '#0022ff', width: 1 })
})
});
}
</script>
</body>
</html>