目录
前言
在前面的博文中,我们对全球的国家信息进行了空间数据的入库。同时为了提供完整准确的空间数据,也同步参考了国家外交部的国家信息介绍。博文列表如下:
|----|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 序号 | 博文地址 |
| 1 | 使用Java调用GeoTools实现全球国家矢量数据入库实战 |
| 2 | 基于SpringBoot的国家基础信息管理功能的设计与实现 |
第一篇主要讲述如何使用Geotools来进行空间数据库的入库,这是所有后续操作的前提条件。第二篇介绍在入库的基础之上,对国家的基本信息的一个编辑管理以满足我们的标准化显示。这两篇博客都没有对如何进行国家的空间矢量范围进行展示。要求不仅提供国家的中文检索,同时支持对国家的空间范围进行可视化,将国家信息叠加到地图中。如下图所示:
本文即讲解如何在SpringBoot中结合Leaflet如何进行国家信息的查询、空间定位、关键信息展示。结合之前讲解过的DivIcon来进行关键信息展示。博客首先讲解如何使用Java在后台进行信息查询的设计与代码实现,然后介绍如何使用Leaflet来进行空间数据Geojson数据的WebGIS的展示,其次介绍如何使用DivIcon来进行关键信息展示,最后展示国家基本信息的查询结果。如果您当前想开发类似的功能或者感兴趣,不妨来来这里看一下。
一、Java后台程序设计
后台主要为前台界面提供信息检索、根据国家ID查询对应的GeoJson信息以及详细信息。这里以Java语言为例,使用MyBatis-Plus来进行数据库的操作查询。后台服务的稳定性和可靠性对整体的查询和操作至关重要,因此这里首先介绍如何进行进行后台的程序设计。
1、业务层设计
业务层主要包含三个主要的方法,如下表所示:
|----|--------------------------------------------------------------------------|-------------------|
| 序号 | 方法名 | 说明 |
| 1 | public List<WorldCountries> selectList(WorldCountries worldCountries); | 查询全球国家信息列表 |
| 2 | WorldCountries findGeoJsonById(Long id); | 根据id查询国家geojson数据 |
| 3 | WorldCountries findByCode(String minName); | 根据国家简称查询国家信息 |
在接口的实现层,提供上面三个方法的主要实现,关键代码如下所示:
java
package com.yelang.project.extend.earthquake.service.impl;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yelang.project.extend.earthquake.domain.WorldCountries;
import com.yelang.project.extend.earthquake.mapper.WorldCountriesMapper;
import com.yelang.project.extend.earthquake.service.IWorldCountriesService;
@Service
public class WorldCountriesServiceImpl extends ServiceImpl<WorldCountriesMapper, WorldCountries> implements IWorldCountriesService{
@Override
public List<WorldCountries> selectList(WorldCountries worldCountries) {
QueryWrapper<WorldCountries> queryWrapper = new QueryWrapper<WorldCountries>();
if(StringUtils.isNotBlank(worldCountries.getFullChineseName())){
queryWrapper.like("full_chinese_name", worldCountries.getFullChineseName());
}
if(StringUtils.isNotBlank(worldCountries.getFullEnglishName())) {
queryWrapper.like("full_english_name", worldCountries.getFullEnglishName());
}
if(StringUtils.isNotBlank(worldCountries.getShortChineseName())) {
queryWrapper.like("short_chinese_name", worldCountries.getShortChineseName());
}
queryWrapper.select(" pk_id,full_english_name,short_english_name,min_english_name,full_chinese_name,short_chinese_name,continent,unreg ");
queryWrapper.orderByAsc("min_english_name");
return this.baseMapper.selectList(queryWrapper);
}
@Override
public WorldCountries findGeoJsonById(Long id) {
return this.baseMapper.findGeoJsonById(id);
}
@Override
public WorldCountries findByCode(String minName) {
QueryWrapper<WorldCountries> queryWrapper = new QueryWrapper<WorldCountries>();
queryWrapper.eq("min_english_name", minName);
queryWrapper.select(" pk_id,full_english_name,short_english_name,min_english_name,full_chinese_name,short_chinese_name,continent,unreg ");
return this.getOne(queryWrapper);
}
}
在这里,为了避免在查询详情或者列表时,也同步把geometry空间属性给查询出来。因此使用Mybatis-Plus的select查询方式进行字段的限制,详情请见上面的关键方法。大家可以查询Mybatis-Plus的官方文档,合理选择查询字段。
2、控制层设计
控制层是具体接收前端的请求的具体对象。从上面的需求中可以得知,我们需要提供一个列表查询接口、空间GeoJson数据的查询接口。提供的方法列表如下:
|----|-----------------------------------------------------------|-------------|
| 序号 | 方法 | 说明 |
| 1 | public TableDataInfo list(WorldCountries wCountry) | 获取国家信息列表 |
| 2 | public AjaxResult getGeojson(@PathVariable("id") Long id) | 查询GeoJson数据 |
代码其实不复杂,这里提供相应的代码实现:
java
@RequiresPermissions("eq:wcountry:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(WorldCountries wCountry){
startPage();
List<WorldCountries> list = wCountryService.selectList(wCountry);
return getDataTable(list);
}
@RequiresPermissions("eq:wcountry:geom")
@GetMapping("/geojson/{id}")
@ResponseBody
public AjaxResult getGeojson(@PathVariable("id") Long id){
WorldCountries country = wCountryService.findGeoJsonById(id);
return AjaxResult.success().put("data", country.getGeomJson());
}
到这里我们大致就将后台的相关服务设置完毕。接下来就可以前端页面的开发和实现。
二、WebGIS可视化实现
在进行了后台服务的实现之后,我们需要展示空间数据,依然采用我们熟悉的Leaflet组件。在Leaflet组件中,采用siderbar侧边栏展示国家基本信息。支持国家信息的检索和具体国家的定位,在定位的同时支持将国家的基本信息以DivIcon的形式进行展示。下面将分别从这三个方面进行讲解如何进行WebGIS的实现。
1、侧边栏展示
侧边栏作为主要的信息列表展示窗口,需要展示国家信息列表,同时列表支持按名称进行模糊查询。为了与地图深入融合,这里我们选择熟悉的sidebar组件。
这里给出sidebar的实现方式,在这里需要后台的查询接口的支持也就是之前开发的后台控制接口。前端展示代码如下所示:
javascript
function initWorldCountryTable(){
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
modalName: "全球国家列表",
columns: [{
checkbox: true
},
{
field: 'pkId',
title: '',
visible: false
},
{
field: 'shortChineseName',
title: '名称',
formatter: function(value, row, index) {
return row.shortChineseName + "(" + row.minEnglishName + ")";
}
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="previewTown(\'' + row.pkId + '\',\''+row.fullChineseName+'\',\''+row.shortEnglishName+'\')"><i class="fa fa-paper-plane"></i>定位</a>');
return actions.join('');
}
}]
};
$.table.init(options);
}
2、空间边界信息展示
在国家信息表格中,点击定位按钮,需要在地图中展示当前选择国家的空间范围信息。为了突出边界范围,我们将边界范围用红色面来标识。同时为了在地图上标识国家信息,同时我们使用DivIcon来进行国家信息的展示。实现的效果如下所示:
首先是边界信息展示,国家边界信息是通过国家ID传到后台后,查询国家边界后返回给前端的。关键代码如下所示:
javascript
function previewTown(gid,cnName,enName){
var myStyle = {color:"red",weight:5,"opacity":0.6};
$.ajax({
type:"get",
url:prefix + "/geojson/" + gid,
data:{},
dataType:"json",
cache:false,
processData:false,
success:function(result){
if(result.code == web_status.SUCCESS){
var areaLayer = L.geoJSON(JSON.parse(result.data),{style:myStyle}).addTo(mymap);
var myIcon = L.divIcon({
iconSize: null,
className: '',
popupAnchor:[5,5],
shadowAnchor:[5,5],
html: "<div class='marsBlackPanel' animation-spaceInDown><div class='marsBlackPanel-text'>中文名称:"+cnName+"<span class='temperature'></span></div><div class='marsBlackPanel-text'>英文名称:"+enName+"<span class='temperature'></span></div></div>"});
showLayerGroup.clearLayers();
showLayerGroup.addLayer(areaLayer);
mymap.fitBounds(areaLayer.getBounds());
//中心点位
L.marker(areaLayer.getBounds().getCenter(), { icon: myIcon}).addTo(showLayerGroup);
}
},
error:function(){
$.modal.alertWarning("获取空间信息失败");
}
});
}
请注意,这里的中心我们取的是GeoJSON的中心点。比较好的方式是通过标记到国家首都会比较好。在一些国土面积狭长的国家,可能就会飘在国土外。在一些大西洋的岛国上,甚至完全飘到了海上,如下图中的巴哈马。因此这里仅作为示例,大家在实践过程中需要结合首都位置来进行标记。
上面就是一个大西洋国家的巴哈马的,由很多的海岛,通过取中心点的方式得到的位置就标注到了大西洋去了。
三、标注成果展示
经过前面后台和前端程序的的开发,基本可以实现国家信息的WebGIS可视化。下面我们来看下全球一些国家的地理知识。基于国家基本信息进行Web可视化来探寻一下。
1、面积最大的国家
首先先来看一下世界上陆地国土面积最大的国家-俄罗斯。横跨了欧亚大陆,其国土面积1709.82万平方公里。俄罗斯横跨欧亚大陆,东西最长9000公里,南北最宽4000公里。邻国西北面有挪威、芬兰,西面有爱沙尼亚、拉脱维亚、立陶宛、波兰、白俄罗斯,西南面是乌克兰,南面有格鲁吉亚、阿塞拜疆、哈萨克斯坦,东南面有中国、蒙古和朝鲜。东面与日本和美国隔海相望。大部分地区处于北温带,以大陆性气候为主,温差普遍较大,1月气温平均为-40~-5℃,7月气温平均为11~27℃。
这几年俄乌大战,因此这里也来看看乌克兰的国家地理位置。
上图便是乌克兰的国家基本位置。 位于欧洲东部。北邻白俄罗斯,东北接俄罗斯,西连波兰、斯洛伐克、匈牙利,西南同罗马尼亚、摩尔多瓦毗邻,南面是黑海、亚速海,隔海同土耳其相望。
2、国土面积最小的国家
来看了国土面积最大的国家,再来看一下国土面积最小的国家-那就是梵蒂冈。梵蒂冈城国(The Vatican City State)。国土面积只有0.44平方公里。常住人口764人(2023年6月),意大利人为主。官方语言为意大利语和拉丁语。信奉天主教。764个人,我们国家一个小区恐怕都比这多。它位于意大利的首都罗马中。由于它的国土面积太小,以至于我无法在地图上精准的标绘。
3、海拔最低的国家
世界上海拔最低的国家:荷兰。荷兰位于欧洲的西北部,境内有1/3的土地仅高出海平面1米,有24%的土地低于海平面6-7米,最高海拔321米,平均海拔仅仅只有2米,被称为"低地之国"。本土位于欧洲西北部。东邻德国,南接比利时,西、北濒北海。海岸线长1075公里。24%的面积低于海平面,1/3的面积仅高出海平面1米。从13世纪即开始围海造田,增加土地面积约6000平方公里。属海洋性温带阔叶林气候。沿海地区平均气温夏季16℃,冬季3℃;内陆地区夏季17℃,冬季2℃。年平均降水量797毫米。
4、最大的群岛国家
世界上最大的群岛国家:印度尼西亚。印尼位于东南亚、印度洋和太平洋之间,是全世界最大的群岛国家,由17508个岛屿组成。印度尼西亚有数百个民族,其中爪哇族人口占45%,还有巽他族、马都拉族、马来族等。它的人口有2.81亿(2023年12月),世界第四人口大国。没有想到吧,它的人口居然有这么多。印度尼西亚的国土范围如下:
关于世界国家地理,有了这个基础,大家可以任意发挥,去探索更加有趣的地理知识吧。世界很大,等你去发现。
四、总结
以上就是本文的主要内容,本文即讲解如何在SpringBoot中结合Leaflet如何进行国家信息的查询、空间定位、关键信息展示。结合之前讲解过的DivIcon来进行关键信息展示。博客首先讲解如何使用Java在后台进行信息查询的设计与代码实现,然后介绍如何使用Leaflet来进行空间数据Geojson数据的WebGIS的展示,其次介绍如何使用DivIcon来进行关键信息展示,最后展示国家基本信息的查询结果。行文仓促,定有许多不足之处,如有不足还恳请各位专家朋友在评论区批评指出,不甚荣幸。