前言
本文以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<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界面实现
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)" rel="external nofollow" 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 + " <strong>名称(中):</strong>"+dataInfo.cnName; content += " <strong>驻地国家(英):</strong>"+dataInfo.enCountry + " <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、中东的部署
最后来看看它在中东的基地部署,众所周知,中东这个地方是个火药桶。中东小霸王曾经一个人单挑中东多国,应该说与漂亮国的护佑不无关系。
从地图上看起来,它在周边的军事存在还好,主要还是靠小霸王的存在。 还是希望世界和平,冲突对老百姓影响太大了。