最近有一些网友问我,聚合显示怎么实现聚合与不聚合之间的切换,有很多方法能够实现,下面是一个示例作为参考。
<!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的IDtarget: '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的单位,默认为百分比,也可以使用pxanchorYUnits: 'pixels',//锚点Y的单位,默认为百分比,也可以使用pxoffsetOrigin: 'top-right',//原点偏移bottom-left, bottom-right, top-left, top-right,默认 top-left// offset:[0,10],//图标缩放比例// scale:0.5,//可以设置该比例实现,图标跟随地图层级缩放//透明度opacity: 0.75,//如果想隐藏某个图标,可以单独设置该值,透明度为0时,即可隐藏,此为隐藏元素的方法之一。//图标的urlsrc: 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>