基于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; @TableId private 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 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{ static final String FIND_LIST= "" + " select t.*,st_asgeojson(t.geom) as geomJson from biz_usa_military_base t order by create_time desc,en_name " + ""; /** * 查询美军军事基地列表 * @return 返回美军全球军事基地列表 */ @Select(FIND_LIST) List findList(); static final String FIND_BYID= "" + " select t.*,st_asgeojson(t.geom) as geomJson from biz_usa_military_base t where t.id = #{id} " + ""; /** * 根据数据库ID查询基地详情 * @param id * @return id对应的基地信息 */ @Select(FIND_BYID) UsaMilitaryBase findMilitaryBaseById(@Param("id") Long id); }
2、控制层设计
控制层主要接收前端的请求,同时调用业务层的业务逻辑代码,将前端传入的参数再传给业务层,实现业务的处理,然后接收业务层返回的数据,再继续返回给前端。由于这里的业务层没有特别复杂的方法,这里仅将分页查询List的方法分享出来,其它方法都是简单的单表操作。
@Override public List selectList(UsaMilitaryBase entity) { QueryWrapper queryWrapper = new QueryWrapper(); 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 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、列表界面的定义
列表的展示需要绑定到前端组件中,定义的关键代码如下:
- 基地名(英):
- 基地名(中):
- 搜索 重置
然后我们通过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(' '); 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