基于Leaflet Legend的图例数据筛选实践-以某市教培时空分布为例

news2024/11/24 12:05:44

目录

前言

一、关于Leaflet.Legend组件

1、Legend组件的主要参数

2、相关参数

二、Legend图例可视化控制

1、违规教培信息的管理

2、违规培训信息时空可视化及图例渲染控制 

 3、成果展示

三、总结


前言

        在很多的地理时空分析系统中,我们经常会遇到一些需求。比如在地图中,我们会结合内容的分类来进行图例的展示,而图例不仅承担着区分的作用,同时还可能承担着展示不同数据的重要作用。比如在Echarts这类的图形报表效果展示中,我们在图表上要展示相应的数据,在图形的左边还展示了一些图例,通过这些图例,我们可以选择进行数据的展示与隐藏。通过使用鼠标的点击来进行不同状态的切换。当然,在Echarts当中,已经有现成的解决方案,我们可以直接使用组件提供的功能即可。

        与这种图表的应用很相似,在地理信息系统建设过程当中,也会有许多的图表和图例生成。以我们常见的Leaflet渲染框架为例,它的图例控件需要自己去定义。 我们在之前的博文中,也介绍了一款基于Leaflet的Leaflet Legend的图例组件。但是没有讲解如何在这款图例生成软件中来进行图例的切换和数据的隐藏与控制。

        本文即在这样的背景下诞生。本文以Leaflet Legend为例,结合之前采集的某市校外违规培训的时空数据,首先讲解如何进行数据的空间可视化,然后讲解Leaflet.Legend这款组件的具体应用,最后将数据和组件进行融合,讲解如何实现在图例上进行切换实现空间数据的切换与隐藏。如果您对基于图例的时空可视化渲染有兴趣,不妨来本文看看。

一、关于Leaflet.Legend组件

        在正式介绍本文的主要内容之前,请允许在这里花一点时间将Leaflet.Legend这个组件来简单进行介绍,对这个组件熟悉的朋友就当做加深了解。如果对Legend图例组件不是很熟悉的朋友刚好可以利用这个机会来深入认识一下。本节从两个方面来进行介绍,第一个方面是关于Legend这个组件的主要参数;另一个方面则简要介绍Legend的主要方法和实现。

1、Legend组件的主要参数

        Leaflet.Legend 是一个 Leaflet 插件, 用于显示图例符号和切换相应的叠加层的显示。对Legend的源码感兴趣的同学可以在Github或者Git上找到它的源代码,Leaflet.Legend。

        大家可以把源代码clone下来,插件比较小,很简单。里面的代码相信大家都能很轻松的看懂。 同时这款插件采用的开源协议是MIT的,因此您可以免费的放心使用。

2、相关参数

        为了更详细的介绍和展示这款组件的功能,下面对Legend组件的相关参数来进行简单介绍,方便大家在使用时对它的属性有一个比较全面的了解。

选项类型默认值描述
positionString'topleft'图例控件位置。
titleString'Legend'图例控件的标题。
opacityNumber1.0图例面板的透明度。
legendsLegendSymbol[][]LegendSymbol 图例符号数组。
symbolWidthNumber24图例符号的宽度,以像素为单位。
symbolHeightNumber24图例符号的高度,以像素为单位。
columnNumber1图例符号排列的列数。
collapsedBooleanfalse图例面板是否默认展开。

        关于上面的属性定义,大家也可以在clone下来的原始代码中找到,在src/leaflet.legend.js这个文件当中的第199行,代码如下所示:

L.Control.Legend = L.Control.extend({
        options: {
            position: "topleft",
            title: "Legend",
            legends: [],
            symbolWidth: 24,
            symbolHeight: 24,
            opacity: 1.0,
            column: 1,
            collapsed: false,
        },
        xxx
}

        既然是图例,肯定最重要还得是图例组件的属性介绍,也就是上面的表格中的LegendSymbol,我们来看下LegendSymbol的具体属性:

选项类型默认值描述
labelStringundefined图例符号的文本标签。
typeStringundefined图例符号的类型. 可以是 'image','circle','rectangle','polygon' 或 'polyline'。
urlStringundefined图里图片的 URL,仅用于 type 为 'image' 时。
radiusNumberundefined圆形图例的半径,以像素为单位,仅用于 type 为 'circle' 时。
sidesNumberundefined正多边形的边数,仅用于 type 为 'polygon' 时。
layersLayer|Layer[]undefined图例符号关联的叠加层. 关联叠加层后可通过点击图例来切换相应叠加层的可见性。
inactiveBooleanundefined图例符号是否为非激活的, 非激活的图例会减淡显示。
strokeBooleantrue是否绘制边框。
colorString'#3388ff'边框颜色。
weightNumber3边框宽度。
opacityNumber1.0边框透明度。
lineCapString'round'指定如何绘制每一条线段末端的属性。有 3 个可能的值,分别是:'butt','round' 或 ’square‘。
lineJoinString'round'用来设置2个长度不为0的相连部分(线段,圆弧,曲线)如何连接在一起的属性(长度为0的变形部分,其指定的末端和控制点在同一位置,会被忽略)。
dashArrayStringnull控制用来描边的点划线的图案范式。
dashOffsetStringnulldash模式到路径开始的距离。
fillBooleandepends是否用颜色填充。
fillColorString*填充色,默认与边框颜色相同
fillOpacityNumber0.2填充透明度。
fillRuleString'evenodd'填充规则。

        这里,有一个参数非常重要,就是Layers这个参数,这个参数就是实现我们今天核心主题的钥匙。要想实现图例的切换,就是依靠上面的Layers这个图层参数。同时注意查看这个Layers这个属性,它的值可以是一个对象也可以是一个数组,比如多个点对象集合。通过Leaflet.Legend.js源码可以看到一些它的初始化状态和属性信息:

 _style() {
            var ctx = (this._ctx = this._canvas.getContext("2d"));
            if (this._legend.fill || this._legend.fillColor) {
                ctx.globalAlpha = this._legend.fillOpacity || 1;
                ctx.fillStyle = this._legend.fillColor || this._legend.color;
                ctx.fill(this._legend.fillRule || "evenodd");
            }

            if (this._legend.stroke || this._legend.color) {
                if (this._legend.dashArray) {
                    ctx.setLineDash(this._legend.dashArray || []);
                }
                ctx.globalAlpha = this._legend.opacity || 1.0;
                ctx.lineWidth = this._legend.weight || 2;
                ctx.strokeStyle = this._legend.color || "#3388ff";
                ctx.lineCap = this._legend.lineCap || "round";
                ctx.lineJoin = this._legend.lineJoin || "round";
                ctx.stroke();
            }
        }

        在介绍了上面的API信息之后,我们来看一下具体如何实现基于Legend的图例可视化开关。

二、Legend图例可视化控制

        本节将重点介绍在Legend中如何进行图例的切换与数据绑定,在图例生成和绑定过程中可能会遇到一些问题,也会介绍如何介绍这些问题,最终实现可以点击图例来进行相应数据的显示与隐藏。由于会涉及之前的违规教培信息的可视化展示,因此如果对违规教培的数据和采集不熟悉的,可以翻阅博主早些时候的一些博客。里面有相关信息的叙述,闲言少语,我们直接加进入正题。

1、违规教培信息的管理

        作为数据可视化的核心,违规教培信息的管理尤其重要。违规教培信息在这里包含两个方面的信息,第一个方面是基本信息,比如机构的信息、机构的地址、违规培训的类型、发布的日期、信息的来源等,另一方面就是空间信息,比如这个机构信息是在长沙而不是上海。这属于空间坐标位置信息。同样是重要的,因此我们可以进行统一的登记管理。这里仅展示管理的功能界面,大多数的功能界面都是增删改查,因此没有过多的叙述。

        上图仅展示了违规教培信息的列表信息,系统支持新增单条信息,也支持编辑单条培训信息,可以进行新处罚机构的信息录入,也可以进行信息的调整。 

2、违规培训信息时空可视化及图例渲染控制 

        在上面的违规培训信息管理中,我们已经实现了基本信息的管理,本小节中将进行赋予了经纬度信息的违规培训机构信息时空可视化展示。同时基于Legend的图例控制器来进行不同违规类型的切换与隐藏展示。当然,如果不想在图例上进行数据的安全过滤,也可以考虑做到全局的数据过滤中,直接在sql中加入where条件即可。

        要想实现基于Legend的图例数据切换,结合在最前面介绍的API接口,我们来梳理一下如何进行实现(至于其他的比如底图的加载与初始化,由于在之前的博客中已经讲解了很多,这里不再进行赘述)。第一步、根据之前的基本数据,违规培训的类型可以分为:隐形变异学科培训、无证非学科类培训、有证机构违规办学这三种,因此我们需要在地图上初始化这三类图例。同时,为了能将图例和数据进行一一对应,我们定义三个数组,在请求后台的数据时,根据不同的数据类型来进行赋值,最后将图例添加到地图组件中,就圆满的完成了图例的可视化。

        首先我们定义三个空的数组,用来接收三类违规培训的类型,代码如下:

var training1 = new Array();//隐形变异学科培训
var training2 = new Array();//无证非学科类培训
var training3 = new Array();//有证机构违规办学

        然后,获取所有的违规培训信息,根据三类违规培训类型,对上面的三个数组进行赋值。

function showViolationTraining(){
     $.ajax({  
		  type:"get",  
		  url:prefix + "/globallist",  
		  dataType:"json",  
		  cache:false,
		  processData:false,
		  success:function(result){
		       if(result.code == web_status.SUCCESS){
		        	var strokeStyleSet = "#c50808";
		        	var lat,lng,cityInfo;
		        	for(var i=0;i < result.data.length;i++){
		        		var dataInfo = result.data[i];
		        		if(dataInfo.geomJson != null){
		        			var geomObj = JSON.parse(dataInfo.geomJson);
			        		var radiusSize = 6;
			        		switch(dataInfo.type) {
				        		case '无证非学科类培训':  
				        		    strokeStyleSet = "#168d40";
				        		    break;
				        		case '有证机构违规办学':  
				        		    strokeStyleSet = "#2196f3";
				        		    break;
				        		default:
				        		    strokeStyleSet = "#c50808";
				        	}
		    				var content = "<strong>机构名称:</strong>"+dataInfo.name + "<br/><strong>地址:</strong>"+dataInfo.address;
		    				content += "<br/><strong>发布时间:</strong>"+dataInfo.publishDate + "<br/><strong>类型:</strong>"+dataInfo.type;
			    			var latlng = new L.latLng(geomObj.coordinates[1], geomObj.coordinates[0]);
			    			let marker = L.circleMarker(latlng, {
			        		     radius: radiusSize,
			        		    color: strokeStyleSet,//这里设置的是circleMarker的颜色属性
			        		    labelStyle: {
			        		       offsetX: 0, //横坐标偏移(像素)
			        		       offsetY: 30, //纵坐标偏移(像素)
			        		       text: dataInfo.name,
			        		       rotation: 0,
			        		       zIndex: radiusSize,
			        			   minZoom : 2,
			        		      fillStyle: strokeStyleSet
			        		     }
		        		     }).addTo(showLayerGroup);
		        		     switch(dataInfo.type) {
				        		    case '无证非学科类培训':  
				        		    	training2.push(marker);
				        		        break;
				        		    case '有证机构违规办学':  
				        		    	training3.push(marker);
				        		        break;
				        		    default:
		        		      			training1.push(marker);
				        		}
			    				marker.bindPopup(content); 
		        			}
		        		}
		        		mymap.addLayer(showLayerGroup);
		        	}
		        },
		        error:function(){
		        	$.modal.alertWarning("获取信息失败");
		        }
		    });
        }

        最后,将图例和数据进行绑定,关键代码如下:

function initLegend(){
	 const legend = L.control.Legend({
	      position: "bottomright",
	      collapsed: false,
	      symbolWidth: 35,
	      opacity: 1,
		  title:"图例",
	      column: 1,
	      legends: [ {
	          label: "\xa0\xa0 隐形变异学科培训",//一定要注意这里的转义字符
	          type: "rectangle",
	          color: "#c50808",
	          fillColor: "#c50808",
	          weight: 2,
	          layers: training1,
	          inactive: false
	       }, {
	          label: "\xa0\xa0 无证非学科类培训",
	          type: "rectangle",
	          color: "#168d40",
	          fillColor: "#168d40",
	          weight: 2,
	          layers: training2,
	          inactive: false
	        }, {
	          label: "\xa0\xa0 有证机构违规办学",
	          type: "rectangle",
	          color: "#2196f3",
	          fillColor: "#2196f3",
	          weight: 2,
	          layers: training3,
	          inactive: false
	          }]
	     }).addTo(mymap);
	}

        在上面的代码中,在设置图例的时候,legends对象数组中的每个一个layers将不同的违规培训类型进行绑定,从而实现点击图例,切换不同的违规培训数据。在本例中,请求后台的所有违规培训信息列表接口返回的数据如下:

        单个培训单位信息内容如下:

address: "湘江新区奥克斯中央公馆9栋308房"
geom: "0101000020E6100000A2B437F8C23C5C40FB3A70CE883A3C40"
geomJson: "{\"type\":\"Point\",\"coordinates\":[112.9494,28.22865]}"
id: "1827241962588106753"
lat: "28.22865"
lon: "112.9494"
name: "唐*"
params: {}
publishDate: "2024-08-07"
remark: ""
source: "长沙晚报"
type: "隐形变异学科培训"

 3、成果展示

        下面将重点对图例切换的时空可视化结果进行展示。主题功能分左边和右边两块,左边展示违规培训信息列表,右边展示地图信息。左边的违规培训机构信息展示,支持按照机构名称进行模糊搜索,而右边的地图默认显示整个长沙市的违规教育培训信息。

        图例窗口默认展示在界面右下角,在地图主界面默认将所有类型的培训机构信息展示齐全。

点击图例中的隐形变异学科培训”,将隐藏所有的隐形变异学科培训培训机构。效果如下所示:

        同样的操作,可以一次进行剩下的“无证非学科类培训”和“有证机构违规办学”这两种培训的切换和隐藏。

         当某一类型的违规培训机构被取消选中后,其颜色会变灰。跟Echarts的效果几乎是一模一样的。这样就满足了我们的实际需求。

三、总结

        以上就是本文的主要内容,本文以Leaflet Legend为例,结合之前采集的某市校外违规培训的时空数据,首先讲解如何进行数据的空间可视化,然后讲解Leaflet.Legend这款组件的具体应用,最后将数据和组件进行融合,讲解如何实现在图例上进行切换实现空间数据的切换与隐藏。如果您对基于图例的时空可视化渲染有兴趣,不妨来本文看看。行文仓促,定有许多不足之处,在此恳请各位专家博主和读者不吝赐教,在评论区留下宝贵的意见,不胜感激。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2087100.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

运维-3.分库分表

分库分表 1.介绍2.Mycat概述3.Mycat入门4.Mycat配置4.1 schema.xml4.1.1 schema标签4.1.2 dataNode标签4.1.3 dataHost标签 4.2 rule.xml4.3 server.xml4.3.1 system标签4.3.2 user标签 5.Mycat分片5.1 垂直拆分5.2 水平拆分5.3 分片规则5.3.1 范围分片5.3.2 取模分片5.3.3 一致…

若依微服务Admin控制台不显示ruoyi-file问题解决

本地启动完若依微服务,发现Admin控制台只显示了6个服务,其中ruoyi-file启动成功,但是没有在Admin控制台中显示处理,本章问题,给出这个问题的解决办法。 一、什么是服务监控 监视当前系统应用状态、内存、线程、堆栈、日志等等相关信息,主要目的在服务出现问题或者快要出…

机器学习和深度学习·贝叶斯优化和optuna

贝叶斯优化 贝叶斯优化的思想 先验&#xff1a;取点 似然&#xff1a;假设分布 取了n个点之后… 后验&#xff1a;近似取得极值 贝叶斯优化的数学过程 在贝叶斯优化的数学过程当中&#xff0c;我们主要执行以下几个步骤&#xff1a; 1 定义需要估计的 f ( x ) f(x) f(x)以及…

零基础学习Python(七)

1. 字符串常用方法 lower()、upper()&#xff1a;转换为小写字符串、大写字符串 split(str)&#xff1a;按照指定字符串str进行分割&#xff0c;结果为列表&#xff1a; email "123qq.com" print(email.split("")) [123, qq.com] count(str)&#xf…

MySQL 系统库

文章目录 一. 概念二. performance_schema1. 概念 2. 检查当前数据库版本是否支持3. performance_schema表分类5. 配置与使用6. 查看执行失败的SQL语句7. 查看最近事务执行信息8. 小结 三. sys系统库1. 使用须知2. 使用3. 查看慢SQL语句慢在哪4. 小结 四. Information_schema1.…

中国城市经济韧性数据集(2007-2022年)

数据来源&#xff1a;数据来自历年《中国城市统计NJ》、各省市《统计NJ》及《中国区域经济统计NJ》 时间范围&#xff1a;2007-2022年 数据范围&#xff1a;中国地级市样例数据&#xff1a; 包含内容&#xff1a; 全部内容下载链接&#xff08;原始数据计算代码最终数据&…

Spring Boot DevTools:简化开发,实现热部署

Spring Boot DevTools&#xff1a;简化开发&#xff0c;实现热部署 1、如何集成&#xff1f;MavenGradle 2、主要特性3、注意事项 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; Spring Boot DevTools是开发者的得力助手&#xff0c;它通过…

AR 眼镜之-系统通知定制(通知弹窗)-实现方案

目录 &#x1f4c2; 前言 AR 眼镜系统版本 系统通知定制 1. &#x1f531; 技术方案 1.1 技术方案概述 1.2 实现方案 1&#xff09;实现系统通知的监听 2&#xff09;系统通知显示&#xff1a;通知弹窗 2. &#x1f4a0; 实现系统通知的监听 2.1 继承 NotificationLi…

全场景——(六)Moubus 功能码详解

文章目录 一、功能码概要二、&#xff08;0x01&#xff09;读取线圈2.1 功能说明2.2 查询报文2.3 响应报文 三、 (0x02) 读取离散量输入值3.1 功能说明3.2 查询报文3.3 响应报文 三、&#xff08;0x03&#xff09;读取保持寄存器值3.1 功能说明3.2 查询报文3.3 响应报文 五、 (…

LabVIEW项目中硬件选型与长期需求沟通

在LabVIEW项目中&#xff0c;选择合适的硬件和有效的需求沟通是成功的关键。大品牌硬件通常具备更高的稳定性和完善的售后服务&#xff0c;而小品牌虽然看似便宜&#xff0c;却可能带来通讯不稳定、技术支持不足等问题&#xff0c;增加开发难度。同时&#xff0c;在科研类项目中…

光性能 -- OSNR Loss均衡

什么是OSNR&#xff1f; OSNR&#xff08;Optical Signal Noise Ratio &#xff09;即光信噪比。它是指传输链路中的信号光功率与噪声光功率的比值&#xff0c;OSNR计算公式如下所示&#xff1a; OSNR是决定波分系统性能的最主要因素之一。它决定了传输性能的最高值&#xff0c…

ZaKi:Ingonyama的Prover market基础设施

1. 引言 Ingonyama团队预计在不久的将来会出现大量去中心化证明市场&#xff08;Prover market&#xff09;。这些市场的独特之处在于高可用性和高性能的基础设施&#xff0c;以及强大的安全性和透明度保障。 2. 证明市场的出现 零知识 (ZK) Rollups&#xff0c;如 Starknet…

望繁信科技亮相2024数博会:以流程智能引领数字化转型新未来

在全球瞩目的2024中国国际大数据产业博览会&#xff08;以下简称“数博会”&#xff09;上&#xff0c;上海望繁信科技有限公司&#xff08;简称“望繁信科技”&#xff09;作为大数据流程智能领域的领军企业&#xff0c;隆重亮相并展示了其在数字化转型与人工智能领域的最新科…

如何使用WebSafeCompiler进行网站优化和知识产权保护

关于WebSafeCompiler WebSafeCompiler是一款功能强大的Web安全与优化工具&#xff0c;该工具基于Node.js开发&#xff0c;可以帮助广大研究人员编译静态网站以进行优化或知识产权保护。 WebSafeCompiler&#xff08;WSC&#xff09;是一款高级Node.js实用程序&#xff0c;旨在…

Python 处理 PDF 文件(PyPDF2, ReportLab)

Python 是一门强大的编程语言&#xff0c;在处理PDF文件方面有着丰富的库支持&#xff0c;其中最常用的两个库是 PyPDF2 和 ReportLab。PyPDF2 主要用于读取、拆分、合并和修改已有的PDF文件&#xff0c;而 ReportLab 则擅长生成新的PDF文件。 一、PyPDF2 1. PyPDF2 概述 Py…

Mysql剖析(四)----Mysql的行锁、表锁、间隙锁详解

目录 一丶Mysql的锁分类 二丶乐观锁和悲观锁 三丶共享锁和排它锁 四丶表锁页锁和行锁 五丶Mysql锁超时 简介&#xff1a;编程中的锁是一种同步机制&#xff0c;用于控制对共享资源的访问&#xff0c;确保同一时间只有一个线程可以访问共享资源&#xff0c;从而避免竞态条件…

通信协议——Modbus 讲明白了

目 录 Modbus通信协议一、说明1.1 描述1.2 查询1.3 响应 二、异常三、功能码 Modbus通信协议 Modbus由Modicon公司&#xff08;也是现在的施耐德电气&#xff09;于1979年开发&#xff0c;是一种工业现场总线协议标准。最初是为使用PLC&#xff08;可编程逻辑控制器&#xff0…

[激光原理与应用-126]:傅里叶变化与频域分析

目录 一、什么是傅里叶变换 1.1 基本概念 &#xff08;1&#xff09;首先&#xff0c;先看时域图像&#xff1a; &#xff08;2&#xff09;接下来&#xff0c;频域波形 &#xff08;3&#xff09;傅里叶变换 1.2 应用 &#xff08;1&#xff09;离散傅里叶变换在图像处…

Shell脚本格式化打印信息样例

以下是一个基于Centos7安装docker的脚本 logging.sh [rootbogon ~]# cat logging.sh #!/bin/bashNC\033[0m RED\033[31m GREEN\033[32m YELLOW\033[33m BLUE\033[34mlog::err() {printf "[$(date %Y-%m-%dT%H:%M:%S.%2N%z)][${RED}ERROR${NC}] %b\n" "$"…

美团2024年春招第一场笔试【前端移动端方向】编程题题解Java

1、小美的平衡矩阵 前缀和&#xff0c;时间复杂度为O(n^3) 对于每个矩形&#xff0c;已知边长k&#xff0c;只用每次遍历矩形的左上顶点&#xff0c;就可以确定整个矩形范围。然后统计该矩形中01的具体数量&#xff0c;判断是否相等。而这一步可以使用前缀和&#xff0c;建立数…