基于SpringBoot和Leaflet的邻省GDP可视化实战
目录
前言
一、技术实现路径
1、空间数据检索
2、数据展示检索流程
二、SpringBoot后台实现
1、模型层实现
2、控制层实现
三、WebGIS前端实现
1、控制面展示
2、成果展示
四、总结
前言
在数字化浪潮席卷全球的今天,数据已成为驱动社会经济发展、指导政策制定、促进科学研究的关键要素。如何高效收集、处理并直观展现这些数据,成为了各领域面临的重要课题。特别是在经济学领域,GDP(国内生产总值)作为衡量一个国家或地区经济规模和发展水平的核心指标,其数据的可视化不仅能够帮助我们迅速把握经济状况,还能为政策制定者提供有力的决策支持。在此背景下,结合SpringBoot这一轻量级Java开发框架与Leaflet这一开源JavaScript库,开展邻省GDP可视化实战项目,无疑是一次富有意义的技术探索与实践。
将SpringBoot与Leaflet结合,构建邻省GDP可视化系统,旨在通过后端强大的数据处理能力,结合前端直观的地图展示,实现数据的动态更新与交互分析。该系统首先利用SpringBoot搭建后端服务,负责数据的收集、清洗、存储及API接口的提供。考虑到数据的时效性和准确性,后端可能会定期从国家统计局等权威渠道获取最新的GDP数据,并通过RESTful API向前端提供服务。前端则利用Leaflet构建交互式地图界面,将邻省的GDP数据以地图标注、区域填充色等形式直观展现,用户可以通过点击、悬停等操作查看具体省份的GDP信息,甚至进行时间序列对比,从而更深入地理解经济发展趋势和区域差异。
总之,基于SpringBoot和Leaflet的邻省GDP可视化实战项目,不仅是一次技术上的融合创新,更是对经济学数据可视化应用的一次深入探索。通过这一项目,我们不仅能够提升数据处理与分析的能力,还能在实践中加深对经济现象的理解,为推动区域经济的均衡发展贡献科技力量。
一、技术实现路径
SpringBoot,作为Spring家族的一员,以其“约定优于配置”的理念简化了企业级应用的开发流程,使得开发者能够专注于业务逻辑的实现,而非繁琐的配置管理。它提供了丰富的内置功能,如嵌入式服务器、自动配置、健康检查等,极大地提高了开发效率和应用的可靠性。在构建后端服务时,SpringBoot能够轻松实现对数据库的操作、API接口的设计以及与其他服务的集成,为前端提供稳定且高效的数据支持。而Leaflet,作为一款轻量级的开源JavaScript地图库,以其简洁的API、良好的跨浏览器兼容性以及丰富的插件生态,成为了实现地理数据可视化的首选工具。Leaflet不仅支持基本的地图操作(如缩放、平移),还能轻松叠加各种地理数据图层,如图标标记、多边形、热力图等,使得地理信息的展示既直观又富有互动性。更重要的是,Leaflet能够与多种数据源无缝对接,包括GeoJSON、KML等格式,为开发者提供了极大的灵活性。
1、空间数据检索
关于在PostGIS中进行相邻省份的检索实现,在之前的博客中有过介绍:基于PostGIS的省域空间相邻检索实践。对于空间数据表的设计与空间检索有详细的介绍。这里将关键的空间检索实现表示如下:
static final String NEIGHBOR_PROVINCE_BYID = "<script>"
+ " select id,code,name,type,st_asgeojson(geom) geomJson from biz_province where id = #{id} "
+ " union "
+ " select t.id,t.code,t.name,t.type,st_asgeojson(t.geom) geomJson from biz_province s,biz_province t "
+ " where s.id = #{id} and ST_Touches(s.geom,t.geom)"
+ "</script>";
2、数据展示检索流程
首先根据前端传入的省域信息,根据省域ID使用St_touches函数查询相邻的省份,然后在后台的Service层方法中查找对应省份的GDP数据, 为了方便在Leaflet前台页面中进行集中展示,我们需要将省份的属性信息、GDP信息和Geometry空间信息进行融合,返回给前端带有GeoJSON的数据接口,最后调用Leaflet的Polygon绘制函数进行绘制。为了方便数据展示,GDP数据我们采用从互联网获取的公开信息,如下:
以上表格就是我们的基础数据,通过查询得到的省份信息关联GDP可以得到联合的数据后在前端进行展示。
二、SpringBoot后台实现
本节将重点介绍在SpringBoot中如何实现对PostGIS空间数据库的检索以及控制层API的实现。
1、模型层实现
在数据库操作模型层中,需要实现前文提到过的相邻国家查询检索方法,在Mapper中的关键代码如下:
static final String NEIGHBOR_PROVINCE_BYID = "<script>"+ " select id,code,name,type,st_asgeojson(geom) geomJson from biz_province where id = #{id} " + " union "+ " select t.id,t.code,t.name,t.type,st_asgeojson(t.geom) geomJson from biz_province s,biz_province t " + " where s.id = #{id} and ST_Touches(s.geom,t.geom)"+ "</script>";
/**
* - 根据省份主键ID查询邻省列表 add by 夜郎king in 2025-02-02
* @param id 查询省份ID
* @return 该国对应的邻省列表
*/
@Select(NEIGHBOR_PROVINCE_BYID)
List<Province> findNeighborProvinceById(@Param("id")Long id);
为了方便在前台将gdp数据与省份信息进行融合,同时可以实现对象的最大共享,我们基于省份Province对象扩展出一个子类,仅包含一个GDP的属性。
package com.yelang.project.extend.earthquake.domain;
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 ProvinceGdpVO extends Province{private static final long serialVersionUID = 4740578201189215164L;private BigDecimal gdp = new BigDecimal("0");
}
2、控制层实现
控制层为了实现方便,这里没有将各个省份的GDP数据保存到数据库中,仅模拟使用一个Map数据进行保存。从PostGIS数据库中查询到对应的省份信息后,在根据key去hashMap中进行获取。这种计算方法比较快,实际业务中,我们可以将GDP数据缓存到服务器中,因为这种数据基本上都是不变的,这样可以极大的提升程序的性能。
@RequiresPermissions("eq:nearprovince:list")
@GetMapping("/nearprovince/list/{id}")
@ResponseBody
public AjaxResult nearProvinceList(@PathVariable("id") Long id){List<ProvinceGdpVO> provinceGdpList = new ArrayList<ProvinceGdpVO>();List<Province> provinces = provinceService.findNeighborProvinceById(id);Map<String,BigDecimal> gdpMap = provinceService.province2024GdpMap();if(StringUtils.isNotEmpty(provinces)) {for(Province p : provinces) {ProvinceGdpVO gdpVo = new ProvinceGdpVO();BeanUtils.copyBeanProp(gdpVo, p);if(gdpMap.containsKey(gdpVo.getCode())) {gdpVo.setGdp(gdpMap.get(gdpVo.getCode()));}provinceGdpList.add(gdpVo);}}return AjaxResult.success().put("data", provinceGdpList);}
可以在前端来看一下返回的数据格式:
三、WebGIS前端实现
本节将重点展示在Leafelt中如何实现对相邻省份的空间信息以及它的GDP等关键信息的综合展示,关于Leaflet中展示相关信息,在之前的系列博文中均有所提及,故不再赘述。
1、控制面展示
在Leaflet中将循环获取的各个省份的GeoJSON数据信息,然后将GeoJSON数据展示出来。关键代码如下:
function previewGdp(gid,name){$.ajax({ type:"get", url:prefix + "/nearprovince/list/" + gid, data:{}, dataType:"json", cache:false,processData:false,success:function(result){if(result.code == web_status.SUCCESS){showLayerGroup.clearLayers();var legendData = new Array();for(var i = 0;i< result.data.length;i++){var areaData = result.data[i];var color = ccolor = getRandomColor();if(gid == areaData.id){color = "red";}var areaLayer = L.geoJSON(JSON.parse(areaData.geomJson),{style: {color:color,fillColor:color,weight:3,"opacity":0.65, fillOpacity: 0.65 }}).addTo(mymap);var myIcon = L.divIcon({iconSize: null,className: '',popupAnchor:[5,5],shadowAnchor:[5,5],html: buildShowInfo(i,color,areaData)});showLayerGroup.addLayer(areaLayer);//中心点位L.marker(areaLayer.getBounds().getCenter(), { icon: myIcon}).addTo(showLayerGroup);legendData.push({label: "\xa0\xa0"+areaData.name,type: "rectangle",radius: 12,color: color,fillColor: color,fillOpacity: 0.8,weight: 2});}mymap.fitBounds(showLayerGroup.getBounds());//legend.remove();initLegend(legendData);}},error:function(){$.modal.alertWarning("获取空间信息失败");}});}
下面就来看一下2024年全国各个省份及其邻省的GDP信息展示成果。
2、成果展示
首先来看下傲视群雄的广东省,如下图所示:
广东省2024年GDP是141633.81亿元,它的相邻省份分别是:广西壮族自治区、湖南省、江西省、福建省、香港特别行政区和澳门特别行政区。由于香港和澳门的相关数据暂未发布,因此暂时未列入其中。可以看到广西的GDP是28649.40亿元,湖南是53230.99亿元,江西GDP为34202.5亿元,福建GDP为57761.02亿元。广东一个省几乎是人家三个省的和。看了第一名的省份,接下来看一下排名靠中的湖南省,如下图所示:
与湖南省相邻的省份中, 除了前面介绍过的省份外,还有湖北省、重庆市、贵州省。这三个省份中,湖北省的GDP比湖南省的要稍微多一点,为60012.97亿元,重庆市为32193.15亿元,贵州GDP为22667.12亿元。湖南省的GDP相当于重庆市和贵州省GDP之和。最后来看一下青海省的GDP,如下图所示:
青海省2024年的GDP是3950.8亿元,而其相邻省份西藏自治区的GDP为2764.94亿元,新疆维吾尔自治区20534.08亿元,甘肃GDP为13002.9亿元,四川GDP为64697.0亿元 。 从数值上可以看到,青海省的GDP还是比较少的,同比发现四川的GDP是比较高的,在全国的排名中也是可以排到前5的,这非常了不起。四川与前面几个省份(广东、江苏、山东、浙江)不一样的是,四川是位于内陆的省份。
四、总结
以上就是本文的主要内容,本文将SpringBoot与Leaflet结合,构建邻省GDP可视化系统,旨在通过后端强大的数据处理能力,结合前端直观的地图展示,实现数据的动态更新与交互分析。基于SpringBoot和Leaflet的邻省GDP可视化实战项目,不仅是一次技术上的融合创新,更是对经济学数据可视化应用的一次深入探索。通过这一项目,我们不仅能够提升数据处理与分析的能力,还能在实践中加深对经济现象的理解,为推动区域经济的均衡发展贡献科技力量。行文仓促,难免有许多不足之处,如有不足,在此恳请各位专家博主在评论区不吝留言指出,不胜感激。
相关文章:

基于SpringBoot和Leaflet的邻省GDP可视化实战
目录 前言 一、技术实现路径 1、空间数据检索 2、数据展示检索流程 二、SpringBoot后台实现 1、模型层实现 2、控制层实现 三、WebGIS前端实现 1、控制面展示 2、成果展示 四、总结 前言 在数字化浪潮席卷全球的今天,数据已成为驱动社会经济发展、指导政策…...

esp工程报错:something went wrong when trying to build the project esp-idf 一种解决办法
最近上手了正点原子esp32s3板子,环境采用的是vscodeesp-idf插件。导入了正点原子的demo测试,每次都报这个错误无法建造。也不是网上说的ninja error,不是中文路径的问题。 在终端中查看,发现是缺少了git。(我这里没有…...

Grouped-Query Attention(GQA)详解: Pytorch实现
Grouped-Query Attention(GQA)详解 Grouped-Query Attention(GQA) 是 Multi-Query Attention(MQA) 的改进版,它通过在 多个查询头(Query Heads)之间共享 Key 和 Value&am…...
DeepSeek AI人工智能该如何学习?
人工智能(Artificial Intelligence, AI)是当今科技领域的热门话题,它涵盖了机器学习、深度学习、自然语言处理、计算机视觉等多个子领域。 作为中国科技发展的核心方向之一,AI在国家战略规划中占据了重要地位,特别是在…...
【数据库】【MySQL】索引
MySQL中索引的概念 索引(MySQL中也叫做"键(key)")是一种数据结构,用于存储引擎快速定找到记录。 简单来说,它类似于书籍的目录,通过索引可以快速找到对应的数据行,而无需…...
SprinBoot整合HTTP API:从零开始的实战指南
在现代 Web 开发中,HTTP API 是前后端交互的核心。Spring Boot 作为 Java 生态中备受欢迎的框架,提供了简洁而强大的方式来构建和整合 HTTP API。本文将带你从零开始,通过具体代码示例,展示如何在 Spring Boot 中整合 HTTP API,实现高效、稳定的前后端通信。 一、为什么选…...

可狱可囚的爬虫系列课程 13:Requests使用代理IP
一、什么是代理 IP 代理 IP(Proxy IP)是一个充当“中间人”的服务器IP地址,用于代替用户设备(如电脑、手机等)直接与目标网站或服务通信。用户通过代理IP访问互联网时,目标网站看到的是代理服务器的IP地址&…...

DBeaver下载安装及数据库连接(MySQL)
1. DBeaver下载 官网下载地址:Download | DBeaver Community 2. 安装 1. 双击下载的安装包,选择简体中文。 2. 点击下一步。 3. 点击我接受。 4. 如下勾选为所有用户安装,点击下一步。 5. 需重复做1~3 的步骤。 6. 选择组件,默认即可&…...

国产开源PDF解析工具MinerU
前言 PDF的数据解析是一件较困难的事情,几乎所有商家都把PDF转WORD功能做成付费产品。 PDF是基于PostScript子集渲染的,PostScript是一门图灵完备的语言。而WORD需要的渲染,本质上是PDF能力的子集。大模型领域,我们的目标文件格…...
消息中间件的开源实现
根据你的需求,以下是一些可以实现类似阿里巴巴 MetaQ 功能的消息中间件和相关项目,这些项目可以帮助你实现消息的动态配置和管理: 1. RocketMQ RocketMQ 是一个分布式消息中间件,支持高吞吐量、低延迟的消息传递,适合…...
AcWing 299 裁剪序列
这道题算是我做过所有的单调队列优化 d p dp dp 题目中最难想的一道题,所以写篇题解再捋捋思路。 暴力 首先很容易想到设 d p i dp_i dpi 表示将前 i i i 个数划分成若干序列,【每个序列的最大值之和】的最小值。 那么就会有: d p i …...
P2889 [USACO07NOV] Milking Time S
题目大意 有 N N N 个小时可以挤奶。其中有 m m m 个时间段可以给 Bessis 奶牛挤奶。第 i i i 个时间段为 s i s_i si ~ t i t_i ti,可以获得 E f f i Eff_i Effi 滴奶。每次挤完奶后,人都要休息 R R R 小时。最后问,一共能挤出…...

基于Spring Boot的健康医院门诊在线挂号系统设与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...

PyTorch-基础(CUDA、Dataset、transforms、卷积神经网络、VGG16)
PyTorch-基础 环境准备 CUDA Toolkit安装(核显跳过此步骤) CUDA Toolkit是NVIDIA的开发工具,里面提供了各种工具、如编译器、调试器和库 首先通过NVIDIA控制面板查看本机显卡驱动对应的CUDA版本,如何去下载对应版本的Toolkit工…...

复现论文:DPStyler: Dynamic PromptStyler for Source-Free Domain Generalization
论文:[2403.16697] DPStyler: Dynamic PromptStyler for Source-Free Domain Generalization github: TYLfromSEU/DPStyler: DPStyler: Dynamic PromptStyler for Source-Free Domain Generalization 论文: 这篇论文还是在PromptStyler:Prompt-driven Style Gener…...

6.将cr打包成网络服务|使用postman进行测试|编写oj_server的服务路由功能(C++)
将cr打包成网络服务 compile_server.cc #include "compile_run.hpp" #include "../comm/httplib.h"using namespace ns_compile_and_run; using namespace httplib;//编译服务随时可能被多个人请求,必须保证传递上来的code,形成源…...

基于SpringBoot + Vue的共享汽车(单车)管理系统设计与实现+毕业论文+开题报告+指导搭建视频
本系统包含管理员、用户两个角色。 管理员角色:个人中心管理、用户管理、投放地区管理、汽车信息管理、汽车投放管理、汽车入库管理、使用订单管理、汽车归还管理。 用户角色:注册登录、汽车使用下单、汽车归还。 本共享汽车管理系统有管理员和用户。管…...
Day54(补)【AI思考】-SOA,Web服务以及无状态分步解析与示例说明
文章目录 **SOA,Web服务以及无状态**分步解析与示例说明**分步解析与示例说明****1. 核心概念解析****2. 为什么说SOA与Web服务是“正交的”?****3. 架构风格 vs. 实现技术****4. 接口(Interface)的核心作用****5. Web服务的“被认…...

回溯算法之组合和排列问题
文章目录 1.什么是回溯算法2.回溯算法解题步骤3.回溯算法解决组合问题4.回溯算法解决排列问题 1.什么是回溯算法 回溯算法是一种通过尝试所有可能的解决方案来解决问题的算法策略,它通常用于求解组合优化、排列组合、路径搜索等类型的问题,是一种暴力求解的算法。 2…...
gihub上适合练手的Python项目
GitHub 上有许多适合练手的 Python 项目,涵盖了从初学者到中级开发者的不同难度级别。以下是一些推荐的项目类型和具体示例,帮助你提升 Python 编程技能: 1. 基础项目 适合初学者,帮助掌握 Python 基础语法和常用库。 示例项目&…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...

Linux-进程间的通信
1、IPC: Inter Process Communication(进程间通信): 由于每个进程在操作系统中有独立的地址空间,它们不能像线程那样直接访问彼此的内存,所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...

C++中vector类型的介绍和使用
文章目录 一、vector 类型的简介1.1 基本介绍1.2 常见用法示例1.3 常见成员函数简表 二、vector 数据的插入2.1 push_back() —— 在尾部插入一个元素2.2 emplace_back() —— 在尾部“就地”构造对象2.3 insert() —— 在任意位置插入一个或多个元素2.4 emplace() —— 在任意…...