场景
Openlayers中实现地图上打点并显示图标和文字:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/118631046
上面实现加载显示离线地图并显示图标元素的效果后。
实现当多个元素堆积在一起时实现聚合显示效果。
并且伴随着地图的缩放实现自动聚合显示和取消聚合。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
1、随机创建一些要素
// 随机创建要素 var clusterSource = new ol.source.Vector(); debugger for (var i = 1; i <= 10; i++) { var coordinates = [-11551949.709486058 + Math.random(), 5533080.7247905275 + Math.random()]; var feature = new ol.Feature(new ol.geom.Point(coordinates)); clusterSource.addFeature(feature); } for (var i = 1; i <= 20; i++) { var coordinates = [-11553949.709486058 + Math.random(), 5527080.7247905275 + Math.random()]; var feature = new ol.Feature(new ol.geom.Point(coordinates)); clusterSource.addFeature(feature); }
这里的坐标值是从地图上获取的一些坐标值,然后通过对x和y随机增加随机数,构造一组10和一组20个的要素。
2、新建聚合图层数据源
// 聚合图层数据源 var clusterSourceForLayer = new ol.source.Cluster({ source: clusterSource, distance: 100 })
这里的distance就是设置的聚合的距离。
3、新建聚合图层
// 聚合图层 var clusterLayer = new ol.layer.Vector({ source: clusterSourceForLayer, style: function (feature, resolution) { var size = feature.get('features').length; if (size == 1) { return new ol.style.Style({ image: new ol.style.Icon({ scale: 0.8, src: './icon/house.png', anchor: [0.48, 0.52] }), text: new ol.style.Text({ font: 'normal 12px 黑体', // // 对其方式 textAlign: 'center', // 基准线 textBaseline: 'middle', offsetY: -35, offsetX: 0, backgroundFill: new ol.style.Stroke({ color: 'rgba(0,0,255,0.7)', }), // 文本填充样式 fill: new ol.style.Fill({ color: 'rgba(236,218,20,1)' }), padding: [5, 5, 5, 5], text: `霸道的程序猿`, }) }); } else { return new ol.style.Style({ image: new ol.style.Circle({ radius: 30, stroke: new ol.style.Stroke({ color: 'white' }), fill: new ol.style.Fill({ color: 'blue' }) }), text: new ol.style.Text({ text: size.toString(), fill: new ol.style.Fill({ color: 'white' }) }) }); } } });
注意这里的核心的代码就是
style: function (feature, resolution) { var size = feature.get('features').length; if (size == 1) { }else{ }
如果size大于1则返回聚合样式,反之则返回图片样式。
4、将聚合图层添加进地图
//View 视图管理器,主要用来管理地图视图,分辨率或旋转,中心、投影、分辨率、缩放级别等。 var view = new ol.View({ //中心点 center: [-11549894, 5533433], //缩放等级 zoom: 11, //投影坐标系 projection: projection, //边界 extent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34] }); //Map Openlayers的核心组件,包含图层、交互事件、UI控制元素等。 var map = new ol.Map({ layers: [layer, clusterLayer], target: 'map', view: view });
5、除此之外的代码就是离线加载瓦片地图的代码,完整代码
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>OpenLayers example</title> <link rel="stylesheet" href="lib/ol65/ol.css" type="text/css"> <style> html, body, #map { padding: 0; margin: 0; 100%; height: 100%; overflow: hidden; } </style> </head> <body> <div id="map"></div> <script type="text/javascript" src="lib/ol65/ol.js"></script> <script type="text/javascript"> var source = new ol.source.XYZ({ tileUrlFunction: function (xyz, obj1, obj2) { if (!xyz) return ""; var z = xyz[0]; var x = Math.abs(xyz[1]); var y = Math.abs(xyz[2]); var xyz_convert = self.convert_(z, x, y); x = xyz_convert[0]; y = xyz_convert[1]; z = xyz_convert[2]; var shift = z / 2; var half = 2 << shift; var digits = 1; if (half > 10) digits = parseInt(Math.log(half) / Math.log(10)) + 1; var halfx = parseInt(x / half); var halfy = parseInt(y / half); x = parseInt(x); y = parseInt(y) - 1; var url = "./images/EPSG_900913" + "_" + self.padLeft_(2, z) + "/" + self.padLeft_(digits, halfx) + "_" + self.padLeft_(digits, halfy) + "/" + self.padLeft_(2 * digits, x) + "_" + self.padLeft_(2 * digits, y) + "." + 'png'; return url; } }); //projections投影坐标系转换相关的操作 var projection = new ol.proj.Projection({ code: 'EPSG:900913', units: 'm', axisOrientation: 'neu' }); //Layers 图层管理类,用来管理图层信息。主要包括Tile,Image,Vector,VectorTile等图层。 var layer = new ol.layer.Tile({ source: source }); // 随机创建要素 var clusterSource = new ol.source.Vector(); debugger for (var i = 1; i <= 10; i++) { var coordinates = [-11551949.709486058 + Math.random(), 5533080.7247905275 + Math.random()]; var feature = new ol.Feature(new ol.geom.Point(coordinates)); clusterSource.addFeature(feature); } for (var i = 1; i <= 20; i++) { var coordinates = [-11553949.709486058 + Math.random(), 5527080.7247905275 + Math.random()]; var feature = new ol.Feature(new ol.geom.Point(coordinates)); clusterSource.addFeature(feature); } // 聚合图层数据源 var clusterSourceForLayer = new ol.source.Cluster({ source: clusterSource, distance: 100 }) // 聚合图层 var clusterLayer = new ol.layer.Vector({ source: clusterSourceForLayer, style: function (feature, resolution) { var size = feature.get('features').length; if (size == 1) { return new ol.style.Style({ image: new ol.style.Icon({ scale: 0.8, src: './icon/house.png', anchor: [0.48, 0.52] }), text: new ol.style.Text({ font: 'normal 12px 黑体', // // 对其方式 textAlign: 'center', // 基准线 textBaseline: 'middle', offsetY: -35, offsetX: 0, backgroundFill: new ol.style.Stroke({ color: 'rgba(0,0,255,0.7)', }), // 文本填充样式 fill: new ol.style.Fill({ color: 'rgba(236,218,20,1)' }), padding: [5, 5, 5, 5], text: `霸道的程序猿`, }) }); } else { return new ol.style.Style({ image: new ol.style.Circle({ radius: 30, stroke: new ol.style.Stroke({ color: 'white' }), fill: new ol.style.Fill({ color: 'blue' }) }), text: new ol.style.Text({ text: size.toString(), fill: new ol.style.Fill({ color: 'white' }) }) }); } } }); //View 视图管理器,主要用来管理地图视图,分辨率或旋转,中心、投影、分辨率、缩放级别等。 var view = new ol.View({ //中心点 center: [-11549894, 5533433], //缩放等级 zoom: 11, //投影坐标系 projection: projection, //边界 extent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34] }); //Map Openlayers的核心组件,包含图层、交互事件、UI控制元素等。 var map = new ol.Map({ layers: [layer, clusterLayer], target: 'map', view: view }); //xy行列转换 function convert_(zoomLevel, x, y) { var extent = Math.pow(2, zoomLevel); if (x < 0 || x > extent - 1) { console.log("The X coordinate is not sane: " + x); return; } if (y < 0 || y > extent - 1) { console.log("The Y coordinate is not sane: " + y); return; } // openlayers 6.0版本 var gridLoc = [x, extent - y, zoomLevel]; // openlayers 4.5版本 // var gridLoc = [x, extent - y + 1, zoomLevel]; return gridLoc; } //字符截取 function padLeft_(num, val) { return (new Array(num).join('0') + val).slice(-num); } </script> </body> </html>