基于SpringBoot和PostGIS的某国基地可视化实战
目录
前言
一、Java后台开发设计与实现
1、模型层实现
2、控制层设计
二、WebGIS界面实现
1、列表界面的定义
2、全球基地可视化
三、成果展示
1、全球部署情况
2、亚太地区
3、欧洲基地分布
4、中东的部署
四、总结
前言
在之前的博客中,我们曾经对漂亮国的基地信息进行了采集,包括其国内的基地和海外的基地。关注最近的世界新闻的朋友应该注意到了,就是最近中东小霸王被周边的国家群殴了。今天我们结合上次搜集的数据来对其全球的基地信息进行空间可视化,看看它的空间部署方位图。

本文以Java开发语言为例,使用SpringBoot框架来进行后台开发,详细讲解如何使用Leaflet对PostGIS的全球基地信息进行Web可视化,最后分享Web可视化结果。从国内基地,到海外不同国家的具体的驻扎分布。让您对其在世界各地的分布有直观的感受。通过本文,您可以学习如何使用Java来开发WebGIS系统,对于空间数据的可视化有了更深的掌握。
一、Java后台开发设计与实现
作为标准的web程序,这里采用MVC的设计架构,后台采用Springboot来进行开发。本节将从模型层、业务层、控制层三层的具体设计与实现来详细讲解。
1、模型层实现
模型层主要包含业务实体层和Mapper的数据库操作层。其中模型层主要用来做数据库和真实基地对象的关系映射,与数据库表是逐一对应的。Mapper是实现空间对象到数据库对应持久化的对象,来实现基地信息的查询、新增、修改和删除操作。
实体层对象的代码如下:
package com.yelang.project.extend.militarytopics.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yelang.framework.handler.PgGeometryTypeHandler;
import com.yelang.framework.web.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/*** 美军军事基地实体类* @author 夜郎king*/
@TableName(value ="biz_usa_military_base",autoResultMap = true)
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class UsaMilitaryBase extends BaseEntity{private static final long serialVersionUID = 9052078556566456025L;@TableIdprivate Long id;//主键@TableField(value = "en_name")private String enName;@TableField(value = "en_desc")private String enDesc;@TableField(value = "cn_name")private String cnName = "";private String remark;private Integer type;//基地类型,1海外 0 本土@TableField(value="en_country")private String enCountry = "";//部署国家英文名@TableField(value="cn_country")private String cnCountry = "";//部署国家英文名@TableField(value="en_city")private String enCity = "";//部署城市英文名@TableField(value="cn_city")private String cnCity = "";//部署城市中文名@TableField(typeHandler = PgGeometryTypeHandler.class)private String geom;@TableField(exist=false)private String geomJson;
}
其次,在Mapper层中,我们提供两个方法,方法展示如下:
| 序号 | 方法名 | 说明 |
| 1 | List<UsaMilitaryBase> findList() | 查询美军军事基地列表 |
| 2 | UsaMilitaryBase findMilitaryBaseById(@Param("id") Long id) | 根据数据库ID查询基地详情 |
Mapper对象的关键代码如下:
package com.yelang.project.extend.militarytopics.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yelang.project.extend.militarytopics.domain.UsaMilitaryBase;
public interface UsaMilitaryBaseMapper extends BaseMapper<UsaMilitaryBase>{static final String FIND_LIST= "<script>"+ " select t.*,st_asgeojson(t.geom) as geomJson from biz_usa_military_base t order by create_time desc,en_name "+ "</script>";/*** 查询美军军事基地列表* @return 返回美军全球军事基地列表*/@Select(FIND_LIST)List<UsaMilitaryBase> findList();static final String FIND_BYID= "<script>"+ " select t.*,st_asgeojson(t.geom) as geomJson from biz_usa_military_base t where t.id = #{id} "+ "</script>";/*** 根据数据库ID查询基地详情* @param id* @return id对应的基地信息*/@Select(FIND_BYID)UsaMilitaryBase findMilitaryBaseById(@Param("id") Long id);
}
2、控制层设计
控制层主要接收前端的请求,同时调用业务层的业务逻辑代码,将前端传入的参数再传给业务层,实现业务的处理,然后接收业务层返回的数据,再继续返回给前端。由于这里的业务层没有特别复杂的方法,这里仅将分页查询List的方法分享出来,其它方法都是简单的单表操作。
@Override
public List<UsaMilitaryBase> selectList(UsaMilitaryBase entity) {QueryWrapper<UsaMilitaryBase> queryWrapper = new QueryWrapper<UsaMilitaryBase>();if (StringUtils.isNotBlank(entity.getEnName())) {queryWrapper.like("en_name", entity.getEnName());}if (StringUtils.isNotBlank(entity.getCnName())) {queryWrapper.like("cn_name", entity.getCnName());}queryWrapper.orderByDesc("create_time");queryWrapper.orderByAsc("en_name");return this.baseMapper.selectList(queryWrapper);
}
剩下比较重要的就是定义控制层,除了之前提供的管理接口。这里我们重要介绍三个方法:
| 序号 | 方法名 | 说明 |
| 1 | String map() | 前端跳转到地图展示页面 |
| 2 | AjaxResult globalList() | 使用ajax获取所有基地信息列表 |
| 3 | AjaxResult getInfo(@PathVariable("id") Long id) | 获取单个基地信息接口 |
其关键方法如下:
@RequiresPermissions("mt:usabase:map")
@GetMapping("/map")
public String map(){return prefix + "/map";
}@RequiresPermissions("mt:usabase:globallist")
@GetMapping("/globallist")
@ResponseBody
public AjaxResult globalList(){List<UsaMilitaryBase> list = mbaseService.findList();AjaxResult ar = AjaxResult.success();ar.put("data", list);return ar;
}@GetMapping("/info/{id}")
@ResponseBody
public AjaxResult getInfo(@PathVariable("id") Long id){UsaMilitaryBase province = mbaseService.findMilitaryBaseById(id);return AjaxResult.success().put("data", province);
}
以上就是后台的设计及代码的具体实现。下面再来进行前端的WebGIS功能开发。
二、WebGIS界面实现
在WebGIS的页面中,我们将展示界面分为两个部分,左边是全球的基地展示部分,右边的地图展示部分,左边支持按照基地的中英文名称进行模糊检索,结果以列表的形式展示;右边是地图展示界面,将全球的基地信息都显示在一张图上,同时在地图上点击一个标记,可以把当前基地的主要信息展示出来,比如基地的中英文名称,驻扎所在国家的中英文名称也同时展示出来。下面我们将代码进行详细的说明。
1、列表界面的定义
列表的展示需要绑定到前端组件中,定义的关键代码如下:
<div class="col-sm-3"><div class="col-sm-12 search-collapse" style="display: none;"><form id="formId"><div class="select-list"><ul><li>基地名(英):<input type="text" name="enName"/></li><li>基地名(中):<input type="text" name="cnName"/></li><li><a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i> 搜索</a><a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i> 重置</a></li></ul></div></form></div><div class="btn-group-sm" id="toolbar" role="group"><!-- <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="eq:info:export"><i class="fa fa-download"></i> 导出</a>--></div><div class="col-sm-12 select-table table-striped"><table id="bootstrap-table"></table></div></div>
然后我们通过javascript将数据挂载到div元素中,详细的代码如下所示:
ar options = {url: prefix + "/list",modalName: "美军全球军事基地",columns: [{field: 'id',title: '',visible: false},{field: 'enName',title: '基地名称',formatter: function(value, row, index) {//return row.code + "/"+ row.name;return row.enName;}},{title: '操作',align: 'center',formatter: function(value, row, index) {var actions = [];actions.push('<a class="btn btn-success btn-xs " href="javascript:void(0)" onclick="preview(\'' + row.enName + '\',\''+row.id+'\')"><i class="fa fa-send-o"></i></a> ');return actions.join('');}}]};$.table.init(options);
2、全球基地可视化
在界面中初始化表格的基本信息之后,我们还要将其全球的基地信息全部查询出来,然后在地图上进行展示。地图的展示包括两个部分,第一个部分是图例的展示,包括国内和海外基地两种类型。具体图例的展示如下:
function initLegend(){const legend = L.control.Legend({position: "bottomright",collapsed: false,symbolWidth: 35,opacity: 1,title:"图例",column: 2,legends: [ {label: "海外",type: "circle",radius: 12,color: "#c50808",fillColor: "#c50808",fillOpacity: 0.6,weight: 2}, {label: "本土",type: "circle",radius: 10,color: "#168d40",fillColor: "#168d40",fillOpacity: 0.6,weight: 2}]}).addTo(mymap);}
将图例信息定义好之后,再请求后端的获取所有信息接口,将所有的基地信息查询出来,然后在使用Leaflet进行空间展示,关键代码如下:
function showMilitary(){$.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];var geomObj = JSON.parse(dataInfo.geomJson);var radiusSize = 6;switch(dataInfo.type) {case 0: strokeStyleSet = "#168d40";break;default:strokeStyleSet = "#c50808";}var content = "<strong>名称(英):</strong>"+dataInfo.enName + "<br/><strong>名称(中):</strong>"+dataInfo.cnName;content += "<br/><strong>驻地国家(英):</strong>"+dataInfo.enCountry + "<br/><strong>驻地国家(英):</strong>"+dataInfo.cnCountry;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.cnName != '' ? dataInfo.cnName : dataInfo.enName,rotation: 0,zIndex: radiusSize,minZoom : 2,fillStyle: strokeStyleSet}}).addTo(showLayerGroup);marker.bindPopup(content); }mymap.addLayer(showLayerGroup);}},error:function(){$.modal.alertWarning("获取信息失败");}});}
以上就是使用Leaflet进行WebGIS开发的关键代码,实现将基地列表可视化以及全球基地的空间可视化。
三、成果展示
在后台开发和前端web界面可视化都完成之后,下面我们来看一下实际的页面效果。通过对结果的分析,可以看到其全球的基地分布情况。本节将从全球、亚太、欧洲、中东、本地四个角度来进行说明。
1、全球部署情况

从全球来看,漂亮国的基地在全球很多重点的地方都有部署。比如亚太的国家中,日本和韩国;欧洲的德国,意大利等等,同时在南美洲也有一些基地,其太平洋的基地许多都极负盛名,比如关岛的基地。在重要巷道,比如马六甲海峡的新加坡有驻军,红海口也有基地,波斯湾也是部署基地的重要位置。
2、亚太地区
二战及朝鲜战争后,其在亚太地区有很多的军事部署。比如在驻韩美军和驻日美军,这两个国家有很多的基地。下面来详细看一下:

这是驻韩美军的分布,可以看到在很多密密麻麻的红点,表明在韩国部署了大量的力量。

与之对应的还有日本,日本也是很多驻军,其中包括美军海外的唯一一个航母基地,横须贺航母基地,还有若干的空军基地。在冲绳地区,很小的地方就部署了若干的基地。

3、欧洲基地分布
美国的欧洲基地分布主要集中在德国、意大利和英国等,这些国家也是北约的主要成员国。

在德国的基地分布主要是集中在原西德的地方,基地的分布是最多的。其在意大利的基地分布情况如下:

4、中东的部署
最后来看看它在中东的基地部署,众所周知,中东这个地方是个火药桶。中东小霸王曾经一个人单挑中东多国,应该说与漂亮国的护佑不无关系。

从地图上看起来,它在周边的军事存在还好,主要还是靠小霸王的存在。 还是希望世界和平,冲突对老百姓影响太大了。
四、总结
以上就是本文的主要内容,本文以Java开发语言为例,使用SpringBoot框架来进行后台开发,详细讲解如何使用Leaflet对PostGIS的全球基地信息进行Web可视化,最后分享Web可视化结果。从国内基地,到海外不同国家的具体的驻扎分布。让您对其在世界各地的分布有直观的感受。行文仓促,难免有不足之处,欢迎朋友们在评论区批评指正,不甚感谢。
相关文章:
基于SpringBoot和PostGIS的某国基地可视化实战
目录 前言 一、Java后台开发设计与实现 1、模型层实现 2、控制层设计 二、WebGIS界面实现 1、列表界面的定义 2、全球基地可视化 三、成果展示 1、全球部署情况 2、亚太地区 3、欧洲基地分布 4、中东的部署 四、总结 前言 在之前的博客中,我们曾经对漂亮…...
为什么Linux服务器空间充足而实际上空间已满的原因
以下是一个典型的Linux服务器的磁盘空间使用情况表,展示了不同文件系统的大小、已用空间、可用空间和挂载点等信息 磁盘空间表的基本组成 Linux服务器的磁盘空间使用情况通常通过df命令查看,输出的表格包含以下几列: Filesystem:…...
【LC刷题】DAY16:530 501 236
【LC刷题】DAY16:530 501 236 文章目录 【LC刷题】DAY16:530 501 236530. 二叉搜索树的最小绝对差 [link](https://leetcode.cn/problems/minimum-absolute-difference-in-bst/description/)501.二叉搜索树中的众数236. 二叉树的最近公共祖先 [link](htt…...
Vue 3 的 Teleport 组件实现跨层级通信
突破组件边界 - 使用 Vue 3 的 Teleport 组件实现跨层级通信 你可能已经熟悉了组件的基本概念:每个组件都是一个独立的单元,拥有自己的模板、样式和逻辑。但是,有时候我们需要在不同层级的组件之间进行交互,这就需要用到 Vue 3 中新引入的 Teleport 组件。 Teleport 组件可以…...
chromadb
Chroma是一款AI开源向量数据库,用于快速构建基于LLM的应用,支持Python和Javascript语言。具备轻量化、快速安装等特点,可与Langchain、LlamaIndex等知名LLM框架组合使用。 官网: https://www.trychroma.com/ https://docs.trychr…...
Gradle 自动化项目构建-Gradle 核心之 Project
一、前言 从明面上看,Gradle 是一款强大的构建工具,但 Gradle 不仅仅是一款强大的构建工具,它更像是一个编程框架。Gradle 的组成可以细分为如下三个方面: groovy 核心语法:包括 groovy 基本语法、闭包、数据结构、面…...
简单介绍 Kamailio cfg_rpc 模块
记得先加载 cfg_rpc 模块 loadmodule "cfg_rpc.so" kamailio 起来之后 运行 kamcmd cfg.list 可以得到: dispatcher: probing_threshold dispatcher: inactive_threshold dispatcher: ping_reply_codes rtpengine: rtpengine_disable_tout rtpengine: a…...
Windows 根据github上的环境需求,安装一个虚拟环境,安装cuda和torch
比如我们在github上看到一个关于运行环境的需求 Installation xxx系统Python 3.xxx CUDA 9.2PyTorch 1.9.0xxxxxx 最主要的就是cuda和torch,这两个会卡很多环境的安装。 我们重新走一遍环境安装。 首先创建一个虚拟环境 conda create -n 环境名字 python3.xxx…...
LeetCode 179. 最大数
更多题解尽在 https://sugar.matrixlab.dev/algorithm 每日更新。 组队打卡,更多解法等你一起来参与哦! LeetCode 179. 最大数,难度中等。 排序 解题思路:现将 int 类型转成 str 类型,然后进行字符串比较,…...
基于Java+SpringBoot+vue+elementui药品商城采购系统详细设计实现
基于JavaSpringBootvueelementui药品商城采购系统详细设计实现 🍅 作者主页 网顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各种…...
Pikachu靶场--文件上传
参考借鉴 Pikachu靶场之文件上传漏洞详解_皮卡丘文件上传漏洞-CSDN博客 文件上传漏洞:pikachu靶场中的文件上传漏洞通关_pikachu文件上传通关-CSDN博客 client check 在桌面新建一个文件夹,准备一个hello.php文件,文件写入如下代码 <?p…...
突破架构瓶颈:克服软件系统中的漂移和侵蚀
一种常见但不完美的比喻是将软件系统中的架构漂移和侵蚀与物理建筑的架构相比。虽然这个比喻很直观,但它存在一个根本性的误解,这也常常引发软件开发中的架构问题。 试想一下,一个设计良好的摩天大楼或房屋建成后,我们期望它基本保…...
每日练题(py,c,cpp).6_19,6_20
检验素数 from math import sqrt a int(input("请输入一个数:")) for i in range(2,int(sqrt(a))):if a%i 0:print("该数不是素数")breakelse: print("该数是素数")# # 1既不是素数也不是合数 # #可以用flag做标志位 # b int(…...
居中显示-css样式
在微信小程序中,要让一个盒子(子元素)在另一个盒子(父元素)内部居中显示,可以使用以下几种方法: 1. 使用 Flex 布局 微信小程序支持使用类似于 CSS Flexbox 的布局方式。以下是使用 Flex 布局的…...
生骨肉冻干喂猫比较好?热门、口碑好、值得入手生骨肉冻干力荐
随着科学养猫的普及,生骨肉冻干喂养越来越受欢迎,生骨肉冻干喂养对猫的好处很多,它符合猫咪的天性,可以提供全面的营养,保持牙齿和牙龈的健康,还有助于维持健康的消化系统。虽然许多猫主人看到了生骨肉冻干…...
【安卓13 源码】RescueParty救援机制
RescueParty机制正是在这个背景下诞生的,当它注意到系统或系统核心组件陷入循环崩溃状态时,就会根据崩溃的程度执行不同的救援行动,以期望让设备恢复到正常使用的状态。 开机后会自动重启,进入Recovery界面。经查找,是…...
详细介绍iutils.dll丢失的多个解决方法,一键快速修复丢失的iutils.dll文件
当用户遭遇“iutils.dll缺失”的提示时,这通常预示着依赖该库文件的程序将面临启动失败或功能受限的风险。DLL(Dynamic Link Library,动态链接库)文件无疑占据了核心地位。这些文件就如同建筑师手中的蓝图,为软件的构建…...
基于SpringBoot+Vue的美容美发在线预约系统的设计与实现【附源码】
毕业设计(论文) 题目:基于SpringBootVue的美容美发在线预约系统的设计与实现 二级学院: 专业(方向): 班 级: 学 生: 指导教师ÿ…...
语言的数据结构:树与二叉树(二叉树篇)
语言的数据结构:树与二叉树(二叉树篇) 前言概念特别的二叉树满二叉树完全二叉树 存储结构顺序存储链式存储 查找方式 前言 上文说到了树,有人认为二叉树是树的每一个分支都有两个子节点。其实这也对。但二叉树在此基础上还做了限…...
若以框架学习(3),echarts结合后端数据展示,暂时完结。
前三天,参加毕业典礼,领毕业证,顿时感到空落落的失去感,没有工作,啥也没有,总感觉一辈子白活了。晚上ktv了一晚上,由于我不咋个唱歌,没心情,听哥几个唱了一晚上周杰伦&am…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
