基于SpringBoot和PotsGIS的各省地震震发可视化分析

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();
    List<Province> list = 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<EarthquakeInfo> list = earthQuakeInfoService.findListByPcode(code);
	AjaxResult ar = AjaxResult.success();
    ar.put("data", list);
    return ar;
}

}


### 2、Mapper访问层


        系统的业务层比较简单,只是将控制层的参数传递到数据库中。因此这里不对业务层代码进行深度介绍,由于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);
}


### 3、空间查询分析


        在本文的需求中,我们需要对省级行政区划内的地震震发信息进行可视化统计,需要使用到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条数据。


![](https://img-blog.csdnimg.cn/direct/76b9bf55942240e0a4258668db159f1a.png)


##  二、前端可视化展示


        前端空间数据展示使用Leaflet组件展示,静态标注使用Leaflet.canvaslabel.js,图例组件采用leaflet.legend.js。下面来看看前端可视化代码的具体实现过程。


### 1、主体地图定义



//矢量文本标签渲染器
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);


### 2、行政区划列表定义



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('<a class="btn btn-success btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="previewTown(\'' + row.id + '\',\''+row.code+'\')"><i class="fa fa-dot-circle-o"></i>查看</a>');
                        return actions.join('');
                    }
                }]
            };
            $.table.init(options);
    }

### 3、行政区划定位


        在地图右侧列表中,点击定位按钮,可以展示当前省级行政区域的空间范围,同时可以查看对应行政区划范围内的地震震发情况。



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);
}
});
}


## 三、数据分析



# 总结

大型分布式系统犹如一个生命,系统中各个服务犹如骨骼,其中的数据犹如血液,而Kafka犹如经络,串联整个系统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。

**麻烦帮忙转发一下这篇文章+关注我**

![就这一次!拼多多内部架构师培训Kafka源码笔记(现已绝版)](https://img-blog.csdnimg.cn/img_convert/627075da7b3d57b56c060d9fbc3b5d04.webp?x-oss-process=image/format,png)

oup);
	            }
	        });
	    }

三、数据分析

总结

大型分布式系统犹如一个生命,系统中各个服务犹如骨骼,其中的数据犹如血液,而Kafka犹如经络,串联整个系统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。

麻烦帮忙转发一下这篇文章+关注我

[外链图片转存中…(img-y7fojwLJ-1719193564207)]

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值