Openlayers 聚合图、权重聚合图以及聚合图点击事件

  • OpenLayers 教程
    • Openlayers 聚合图、权重聚合图、聚合图事件
    • 在线示例

OpenLayers 教程

在实际工作中,Openlayers 渲染数据的方式有很多种(WMS、瓦片、矢量数据等),一次性渲染较大数据量的情况下,需要做成静态切片,比如WMTS、TMS;或者矢量切片,比如 Geojson、mvt 等。

对于数据量不是很大的数据,常常使用 热力图、聚合图 的方式在前端渲染,能够更好的体现数据特征。

本示例基于实际项目中的应用,介绍: 加载聚合图、权重聚合图、聚合图参数、聚合图点击事件 等功能的用法。

PS:如果数据量很大的话,建议数据入库,使用数据库的聚合函数来实现。

Openlayers 聚合图、权重聚合图、聚合图事件

<html lang="en">
<head><meta charSet="utf-8"><!--注意:openlayers 原版的比较慢,这里引起自己服务器版--><link rel="stylesheet" href="http://openlayers.vip/examples/css/ol.css" type="text/css"><style>/* 注意:这里必须给高度,否则地图初始化之后不显示;一般是计算得到高度,然后才初始化地图 */.map {height: 700px;width: 100%;float: left;}</style><!--注意:openlayers 原版的比较慢,这里引起自己服务器版--><script src="http://openlayers.vip/examples/resources/ol.js"></script><script src="http://openlayers.vip/examples/resources/jquery-3.5.1.min.js"></script><script src="./tiandituLayers.js"></script><title>OpenLayers example</title>
</head>
<body>
<h2>OpenLayers Cluster</h2>
<!--地图容器,需要指定 id -->
<div id="map" class="map"></div><script type="text/javascript">var map = new ol.Map({// 地图容器target: 'map',// 地图图层,比如底图、矢量图等layers: [getIMG_CLayer(),getIBO_CLayer(),getCIA_CLayer(),],// 地图视野view: new ol.View({projection: "EPSG:4326",// 定位center: [115.67724700667199, 37.73879478106912],// 缩放zoom: 6,maxZoom: 18,minZoom: 1,})});/*** @todo wkt格式数据转化成图形对象* @param {string} wkt   "POINT(112.7197265625,39.18164062499999)" 格式数据* @param {string|Projection} sourceCode 源投影坐标系* @param {string|Projection} targetCode 目标投影坐标系* @returns {Feature}*/function getFeatureByWKT(wkt, sourceCode, targetCode) {try {let view = map.getView();if (!wkt) {return null;}let format = new ol.format.WKT();let feature;feature = format.readFeature(wkt, {featureProjection: targetCode || view.getProjection(),dataProjection: sourceCode || view.getProjection(),});return feature;} catch (e) {console.log(e);return null;}}/*** @todo 颜色十六进制转为 rgba* @param sColor 格式数据* @param opacity* @returns rgba颜色字符串*/function colorToRgb(sColor, opacity) {//用于十六进制颜色和rgb转换的正则var REG = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;sColor = sColor.toLowerCase();if (/^[A-Za-z]+$/.test(sColor))return sColor;if (sColor && REG.test(sColor)) {if (sColor.length === 4) {let sColorNew = "#";for (let i = 1; i < 4; i += 1) {sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));}sColor = sColorNew;}//处理六位的颜色值let sColorChange = [];for (let i = 1; i < 7; i += 2) {sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));}if (opacity)sColorChange.push(opacity);return "rgba(" + sColorChange.join(",") + ")";// return sColorChange;} else {return sColor;}};// 地图事件function clickFunction(evt) {let feature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layerVetor) {return feature.getProperties().features;});// 图形要素的点击事件// 这里可以使用气泡框展示信息if (feature && feature.length == 1) {console.log(feature[0]);alert('点击了:' + feature[0].get('name'));} else {feature && console.log(feature);feature && alert('点击了包含:' + feature.length + ' 个图形要素的聚合图!');}}// 初始化点击事件标记var initClickFlag = false;// 点击事件function activateClickFunc() {initClickFlag && alert('已开启点击事件!');map.on('click', clickFunction);initClickFlag = true;}// 关闭点击事件function shutDownClick() {alert('已关闭点击事件!');map.un('click', clickFunction);}// 点线面数组var features = undefined;// 聚合图图层对象var clusterLayer = undefined;// 资源对象var vectorSource = undefined;// 聚合图对象var clusterSource = undefined;// 初始化聚合图function initCluster() {features = [];// 模拟数据for (var i = 1; i <= 15; i++) {var feature = getFeatureByWKT("POINT(" + (113 + (i / 10)) + " " + (35 + (i / 10)) + ")");var feature2 = getFeatureByWKT("POINT(" + (113 + ((i + 5) / 10)) + " " + (35 + (i / 10)) + ")");var feature3 = getFeatureByWKT("POINT(" + (113 + ((i + 9) / 10)) + " " + (35 + (i / 10)) + ")");var point = new ol.style.Style({// 点样式image: new ol.style.Icon({// 允许跨域,如果不设置,打印地图不会打印crossOrigin: 'anonymous',// 标注图片和文字之间的距离anchor: [0.5, 0],// 图片的偏移offset: [0.2, 0],// 图片的锚点,一般来说,都是右下角anchorOrigin: 'bottom-right',//图标的urlsrc: "http://api.tianditu.gov.cn/v4.0/image/marker-icon.png",scale: 1,})});feature.setStyle(point);feature.set('name', 'feature1-' + i);feature.set('capability', i / 15);feature2.setStyle(point);feature2.set('name', 'feature2-' + i);feature2.set('capability', i / 15);feature3.setStyle(point);feature3.set('name', 'feature3-' + i);feature3.set('capability', i / 15);features.push(feature)features.push(feature2)features.push(feature3)}/*** 资源*/vectorSource = new ol.source.Vector({});// 聚合图clusterSource = new ol.source.Cluster({wrapX: false,source: vectorSource,});// 图层clusterLayer = new ol.layer.Vector({source: clusterSource,zIndex: 1,});map.addLayer(clusterLayer);}/*** todo 增加聚合图* @param dynamicData (参数是features)*/function addData(dynamicData, distance, original) {// 最大图形要素数量var maxFeatureCount;// 当前分辨率var currentResolution;// 普通样式,普通小圆圈var originalStyle = function (feature) {var features = feature.get('features');var size = features.length;return new ol.style.Style({image: new ol.style.Circle({radius: 30,stroke: new ol.style.Stroke({color: '#fff'}),fill: new ol.style.Fill({color: '#969696'})}),text: new ol.style.Text({text: size.toString(),fill: new ol.style.Fill({color: '#fff'})})});}// 动态样式样式,根据权重和数量计算var varyStyle = function (feature) {var originalFeatures = feature.get('features');var size = feature.get('features').length;var capability_avg = 0;var textName = "";var j = (void 0), jj = (void 0);for (j = 0, jj = originalFeatures.length; j < jj; ++j) {capability_avg += (originalFeatures[j].get("capability") || 1)textName = originalFeatures[j].get("name") || "";}capability_avg = (capability_avg / size).toFixed(2);var round = getPointArray(capability_avg);var opacity = Math.min(0.8, 0.4 + (size / maxFeatureCount));var style = new ol.style.Style({image: new ol.style.Circle({radius: feature.get('radius'),fill: new ol.style.Fill({color: colorToRgb(round.split(",")[1], opacity)})}),text: new ol.style.Text({// text: textName ? (textName + ":" + capability_avg) : feature.get('radius'),text: "权重平均值:" + capability_avg,font: 'normal bold  14px  Arial,sans-serif',fill: new ol.style.Fill({color: '#fff'}),stroke: new ol.style.Stroke({color: 'rgba(0, 0, 0, 0.6)',width: 3})})});return style;}// 单体 feature 样式var featureStyle = function (feature) {var originalFeatures = feature.get('features');if (originalFeatures.length != 1) {return;}var originalFeature = originalFeatures[0];var style = originalFeature.getStyle();style && style.setText(new ol.style.Text({text: originalFeature.get("name"),// 偏移offsetX: 0,offsetY: -54,// 居中textAlign: 'center',// 比例scale: 1,textBaseline: 'middle',// 边距padding: [2, 2, 2, 2],// 覆盖显示:即文字超过多边形也会显示overflow: true,// 字体颜色fill: new ol.style.Fill({color: 'rgba(51,51,51, 1)'}),// 字体边框,可以配合 fill 是文字高亮stroke: new ol.style.Stroke({color: 'rgba(0, 255, 255, 0.8)',width: 2,}),// 背景色backgroundFill: new ol.style.Fill({color: 'rgba(252,254,255, 1)'}),}))return style;}// 样式方法function styleFunction(feature, resolution) {// 如果是拖动地图,则不重新渲染样式if (resolution != currentResolution) {calculateClusterInfo(resolution);currentResolution = resolution;}var style;var size = feature.get('features').length || 0;// size大于1,则表示是聚合状态if (size > 1) {if (original == true) {style = originalStyle(feature);} else {style = varyStyle(feature);}// size 等于1,表示是单体 feature} else if (size == 1) {style = featureStyle(feature);}return style;}// 计算聚合图样式信息var calculateClusterInfo = function () {if (!clusterLayer) {return;}maxFeatureCount = 0;var features = clusterLayer.getSource().getFeatures();var feature, radius;for (var i = features.length - 1; i >= 0; --i) {feature = features[i];var originalFeatures = feature.get('features');// 计算权重var capability = 0;var j = (void 0), jj = (void 0);for (j = 0, jj = originalFeatures.length; j < jj; ++j) {// 这是使用 capability 自定义属性的值计算权重capability += (originalFeatures[j].get("capability") || 1)}// 根据实际的数据量,调整聚合显示半径的大小// PS:这个需要更新项目实际调整if (originalFeatures.length < 10) {radius = capability + originalFeatures.length;while (radius > 100) {radius = radius / 10;}radius = radius + 10;} else if (originalFeatures.length >= 10 && originalFeatures.length <= 50) {radius = capability + originalFeatures.length;while (radius > 100) {radius = radius / 10;}radius = radius + 20;} else if (originalFeatures.length > 100 && originalFeatures.length <= 5000) {radius = capability + originalFeatures.length;while (radius > 100) {radius = radius / 10;}} else if (originalFeatures.length > 5000 && originalFeatures.length <= 10000) {radius = capability + originalFeatures.length;while (radius > 100) {radius = radius / 10;}} else if (originalFeatures.length > 10000) {radius = capability + originalFeatures.length;while (radius > 100) {radius = radius / 10;}radius = radius;}// 取二者最大值maxFeatureCount = Math.max(maxFeatureCount, jj);feature.set('radius', radius);}};// 获取聚合图颜色// 自定义颜色(图例和颜色以逗号拼接)var getPointArray = function (v) {if (v >= 0.8 && v <= 1) return '0.8-1.0,#FF0000'else if (v >= 0.6 && v < 0.8) return '0.6-0.8,#FFFF00'else if (v >= 0.4 && v < 0.6) return '0.4-0.6,#DAA520'else if (v >= 0.2 && v < 0.4) return '0.2-0.4,#0000FF'else if (v >= 0 && v < 0.2) return '0-0.2,#228B22'}// 设置聚合距离,也就是半径范围内聚合clusterSource.setDistance(distance);// 添加数据vectorSource.addFeatures(features);// 设置样式clusterLayer && clusterLayer.setStyle(styleFunction)}// 添加聚合图// flag, true 为加载原始样式,其他为加载权重样式function addCluster(flag) {closeCluster();initCluster();flag ? addData(features, 60, flag) : addData(features, 40);}// 关闭聚合图function closeCluster() {clusterLayer && map.removeLayer(clusterLayer);clusterLayer = undefined;}// 默认加载原始聚合图addCluster(true);// 默认开始点击事件activateClickFunc();
</script>
<button id="addCluster" onClick="addCluster(true)">添加聚合图</button>
<button id="addWeightCluster" onClick="addCluster()">添加权重聚合图</button>
<button id="closeCluster" onClick="closeCluster()">关闭聚合图</button>
<button id="activateClickFunc" onClick="activateClickFunc()">开启点击事件</button>
<button id="shutDownClick" onClick="shutDownClick()">关闭点击事件</button>
</body>
</html>

PS:点击弹出气泡框可参考 Openlayers 自定义气泡框以及定位到气泡框

在线示例

Openlayers 聚合图:Openlayers-cluster

Openlayers 聚合图、权重聚合图以及聚合图点击事件相关推荐

  1. openlayers 给数据点(散点)添加点击事件 和hover事件

    前言:由于本人也是最近才开始学习openlayers,如说明的有所不对,请在评论区指出. 1.点击事件 /*** 捕捉点击事件*/featureClick(callback) {let _this = ...

  2. 优序图权重计算指标解读

    一.应用 问卷研究中,如果涉及计算权重,通常有以下几种做法,分别是AHP层次法.优序图法.熵值法.因子分析法(探索性因子和验证性因子分析). 二.操作 1.SPSSAU操作如下图: 2.案例背景 当前 ...

  3. [UML]UML系列——类图class的关联关系(聚合、组合)

    关联的概念 关联用来表示两个或多个类的对象之间的结构关系,它在代码中表现为一个类以属性的形式包含对另一个类的一个或多个对象的应用. 程序演示:关联关系(code/assocation) 假设:一个公司 ...

  4. 安卓高德地图聚合点击事件_滴滴进攻,华为入场,互联网地图迎来大变局|深响独家...

    ©深响原创 · 作者|丁直仁  核 心 要 点  市场可能高估了美团与滴滴之间的冲突,而低估了滴滴与高德之间的竞争. 从去年下半年开始,华为便在组建自己的地图团队. 腾讯地图或因数据质量问题遭遇考验: ...

  5. Java后端进行经纬度点抽稀聚合,HTML呈现及前端聚合实现点聚合~

    Java后端进行经纬度点抽稀聚合,HTML呈现及前端聚合实现点聚合~ 1. 效果图~ 1.1 前端实现聚合及呈现 1.2 后端实现点聚合,前端渲染呈现效果图 2. 原理 3. 源码 3.1 前端JS实 ...

  6. pandas使用groupby函数进行分组聚合、使用agg函数指定聚合统计计算的数值变量、并自定义统计计算结果的名称(naming columns after aggregation)

    pandas使用groupby函数进行分组聚合.使用agg函数指定聚合统计计算的数值变量.并自定义统计计算结果的名称(naming columns after aggregation in dataf ...

  7. Elasticsearch聚合学习之二:区间聚合

    本文是<Elasticsearch聚合学习>系列的第二篇,上一篇是我们熟悉了聚合的基本操作,本篇的内容是按照区间聚合的实战操作: 系列文章列表 <Elasticsearch聚合学习之 ...

  8. 2022最新独立版智狐聚合支付v1.0.5.21_聚合支付系统源码

    源码下载:2022最新独立版智狐聚合支付v1.0.5.21_聚合支付系统源码-小程序文档类资源-CSDN下载 PHP聚合支付源码 独立版智狐聚合支付v1.0.5.21 1.在宝塔新建个站点,php版本 ...

  9. Elasticsearch 7.X-8.0 AggregationBuliders 相关聚合函数(二)桶聚合-嵌套查询

    global 全局聚合 定义搜索执行上下文中所有文档的单个存储桶.此上下文由要搜索的索引和文档类型定义,但不受搜索查询‎‎本身的影响.‎ ‎全局聚合器只能作为顶级聚合器放置,因为将全局聚合器嵌入到另一 ...

最新文章

  1. Reading Paper
  2. 深度学习 dns tunnel检测 使用统计特征 全连接网络——精度99.8%
  3. python3 爬取西祠代理IP数据
  4. 【加密U盾】在LINX操作系统中部署KD电子钥匙
  5. 【渝粤题库】陕西师范大学400011 思想政治教育学科教学论 作业(专升本)
  6. AGC 022 B - GCD Sequence
  7. python自动化数据报告_如何:使用Python将实时数据自动化到您的网站
  8. 求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加...
  9. Get IAT Table
  10. 转载文章:Microsoft 将僵尸网络威胁智能分析程序引入云中以提供近实时数据
  11. [转]VS 2005快捷键
  12. Lumerical官方案例、FDTD时域有限差分法仿真学习(五)——液晶(liquid crystal)
  13. 美化牙齿的几大方式,护牙剂省钱省力
  14. 计算机动画制作 课件,第四章 计算机动画的制作与编辑-课件(PPT).ppt
  15. 旧时王谢堂前燕,飞入寻常百姓家
  16. echarts 世界地图 地图不渲染问题
  17. 首届西瓜PLAY视频嘉年华狂欢来袭,万张门票几近售罄
  18. VMware虚拟机/Hyper-V在(校园网/PPPoe拨号上网)环境无法上网解决方案
  19. 程序员如何提一个好问题?
  20. 使用RGB-D摄像机的机器人目标跟踪和避障控制设计

热门文章

  1. 新天龙八部内测服务器维护,《新天龙八部》2月8日全服更新维护公告
  2. JAVA核心,200例,查缺补漏
  3. Golang源码学习(二)----Go源码学习基础
  4. maven基础01环境环境搭建及配置部署
  5. 查看各种软件的版本号
  6. node.js220604_day03
  7. postfix mysql冲突_postfix常用错误解决方案
  8. html字两边的横线_css如何在文字两边加上横线的效果?
  9. 必读!未来月薪10万的五大利器(三)
  10. 如何将图片中文字转为WORD文档可编辑