基于SpringBoot和Echarts的全国地震可视化分析实战
目录
前言
一、后台数据服务设计
1、数据库查询
2、模型层对象设计
3、业务层和控制层设计
二、Echarts前端配置
1、地图的展示
2、次数排名统计
三、最终结果展示
1、地图展示
2、图表展示
总结
前言
在之前的博客中基于SpringBoot和PotsGIS的各省地震震发可视化分析,在这篇博客中采用二维地图的展现形式对全国各省的地震震发情况进行了综合展示。博客发布之后,有小伙伴找到博主说,对于Leaflet等地图可视化框架不熟悉,能不能使用echarts进行替代方案开发。同时在地图分析的同时,能否加上一些统计图表,让数据更加直观。在此基础上,就有了本文编写的初衷。
本文主要面向对于Leaflet等gis可视化框架不熟悉的朋友,在不使用gis可视化框架的同时进行地图应用的开发。本文将重点讲解如何使用SpringBoot进行后端接口的开发,基于后端java语言,直接构造前端echarts图表展示需要的数据。文章的最后,我们会输出一个使用Echarts开发的全国各省地震震发情况统计图、全国地震次数排名前10名和倒数10名(相对安全)的省份以及完整的统计数据列表。虽然在之前的博客中也对echarts组件进行了一些介绍,温故而知新,这里不仅回顾了一些地图开发的基础知识,同时结合地震各省份分布统计的需求场景更加有助朋友们理解。
一、后台数据服务设计
后台数据主要用于为前端提供数据来源,将各省份的地震震发数据从数据库中查询出来,然后以json的形式为前端提供。闲言少叙,下面直接进行正式的代码编写。基础采用的技术框架都是熟悉的框架,在之前的博客中也对开发框架进行了介绍,不再赘述。
1、数据库查询
为了能实现全国各个省份数据和地震信息进行关联查询,同时根据省份编码进行分组查询。这里涉及的表有两张。第一张是biz_province(全国省份行政区划信息表),另一张表是我们之前采集的biz_earthquake_info(地震信息表)。通过空间计算,将地震信息表中的位置和省份表进行包含计算,将地震信息包含在省份面中纳入所属省份口径。

图 1 省份信息表

图2 地震信息表
我们使用一下语句进行空间计算和分组统计计算:
select p.code data_id,max(p.name) data_name,count(1) data_value from biz_province p,biz_earthquake_info t where st_contains(p.geom, ST_GeomFromText(format('point(%s %s)',t.eq_lng,t.eq_lat),4326))group by p.code order by data_value desc;
将以上的sql语句在数据库中执行以后可以得到一下结果:

2、模型层对象设计
模型层对象主要包括统计的视图对象即VO,还有业务层对象,比如数据访问层对象和业务对象。数据访问层对象将数据库中查询的结果写入到视图对象中。首先来看一下视图对象的定义,为了方便在echarts中进行展示,我们将展示的值分成统计指标、唯一id、统计指标值。对应的视图对象如下,这个类其实是通用的,一般的统计值都可以用这个视图对象来接收值:
package com.yelang.project.extend.earthquake.domain;
import java.io.Serializable;
import java.math.BigDecimal;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class EarthQuakeProvinceStatVO implements Serializable{private static final long serialVersionUID = 5394617081879927259L;private String dataId;private String dataName;private BigDecimal dataValue;
}
定义好了视图对象之后,我们还需要将数据库的sql语句在代码中执行,在数据访问层中执行以下代码完成数据访问。从性能的角度考虑,我们可以把这个查询结果进行缓存,在下一次数据展示的时候可以提高访问速度,这里为了减少不必要的代码,咱不提供实现。
static final String FIND_EARTH_QUAKE_LIST = "<script>"+ "select p.code data_id,max(p.name) data_name,count(1) data_value from biz_province p,biz_earthquake_info t where "+ " st_contains(p.geom, ST_GeomFromText(format('point(%s %s)',t.eq_lng,t.eq_lat),4326)) "+ " group by p.code order by data_value desc "+ "</script>";/*** 全国各省地震震发统计* @return*/@Select(FIND_EARTH_QUAKE_LIST)List<EarthQuakeProvinceStatVO> findEarthQuakeStatList();
3、业务层和控制层设计
相对而言,这里将重点介绍业务层的设计。我们将在后台采用com.github.abel533.echarts组件直接生成前端所需要的echarts数据。两个省份地震次数排名柱状统计图几乎是一致的。在这里将生成图表数据的方法统一封装出来,根据不同的数据源传入来生成。关键代码如下:
public String convert2ProvinceLine(List<EarthQuakeProvinceStatVO> dataList) {String result = "";GsonOption option = new GsonOption();option.title().text("各省地震震发次数统计图(单位:次)");option.tooltip().trigger(Trigger.axis);option.legend("地震次数");option.legend().y(Y.bottom).padding(0);option.toolbox().show(true).feature(new MagicType(Magic.line, Magic.bar).show(true), Tool.saveAsImage);option.calculable(true);List<String> provinces = new ArrayList<String>();List<Integer> eqCounts = new ArrayList<Integer>();for (EarthQuakeProvinceStatVO vo : dataList) {provinces.add(vo.getDataName());eqCounts.add(vo.getDataValue().intValue());}CategoryAxis categoreAxis = new CategoryAxis();categoreAxis.data(provinces.toArray()).axisLabel().interval(0).rotate(20);option.xAxis(categoreAxis);option.yAxis(new ValueAxis());Bar bar = new Bar("地震次数");bar.data(eqCounts.toArray());bar.markPoint().data(new PointData().type(MarkType.max).name("最大值"), new PointData().type(MarkType.min).name("最小值"));bar.markLine().data(new PointData().type(MarkType.average).name("平均值"));option.series(bar);result = option.toString();return result;}
两个生成前top10,和倒数top10的ehcarts数据方法如下:
@Override
public String buildProvinceLineMaxTop10(List<EarthQuakeProvinceStatVO> dataList) {List<EarthQuakeProvinceStatVO> top10 = new ArrayList<EarthQuakeProvinceStatVO>(10);for(int i =0;i<10;i++) {top10.add(dataList.get(i));}return convert2ProvinceLine(top10);
}@Override
public String buildProvinceLineMinTop10(List<EarthQuakeProvinceStatVO> dataList) {List<EarthQuakeProvinceStatVO> top10 = new ArrayList<EarthQuakeProvinceStatVO>(10);for(int i = dataList.size() - 1;i> dataList.size() - 11;i--) {top10.add(dataList.get(i));}return convert2ProvinceLine(top10);
}
二、Echarts前端配置
完事具备,只欠东风。在后端将相应的数据和接口都准备妥当之后,我们来进行前端的界面开发。对echarts进行初始化。在地图开发过程当中有一些需要注意的地方,一定需要注意。
1、地图的展示
地图的展示,这里采用echarts的map组件,因为在组件采用的时候已经默认注册了china这个图源。因此我们可以直接使用,而无需再次注入。首先需要定义map的挂载组件。
<div id="tab-1" class="tab-pane active"><div class="panel-body"><div class="row"><div class="col-sm-12"><div class="ibox float-e-margins"><div class="ibox-content"><div style="height:600px" id="echarts-map-chart"></div></div></div></div></div></div></div>
地图的展示元素设置好之后,需要采用javascript的方式对数据进行设置。下面是关键代码:
mapChart = echarts.init(document.getElementById("echarts-map-chart"));mapoption = {title : {text: '全国各省地震次数统计',subtext: '数源来源中国国家地震局,单位:次',x:'left'},tooltip : {trigger: 'item'},legend: {orient: 'vertical',x:'right',y:'center',data:['地震次数']},dataRange: {min: 0,max: 2300,x: 'left',y: 'bottom',text:['高','低'], // 文本,默认为数值文本calculable : true},toolbox: {show: true,orient : 'vertical',x: 'right',y: 'bottom',feature : {mark : {show: true},dataView : {show: true, readOnly: false},restore : {show: true},saveAsImage : {show: true}}},roamController: {show: true,x: 'right',mapTypeControl: {'china': true}},series : [{name: '地震次数',type: 'map',mapType: 'china',roam: false,zoom:1.2,//视觉比例大小,1.2即为原有大小的1.2倍itemStyle:{normal:{label:{show:true}},emphasis:{label:{show:true}}},data:[]}]};initProvinceMap();//地图初始化
下面是地图初始化的核心逻辑,这里采用ajax的方式进行数据加载,先给出核心代码:
function initProvinceMap(){$.ajax({url: ctx + "eq/province/echartslist",data: {},dataType : "json",success: function(serverdata){if(serverdata != ""){var serverJsonData = serverdata.data;var jsonData = new Array();for(var i=0;i<serverJsonData.length;i++){var pname = serverJsonData[i].dataName;if(pname.indexOf("黑龙江") != -1 || pname.indexOf("内蒙古") != -1){pname = pname.substring(0,3);}else{pname = pname.substring(0,2);}jsonData.push({name: pname,value: serverJsonData[i].dataValue});}mapoption.series[0].data=jsonData;mapChart.setOption(mapoption,true);$(window).resize(mapChart.resize);charts.push(mapChart);}},error:function(data){parent.layer.alert('系统发生错误!', {icon: 5});}});}
这里需要注意地方是,echarts中的各省份名称是不太准确的,比如新疆维吾尔族自治区,湖南省,北京市等等。省级行政区域名称只取了前两位,而黑龙江和内蒙古则是取了前3位。这里采用的方式是采用前端数据构造的方法,将后端的数据按照echarts的规范来准换。因此在上述代码中,对于黑龙江等省份截取前3位。其它省份或者直辖市自治区采用截取前2位的方式。
2、次数排名统计
次数排名统计,我们设计了两个柱状统计图,分别从次数最多和最少分别取前10进行数据展示。为了完整显示全国各省份的主要信息,我们也提供完整的数据表格清单。柱状统计图的关键代码如下:
provinceLineChart = echarts.init(document.getElementById("echarts-province-chart"));
minprovinceChart = echarts.init(document.getElementById("echarts-minprovince-chart"));
$(window).resize(provinceLineChart.resize);
$(window).resize(minprovinceChart.resize);
charts.push(provinceLineChart);
charts.push(minprovinceChart);
initProvinceChart();
同样图表的数据初始化采用ajax的方式调用,关键代码如下:
function initProvinceChart(){$.ajax({type: "POST",url: ctx + "eq/province/echarts/provinceline",data: {},dataType : "json",success: function(serverdata){if(serverdata != ""){var serverJsonData = eval('('+serverdata.maxdata+')');provinceLineChart.setOption(serverJsonData,true);$(window).resize(provinceLineChart.resize);var minData = eval('('+serverdata.mindata+')');minprovinceChart.setOption(minData,true);$(window).resize(minprovinceChart.resize);}},error:function(data){parent.layer.alert('系统发生错误!', {icon: 5});}});}
三、最终结果展示
经过前后端功能的设计和开发,在完成上述代码的开发之后,我们来看一下实际的效果。看看全国各省的地震震发情况究竟是怎么样的。
1、地图展示

通过echarts图表可以很清楚的看到,在我国的西北和西南,地震的震发次数是非常多,地壳活动也是非常的活跃,新疆维吾尔族自治区,从次数来看一骑绝尘,新疆的地震次数还是非常多的(从公开数据来看)都变成红色的。 具体的数据可以使用鼠标悬浮到对应省份上会悬浮提示地震的次数,如下图所示:

2、图表展示
图表展示将根据地震的震发次数,将次数最多的top10和最少的top10进行展示。方便大家对全国的相关数据有一个直观的掌握。首先来看一下地震次数最多的前10名是哪几个省份。

地震次数最多的前10名依次是:新疆维吾尔自治区、四川省、西藏自治区、云南省、青海省、河北省、台湾省、内蒙古自治区、辽宁省。看完次数最多前10的,再来看安全系数最高的那几个省。

按照次数分别是上海市、海南省、江西省、湖南省、福建省、天津市、北京市、河南省、山东省、江苏省。 其它没有进入统计图的省份具体次数如下:

总结
以上就是本文的主要内容,本文主要面向对于Leaflet等gis可视化框架不熟悉的朋友,在不使用gis可视化框架的同时进行地图应用的开发。本文将重点讲解如何使用SpringBoot进行后端接口的开发,基于后端java语言,直接构造前端echarts图表展示需要的数据。文章的最后,我们会输出一个使用Echarts开发的全国各省地震震发情况统计图、全国地震次数排名前10名和倒数10名(相对安全)的省份以及完整的统计数据列表。行文仓促,难免有诸多不足之处,欢迎朋友们在评论区批评指正,万分感谢。
相关文章:
基于SpringBoot和Echarts的全国地震可视化分析实战
目录 前言 一、后台数据服务设计 1、数据库查询 2、模型层对象设计 3、业务层和控制层设计 二、Echarts前端配置 1、地图的展示 2、次数排名统计 三、最终结果展示 1、地图展示 2、图表展示 总结 前言 在之前的博客中基于SpringBoot和PotsGIS的各省地震震发可视化分…...
基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的农作物害虫检测系统(深度学习模型+UI界面+训练数据集)
摘要:开发农作物害虫检测系统对于提高农业生产效率和作物产量具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个农作物害虫检测系统,并提供了完整的实现代码。该系统基于强大的YOLOv8算法,并对比了YOLOv7、YOLOv6、YOLOv5࿰…...
21 # 高级类型:条件类型
条件类型(Conditional Types)是一种高级的类型工具,它允许我们基于一个类型关系来选择另一个类型。条件类型通常使用条件表达式 T extends U ? X : Y 的形式,其中根据泛型类型 T 是否可以赋值给类型 U 来确定最终的类型是 X 还是…...
Java之List.steam().sorted(Comparator.comparing())排序异常解决方案
使用steam().sorted(Comparator.comparing())对List<T>集合里的String类型字段进行倒序排序,发现倒序失效。记录解决方案。 异常代码如下: customerVOList customerVOList.stream().sorted(Comparator.comparing(CustomerVOVO::getCustomerRate).reversed()…...
js判断对象是否有某个属性
前端判断后端接口是否返回某个字段的时候 <script>var obj { name: "John", age: 30 };console.log(obj.hasOwnProperty("name")); // 输出 trueconsole.log(obj.hasOwnProperty("email")); // 输出 falselet obj11 { name: "Joh…...
CleanMyMac X2024永久免费的强大的Mac清理工具
作为产品功能介绍专员,很高兴向您详细介绍CleanMyMac X这款强大的Mac清理工具。CleanMyMac X具有广泛的清理能力,支持多种文件类型的清理,让您的Mac始终保持最佳状态。 系统垃圾 CleanMyMac X能够深入系统内部,智能识别并清理各种…...
等保测评的知识
结合自己所学的知识和网络上的一些知识做个小总结。 目录 一、概念: 二、等级划分: 三、技术要求: 四、管理要求: 五、等保测评实施过程: 六、典型的网络架构: 一、概念: 全称为信息安全等级保…...
【算法】多路归并(鱼塘钓鱼)
有 N 个鱼塘排成一排,每个鱼塘中有一定数量的鱼,例如:N5 时,如下表: 鱼塘编号12345第1分钟能钓到的鱼的数量(1..1000)101420169每钓鱼1分钟钓鱼数的减少量(1..100)24653当前鱼塘到下…...
unity3d Animal Controller的Animal组件中General基础部分理解
控制器介绍 动物脚本负责控制动物的所有运动逻辑.它管理所有的动画师和刚体参数,以及所有的状态和模式,动物可以做。 动物控制器 是一个动画框架控制器,根动或到位,为任何生物或人形。它利用刚体与物理世界的互动和动画师的玩动画。 States States 是不互相重叠的动画。例如…...
css背景从上到下颜色渐变、css背景从左到右颜色渐变、 css框线展示外阴影、css框线展示内阴影
1. css背景从上到下颜色渐变 body {background: linear-gradient(to bottom, #ff0000, #ffff00); /* 这里的#ff0000表示红色,#ffff00表示黄色 */ }2. css背景从左到右颜色渐变 要实现CSS背景从左到右的颜色渐变,可以使用linear-gradient函数。以下是一…...
Nacos学习笔记
Nacos官网 https://github.com/alibaba/nacos/releases https://www.bilibili.com/video/BV1q3411Z79z 1. Nacos介绍 Nacos是Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 在这个…...
微信小程序 nodejs+vue+uninapp学生在线选课作业管理系统
基于微信小程序的班级作业管理助手使用的是MySQL数据库,nodejs语言和IDEA以及微信开发者工具作为开发工具,这些技术和工具我在日常的作业中都经常的使用,并且因为对编程感兴趣,在闲暇时间也进行的进行编程的提高,所以在…...
trpc-go 博客系统
trpc-go 博客系统 使用go语言构建的全栈项目,充分利用了go的简洁性、高性能和并发处理能力。 系统采用了trpc-go框架和北极星进行分布式开发,展示了如何基于腾讯开源技术栈构建微服务架构,实现高效的服务通信和管理。 https://github.com/…...
【JAVA】Servlet开发
目录 HttpServlet HttpServletRequest HttpServletResponse 错误页面 设置网页自动刷新时间 构造重定向相应 js发起http请求 服务器端对js发起的http请求进行处理 前端获取后端数据,添加到当前页面的末尾,代码示例: 前后端交互&…...
k8s helm 删除 tiller
kuberneter 上面装了 helm 想卸载还并不是那么简单, 参考 stackoverflow 回复 kubectl get -n kube-system secrets,sa,clusterrolebinding -o name|grep tiller|xargs kubectl -n kube-system delete kubectl get all -n kube-system -l apphelm -o name|xargs kubectl dele…...
Python入门(小白友好)
知识图谱 搭建环境 安装Python:Download Python | Python.org 安装PyCharm:Download PyCharm: The Python IDE for data science and web development by JetBrains 注意:专业版本是收费的,新手小白使用社区版(community)即可 创建第一个项目: 一些PyCharm的设置(也适用…...
【数据结构与算法】:非递归实现快速排序、归并排序
🔥个人主页: Quitecoder 🔥专栏:数据结构与算法 上篇文章我们详细讲解了递归版本的快速排序,本篇我们来探究非递归实现快速排序和归并排序 目录 1.非递归实现快速排序1.1 提取单趟排序1.2 用栈实现的具体思路1.3 代码…...
2024-3-18-C++day6作业
1>思维导图 2>试编程 要求: 封装一个动物的基类,类中有私有成员:姓名,颜色,指针成员年纪 再封装一个狗这样类,共有继承于动物类,自己拓展的私有成员有:指针成员:腿的个数&a…...
【OceanBase诊断调优】—— 敏捷诊断工具obdiag一键分析OB集群日志设计与实践
最近总结一些诊断OCeanBase的一些经验,出一个【OceanBase诊断调优】专题,也欢迎大家贡献自己的诊断OceanBase的方法。 1. 前言 obdiag定位为OceanBase敏捷诊断工具。1.2版本的obdiag支持诊断信息的一键收集,光有收集信息的能力,…...
python 调用redis创建查询key
部署redis apiVersion: apps/v1 # 描述api版本,默认都用这个 kind: Deployment # 资源类型,可以配置为pod,deployment,service,statefulset等等 metadata: # deployment相关的元数据,用于描述deployment的…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
