目录
前言
一、后台接口研发
1、控制层实现
2、Mapper访问层
3、空间查询分析
二、前端可视化展示
1、主体地图定义
2、行政区划列表定义
3、行政区划定位
三、数据分析
1、北京市
2、广东省
3、青海省
4、湖南省
总结
在之前的博文中,我们对全球地震信息进行了可视化展示。地震对人类的生命财产安全造成了严重的威胁,但目前又缺乏科学准确的预测。在无法准确预测的前提下,我们对现今发生的地震信息结合我国的行政区划进行统一展示。目前采集的数据是截止到2023年12月6日的。2023年12月6日以后的,暂时没有采集。
本文使用SpringBoot框架进行开发,将深度分析全国各省的地震震发情况,按照省级行政区划的方式进行空间统计分析,空间数据库依然采用我们熟悉的PostGIS数据库。通过本文可以对全国各省的地震分布有一个大致的了解,快来看看你所在省份是否是地震高发区呢。跟着本文一起来看看吧。
本文后台采用SpringBoot开发框架,数据访问层采用Mybatis-Plus插件。下面将按照MVC开发模式对各层进行设计和实现。
控制层主要提供三个方法,第一个方法是跳转到具体的地图展示页面,第二个方法是根据行政区划code查询地震信息列表,第三个方法是查询行政区划的geojson边界数据。关键代码如下:
package com.yelang.project.extend.earthquake.controller; import java.util.List; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.yelang.framework.web.controller.BaseController; import com.yelang.framework.web.domain.AjaxResult; import com.yelang.framework.web.page.TableDataInfo; import com.yelang.project.extend.earthquake.domain.EarthquakeInfo; import com.yelang.project.extend.earthquake.domain.Province; import com.yelang.project.extend.earthquake.service.IEarthquakeInfoService; import com.yelang.project.extend.earthquake.service.IProvinceService; @Controller @RequestMapping("/eq/province") public class ProvinceController extends BaseController{ private String prefix = "earthquake/province"; @Autowired private IProvinceService provinceService; @Autowired private IEarthquakeInfoService earthQuakeInfoService; @RequiresPermissions("eq:province:view") @GetMapping() public String map(){ return prefix + "/map"; } @RequiresPermissions("eq:province:list") @PostMapping("/list") @ResponseBody public TableDataInfo list(Province province){ startPage(); Listlist = provinceService.selectList(province); return getDataTable(list); } @RequiresPermissions("eq:province:geom") @GetMapping("/geojson/{id}") @ResponseBody public AjaxResult getGeojson(@PathVariable("id") Long id){ Province province = provinceService.findGeoJsonById(id, null); return AjaxResult.success().put("data", province.getGeomJson()); } @RequiresPermissions("eq:province:statview") @GetMapping("/statview") public String statview(){ return prefix + "/statview"; } @RequiresPermissions("eq:province:quakelist") @GetMapping("/quakelist/{code}") @ResponseBody public AjaxResult quakelist(@PathVariable("code") String code){ List list = earthQuakeInfoService.findListByPcode(code); AjaxResult ar = AjaxResult.success(); ar.put("data", list); return ar; } }
系统的业务层比较简单,只是将控制层的参数传递到数据库中。因此这里不对业务层代码进行深度介绍,由于Mapper访问层是对空间数据库的访问,有必要在此进行一些介绍,让广大朋友知道空间分析函数的基本使用方法。
package com.yelang.project.extend.earthquake.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.earthquake.domain.EarthquakeInfo; /** * 地震信息数据操作接口 * @author wuzuhu * */ public interface EarthQuakeInfoMapper extends BaseMapper{ static final String FIND_LISTBY_PCODE = ""; /** * 根据省级行政区划查询对应的地震信息发生列表 * @param code 省份编码 * @return 对应的地震信息列表 */ @Select(FIND_LISTBY_PCODE) List findListByPcode(@Param("code")String code); }
在本文的需求中,我们需要对省级行政区划内的地震震发信息进行可视化统计,需要使用到st_contains函数。这里需要判断点是否在面数据中,使用数据库客户端来验证一下:
select t.* from biz_province p,biz_earthquake_info t where p.code = '110000' and st_contains(p.geom, ST_GeomFromText(format('point(%s %s)',t.eq_lng,t.eq_lat),4326));
其中,110000是北京市的行政编号,通过行政编码来进行行政区划的过滤。执行上述sql语句后可以看到,北京市的震发数量是18条数据。
前端空间数据展示使用Leaflet组件展示,静态标注使用Leaflet.canvaslabel.js,图例组件采用leaflet.legend.js。下面来看看前端可视化代码的具体实现过程。
//矢量文本标签渲染器 var canvasLabel = new L.CanvasLabel({ defaultLabelStyle: { collisionFlg: true, scale: 1.1, //strokeStyle: "#000", strokeStyle: "red", fillStyle: "#fff", //lineWidth:3 lineWidth:15 } }); $("#mapid").height($(window).height());//动态设置高度 L.CRS.CustomEPSG4326 = L.extend({}, L.CRS.Earth, { code: 'EPSG:4326', projection: L.Projection.LonLat, transformation: new L.Transformation(1 / 180, 1, -1 / 180, 0.5), scale: function (zoom) { return 256 * Math.pow(2, zoom - 1); } }); var showGroup = L.layerGroup(); var quakeGroup = L.layerGroup(); //限制地图的拖动范围是正负90到正负180,这样才合理。 var maxBounds = L.latLngBounds(L.latLng(-90, -180), L.latLng(90, 180)); //构建视图限制范围 第一个参数是左上角经纬度 第二个参数是右下点经纬度 var mymap = L.map('mapid',{renderer: canvasLabel,crs:L.CRS.CustomEPSG4326,maxBounds:maxBounds,attributionControl:false}).setView([29.052934, 104.0625], 5); var showLayerGroup =L.featureGroup().addTo(mymap); L.tileLayer('http://192.168.31.64:8086/data/basemap_nowater/1_10_tms/{z}/{x}/{y}.jpg', {minZoom:1, maxZoom: 16, id: 'baseMap-nowater', tileSize: 256, zoomOffset: -1 }).addTo(mymap); //标签 L.tileLayer('http://192.168.31.64:8086/data/basemap_nowater/1-10label/{z}/{x}/{y}.png', {maxZoom: 10,minZoom:1, id: 'mapbox/label',tileSize: 256,zoomOffset: -1 }).addTo(mymap);
function initSidebar(){//初始化sidebar页面 var sidebar = L.control.sidebar('sidebar', {position: 'right'}).addTo(mymap); //默认sidebar打开,并展示一个tab页 sidebar.open(); $("#xz_info").addClass("active"); $("#home").addClass("active"); //初始化行政区划表格 initHnTownTable(); } function initHnTownTable(){ var options = { url: prefix + "/list", createUrl: prefix + "/add", updateUrl: prefix + "/edit/{id}", modalName: "乡镇行政区划", columns: [ { field: 'id', title: '', visible: false }, { field: 'name', title: '省份' }, { field: 'type', title: '类别' }, { title: '操作', align: 'center', formatter: function(value, row, index) { var actions = []; actions.push('查看'); return actions.join(''); } }] }; $.table.init(options); }
在地图右侧列表中,点击定位按钮,可以展示当前省级行政区域的空间范围,同时可以查看对应行政区划范围内的地震震发情况。
function initEarthInfo(code){ $.ajax({ type: "get", url: prefix + "/quakelist/"+ code, data: {}, success: function(rsData) { quakeGroup.clearLayers(); var earthData = rsData.data; for (var i = 0; i < earthData.length; i++) { var info = earthData[i]; var eqLevel = info.eqLevel; var strokeStyleSet = "green"; if(parseFloat(eqLevel) > 3.5 && parseFloat(eqLevel) <= 5.0){ strokeStyleSet = "yellow"; } if(parseFloat(eqLevel) > 5.0){ strokeStyleSet = "red"; } var marker = L.circleMarker(new L.LatLng(info.eqLat, info.eqLng), {radius: 8, labelStyle: { text: info.eqLevel+'级'+info.eqLocation, rotation: 0, zIndex: i, strokeStyle :strokeStyleSet }}); var content = "发震时间:"+info.eqTime + "
震中位置:"+info.eqLocation; content += "
震源深度(千米):"+info.eqDepth + "
震级:"+info.eqLevel; marker.bindPopup(content); quakeGroup.addLayer(marker); } mymap.addLayer(quakeGroup); } }); }
经过后台相关接口的开发,以及前端webgis的界面开发,基本已经完成整个各省行政区划内震发数据的可视化过程,下面结合各省份进行分别说明。由于省份信息众多,这里不全部展开,分别按照区域进行选取一些典型省份进行数据分型说明。
北京市是国家首都,首先来看一下北京市的震发情况,点击操作栏中的查看按钮,地图会自动定位到北京市的行政区划范围,同时将北京市内的所有震发点进行展示。
可以看到,北京的地震震发情况比较少,而且震级也不高。一共是18次(以数据库中发布的地震信息为准,仅供参考),最高的震级是3.6级。整体来说,安全系数还是比较高。
广东省是我们国家的经济大省,也是南方的城市。来看一下南方城市的地震震发情况如何,首先来看一下总体情况。
截止2023年12月6日,广东的地震次数是61次,最大的震级是4.3级。震级不是很高,还算是比较小的。可以看到在省会附近地震震发很少。
看完北部的省份和南方的城市,再来看一下西部的城市,这里选取青海省作为示例。相信从地图上就可以一眼直观的看到地震震发较多。同时通过图例可以知道,红色是大于5级的地震,在青海省超过5级的地震就有好几个。最大是青海果洛州玛多县的7.4级地震
通过在后台查询,青海省的地震次数有466次,比南方和北方省份多了不少。 通过下图可以看到,这附近的大地震还不少。
最后来看一下中部省份湖南省的地震情况。地震震发情况如下:
可以看到,作为中部省份,湖南省的地震情况是非常少的。有一些是矿震引起的,不是地质运动引起的。在数据中可以查到一共有8条地震信息,其中最大的震级是3.4级,发生在湖南娄底市双峰县。
通过gis发现了一些时空分布的规律,当我们把地震活动和空间分析结合在一起,就可以发现,在我们国家的西部地区,也就是喜马拉雅一带,地震活动比较频繁,这也与世界地震带分布有对应关系。
以上就是本文的主要内容,本文使用SpringBoot框架进行开发,将深度分析全国各省的地震震发情况,按照省级行政区划的方式进行空间统计分析,空间数据库依然采用我们熟悉的PostGIS数据库。通过本文可以对全国各省的地震分布有一个大致的了解,快来看看你所在省份是否是地震高发区呢?通过gis可视化,对我们理解地理分布和活动规律有更多的参考和指导。让我们一起用gis去发现更多有意思的分布情况吧。博文使用数据来源于互联网,如有错误,请指出,必将及时修正,欢迎在评论区留言指导,万分感谢。