当前位置:   article > 正文

基于Java实现震中附近风景区预警可视化分析实践_java实现洪水预报

java实现洪水预报

目录

前言

一、空间数据说明

1、表结构信息展示

2、空间范围查询

二、Java后台开发实现

1、模型层设计与实现

2、控制层设计与实现

三、Leaflet地图开发

1、地震震中位置展示

2、百公里风景区列表展示

3、风景区列表展示

4、附近风景区展示

四、总结


前言

        地震这类地址灾害的发生常常是不能提前预知的,而往往在人群聚集的地方会给人们带来巨大的财产损失。在人类活动过程中,旅游景点往往是人们热门的出行地方,尤其是5A、4A级这样的旅游景区。在出行的过程当中,往往是没有进行任何准备的。这里以2017年8月8日,发生在我国四川省阿坝州九寨沟县的M7.0级地震为例,详细展示了在震区100公里范围内的所有A级旅游景点。通过100公里范围内的旅游景点展示,同时展示直线距离。为地震发生后,结合地震的震级和影像范围,为地震范围内的旅游景点,尤其是热门旅游景点的影响评估做一个评估参考。突如其来的地震,已导致部分列车停运,不少游客被困景区。九寨沟风景名胜区位于九寨沟县漳扎镇境内,地震发生当日接待游客量为3.4万余人次。目前,九寨沟风景名胜区管理局正全力开展景区排险工作,为保证游客游览安全,九寨沟景区停止接待游客。具体接待游客时间另行通告。九寨沟风景名胜区管理局表示,已经预订了8月9日及以后门车票的游客可到阿坝文旅办理退票,已出8月9日票的游客,在九寨沟景区沟口售票大厅办理退票。

        这次地震对旅游风景区的影响很大。地震及后续的余震对这些游客和当地的老板姓都是很大的安全威胁。本文基于地震信息和全国风景旅游区位置信息,在发震位置点构建一个直径100公里的影响范围景区列表。将地震震级、风景区里震中位置距离、风景区级别、旅游人数信息(可以从景点接待处获取),在实际工作当中,我们可以结合这些数据进行地震风险评估,为后续的救援和应急力量的输送与分配推送一个比较优化的方案。

        本文使用Java开发语言,使用PostGIS空间数据库,构建这样一个空间范围分析模型,输出震中百公里影响景点。将作为下一步的数据分析基础提供数据支撑。通过构建源点位与目标点位的实际距离,构建模型分析的基本要素之一,感兴趣的朋友可以看看本文,了解相关的知识。

一、空间数据说明

        本节将对空间数据结构和数据,100公里范围的空间分析查询进行简单介绍。让大家了解如何进行地震位置指定范围风景区查询。查询涉及的表有两张,第一张是地震信息表,第二张是风景区信息表。

1、表结构信息展示

        这里直接展示地震信息表和风景区信息表两张表的物理结构,表结构信息如下:

         上述这两张表的DDL语句如下所示:

  1. CREATE TABLE "public"."biz_ceic_earthquake" (
  2. "pk_id" int8 NOT NULL,
  3. "auto_flag" varchar(30) COLLATE "pg_catalog"."default",
  4. "cata_id" varchar(30) COLLATE "pg_catalog"."default",
  5. "cata_type" varchar(30) COLLATE "pg_catalog"."default",
  6. "epi_depth" numeric(11,8),
  7. "epi_lat" varchar(15) COLLATE "pg_catalog"."default",
  8. "epi_lon" varchar(15) COLLATE "pg_catalog"."default",
  9. "eq_cata_type" varchar(30) COLLATE "pg_catalog"."default",
  10. "eq_type" varchar(30) COLLATE "pg_catalog"."default",
  11. "is_del" varchar(6) COLLATE "pg_catalog"."default",
  12. "location_c" varchar(255) COLLATE "pg_catalog"."default",
  13. "location_s" varchar(100) COLLATE "pg_catalog"."default",
  14. "loc_stn" varchar(20) COLLATE "pg_catalog"."default",
  15. "m" varchar(10) COLLATE "pg_catalog"."default",
  16. "mmb" varchar(10) COLLATE "pg_catalog"."default",
  17. "mmb2" varchar(10) COLLATE "pg_catalog"."default",
  18. "mml" varchar(10) COLLATE "pg_catalog"."default",
  19. "mms" varchar(10) COLLATE "pg_catalog"."default",
  20. "mms7" varchar(10) COLLATE "pg_catalog"."default",
  21. "new_did" varchar(16) COLLATE "pg_catalog"."default",
  22. "o_time" timestamp(6),
  23. "o_time_fra" varchar(10) COLLATE "pg_catalog"."default",
  24. "save_time" timestamp(6),
  25. "sum_stn" varchar(10) COLLATE "pg_catalog"."default",
  26. "sync_time" timestamp(6),
  27. "epi_id" varchar(10) COLLATE "pg_catalog"."default",
  28. "geom" "public"."geometry",
  29. CONSTRAINT "pk_biz_ceic_earthquake" PRIMARY KEY ("pk_id")
  30. );
  31. CREATE INDEX "idx_biz_ceic_earthquake_eqidept" ON "public"."biz_ceic_earthquake" USING btree (
  32. "epi_depth" "pg_catalog"."numeric_ops" ASC NULLS LAST
  33. );
  34. CREATE INDEX "idx_biz_ceic_earthquake_geom" ON "public"."biz_ceic_earthquake" USING gist (
  35. "geom" "public"."gist_geometry_ops_2d"
  36. );
  37. CREATE INDEX "idx_biz_ceic_earthquake_m" ON "public"."biz_ceic_earthquake" USING btree (
  38. "m" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
  39. );
  40. COMMENT ON COLUMN "public"."biz_ceic_earthquake"."pk_id" IS '主键id';
  41. COMMENT ON COLUMN "public"."biz_ceic_earthquake"."epi_depth" IS '地震深度';
  42. COMMENT ON COLUMN "public"."biz_ceic_earthquake"."epi_lat" IS '纬度';
  43. COMMENT ON COLUMN "public"."biz_ceic_earthquake"."epi_lon" IS '经度';
  44. COMMENT ON COLUMN "public"."biz_ceic_earthquake"."geom" IS '位置';
  45. COMMENT ON TABLE "public"."biz_ceic_earthquake" IS '中国地震台网信息表';
  1. CREATE TABLE "public"."biz_scenic_spot" (
  2. "id" int8 NOT NULL,
  3. "name" varchar(255) COLLATE "pg_catalog"."default",
  4. "level" varchar(4) COLLATE "pg_catalog"."default",
  5. "province" varchar(255) COLLATE "pg_catalog"."default",
  6. "city" varchar(255) COLLATE "pg_catalog"."default",
  7. "area" varchar(255) COLLATE "pg_catalog"."default",
  8. "address" varchar(255) COLLATE "pg_catalog"."default",
  9. "evaluation_time" varchar(255) COLLATE "pg_catalog"."default",
  10. "publish_time" varchar(255) COLLATE "pg_catalog"."default",
  11. "lng_gcj02" varchar(30) COLLATE "pg_catalog"."default",
  12. "lat_gcj02" varchar(30) COLLATE "pg_catalog"."default",
  13. "lng_bd09" varchar(30) COLLATE "pg_catalog"."default",
  14. "lat_bd09" varchar(30) COLLATE "pg_catalog"."default",
  15. "lng_wgs84" varchar(30) COLLATE "pg_catalog"."default",
  16. "lat_wgs84" varchar(30) COLLATE "pg_catalog"."default",
  17. "geom" "public"."geometry",
  18. "publish_link" varchar(255) COLLATE "pg_catalog"."default",
  19. CONSTRAINT "pk_biz_scenic_spot" PRIMARY KEY ("id")
  20. );
  21. CREATE INDEX "idx_biz_scenic_spot_geom" ON "public"."biz_scenic_spot" USING gist (
  22. "geom" "public"."gist_geometry_ops_2d"
  23. );
  24. COMMENT ON COLUMN "public"."biz_scenic_spot"."id" IS '主键';
  25. COMMENT ON COLUMN "public"."biz_scenic_spot"."name" IS '景区名称';
  26. COMMENT ON COLUMN "public"."biz_scenic_spot"."level" IS '景区级别';
  27. COMMENT ON COLUMN "public"."biz_scenic_spot"."province" IS '所属省份';
  28. COMMENT ON COLUMN "public"."biz_scenic_spot"."city" IS '所属城市';
  29. COMMENT ON COLUMN "public"."biz_scenic_spot"."area" IS '所属区县';
  30. COMMENT ON COLUMN "public"."biz_scenic_spot"."address" IS '地址';
  31. COMMENT ON COLUMN "public"."biz_scenic_spot"."evaluation_time" IS '评定时间';
  32. COMMENT ON COLUMN "public"."biz_scenic_spot"."publish_time" IS '发布时间';
  33. COMMENT ON COLUMN "public"."biz_scenic_spot"."lng_gcj02" IS 'lng_GCJ02';
  34. COMMENT ON COLUMN "public"."biz_scenic_spot"."lat_gcj02" IS 'lat_GCJ02';
  35. COMMENT ON COLUMN "public"."biz_scenic_spot"."lng_bd09" IS 'lng_BD09';
  36. COMMENT ON COLUMN "public"."biz_scenic_spot"."lat_bd09" IS 'lat_BD09';
  37. COMMENT ON COLUMN "public"."biz_scenic_spot"."lng_wgs84" IS 'lng_WGS84';
  38. COMMENT ON COLUMN "public"."biz_scenic_spot"."lat_wgs84" IS 'lat_WGS84';
  39. COMMENT ON COLUMN "public"."biz_scenic_spot"."publish_link" IS '发布链接';
  40. COMMENT ON TABLE "public"."biz_scenic_spot" IS '全国风景区信息表';

2、空间范围查询

        与之前介绍过的附近城市分析涉及的空间分析查询一样,主要的空间分析函数是:st_dwithin,这里依然以九寨沟地震震发中心点为查询样例:

  1. SELECT
  2. T.*,
  3. st_x ( T.geom ) lon,
  4. st_y ( T.geom ) lat,
  5. st_distance ( T.geom :: geography, t1.geom :: geography ) dist
  6. FROM
  7. biz_scenic_spot T,
  8. biz_ceic_earthquake t1
  9. WHERE
  10. t1.pk_id = 1780964053414354949
  11. AND st_dwithin ( T.geom :: geography, t1.geom :: geography, 5000 * 20 )
  12. ORDER BY
  13. dist;

        在PostGIS当中执行上述空间查询语句之后,可以看到以下结果:

        下面的章节将实现把上面的查询结果进行Web应用开发,完全实现通过一个地震点来实时查询地震点附近的风景区列表分析。 

二、Java后台开发实现

        在了解了空间数据查询的SQL具体的写法之后,我们来开发针对性的后台。开发语言采用我们熟悉的Java开发语言。java开发采用熟悉的MVC三层开发模式。

1、模型层设计与实现

        在模型层,我们主要介绍实体类的代码实现和Mapper即数据库访问层的设计与实现。实体类主要用来将数据库查询的结果集绑定到对象中。而Mapper则实现对PostGIS空间数据库的绑定和设置。实例代码如下:

  1. package com.yelang.project.extend.scenicspot.domain;
  2. import java.io.Serializable;
  3. import java.math.BigDecimal;
  4. import lombok.AllArgsConstructor;
  5. import lombok.Getter;
  6. import lombok.NoArgsConstructor;
  7. import lombok.Setter;
  8. import lombok.ToString;
  9. @NoArgsConstructor
  10. @AllArgsConstructor
  11. @Setter
  12. @Getter
  13. @ToString
  14. public class ScenicSpotDistVo implements Serializable{
  15. private static final long serialVersionUID = -1403627497900208179L;
  16. private BigDecimal dist;//距离
  17. private String address;//位置
  18. private String name;//名称
  19. private String level;//风景区级别
  20. private String lon;//经度
  21. private String lat;
  22. }

           在Mapper接口中定义以下方法,用于实现从数据库中查询相应的风景区数据列表。

  1. static final String FIND_LIST_BY_EARTHID = "<script>"
  2. + " select t.name,t.level,t.address,st_x(t.geom) lon,st_y(t.geom) lat, "
  3. + " st_distance(t.geom :: geography, t1.geom :: geography) dist from biz_scenic_spot t,biz_ceic_earthquake t1 "
  4. + " where t1.pk_id= #{eqId} and st_dwithin(t.geom :: geography,t1.geom :: geography,100000 ) order by dist "
  5. + "</script>";
  6. /**
  7. * 查询地震100公里范围内的风景区列表
  8. * @param eqId
  9. * @return 地震发生地点100公里范围内的景区
  10. */
  11. @Select(FIND_LIST_BY_EARTHID)
  12. List<ScenicSpotDistVo> findListByEarthId(@Param("eqId") Long eqId);

2、控制层设计与实现

         业务层比较简单,不进行详细说明。在这个实例当中,业务层的实现比较简单。这里将控制层的代码实现进行说明。这里仅实现页面的跳转和一个ajax接口,关键代码如下:

  1. //跳转附近风景区页面,用get请求
  2. @RequiresPermissions("ceiceq:info:nearbyss")
  3. @GetMapping("/nearbyscenicspot/{pkId}")
  4. public String nearbyScenicSpot(@PathVariable("pkId")Long pkId,ModelMap mmap){
  5. mmap.put("pkId", pkId);
  6. CeicEarthquake earthQuake = ceicEarthQuakeService.getById(pkId);
  7. mmap.put("earthQuake", earthQuake);
  8. List<ScenicSpotDistVo> dataList = scenicSpotService.findListByEarthId(pkId);
  9. mmap.put("dataList", dataList);
  10. return prefix + "/nearbyscenicspot";
  11. }
  12. /**
  13. * 获取附近风景区列表数据,用post
  14. * @param pkId
  15. * @return
  16. */
  17. @PostMapping("/nearbyscenicspot/{pkId}")
  18. @ResponseBody
  19. public AjaxResult nearbyScenicSpot(@PathVariable("pkId")Long pkId){
  20. AjaxResult ar = AjaxResult.success();
  21. List<ScenicSpotDistVo> dataList = scenicSpotService.findListByEarthId(pkId);
  22. ar.put("data", dataList);
  23. return ar;
  24. }

        以上代码即给出了后台Java实现的关键代码。通过以上代码即完成了空间数据分析查询接口开发。下面通过Leaflet组件来进行地图可视化开发。

三、Leaflet地图开发

        本小节主要讲解如何使用Leaflet进行空间可视化展示开发。关于Leaflet的相关知识不再赘述,这里提供关键代码:

1、地震震中位置展示

          在进行地震百公里风景区可视化展示时,首先需要对震中位置进行展示。关键的代码如下所示。

  1. var lon = [[${earthQuake.epiLon}]];
  2. var lat = [[${earthQuake.epiLat}]];
  3. var cityInfo = [[${earthQuake.locationC}]];
  1. //矢量文本标签渲染器
  2. var canvasLabel = new L.CanvasLabel({
  3. defaultLabelStyle: {
  4. collisionFlg: true,
  5. scale: 1.2,
  6. strokeStyle: "white",
  7. fillStyle: "#fff",
  8. lineWidth:15
  9. }
  10. });
  1. $(function() {
  2. var marker = L.circleMarker(new L.LatLng(lat, lon), {radius: 8,
  3. labelStyle: {
  4. text: cityInfo,
  5. rotation: 0,
  6. zIndex: 2,
  7. strokeStyle :"red"
  8. },
  9. color : "red"
  10. }).addTo(mymap);
  11. //展示距离
  12. showDistance();
  13. });

2、百公里风景区列表展示

        关键代码如下:

  1. function showDistance(){
  2. $.ajax({
  3. type:"post",
  4. url:prefix + "/nearbyscenicspot/" + [[${pkId + ''}]],
  5. dataType:"json",
  6. cache:false,
  7. processData:false,
  8. success:function(result){
  9. if(result.code == web_status.SUCCESS){
  10. var strokeStyleSet = "green";
  11. for(var i=0;i<result.data.length;i++){
  12. var dataInfo = result.data[i];
  13. var dist = dataInfo.dist;
  14. if(parseFloat(dist) <= 30000){
  15. strokeStyleSet = "red";
  16. }
  17. if(parseFloat(dist) > 30000 && parseFloat(dist) <= 60000 ){
  18. strokeStyleSet = "orange";
  19. }
  20. if(parseFloat(dist) >= 60000){
  21. strokeStyleSet = "green";
  22. }
  23. var _dist = parseFloat(dataInfo.dist / 1000).toFixed(2);
  24. var content = "<strong>风景区名称:</strong>"+dataInfo.name + "<br/><strong>震中位置:</strong>"+ cityInfo;
  25. content += "<br/><strong>风景区级别:</strong>"+dataInfo.level + "<br/><strong>距离(千米):</strong>"+_dist;
  26. var marker = L.circleMarker(new L.LatLng(dataInfo.lat, dataInfo.lon), {radius: 8,labelStyle: {
  27. text: dataInfo.name,
  28. rotation: 0,
  29. zIndex: i,
  30. strokeStyle :strokeStyleSet
  31. },
  32. color : strokeStyleSet
  33. }).addTo(mymap);
  34. marker.bindPopup(content);
  35. L.polyline(
  36. [
  37. [
  38. [lat, lon],[dataInfo.lat, dataInfo.lon]]], {
  39. labelStyle: {
  40. text: _dist + "千米",
  41. zIndex: 0,
  42. collisionFlg: false,
  43. textAlign:'center',
  44. strokeStyle :strokeStyleSet
  45. },
  46. color : strokeStyleSet
  47. }).addTo(mymap);
  48. }
  49. }
  50. },
  51. error:function(){
  52. $.modal.alertWarning("获取信息失败");
  53. }
  54. });
  55. }

3、风景区列表展示

  1. <table class="table table-bordered white-bg" >
  2. <thead>
  3. <tr>
  4. <th width="50%">风景区名称</th>
  5. <th>风景区级别</th>
  6. <th>距离(公里)</th>
  7. </tr>
  8. </thead>
  9. <tbody>
  10. <tr th:each="data,itemStat:${dataList}">
  11. <td >[[${itemStat.count}]]、[[${data.name}]]</td>
  12. <td>[[${data.level}]]</td>
  13. <td th:text="${#numbers.formatDecimal((data.dist / 1000 ), 1, 2)}"></td>
  14. </tr>
  15. </tbody>
  16. </table>

4、附近风景区展示

        地震点列表及震中位置定位功能示意图

        可以看到,震中位置附近有很多的风景名胜区,其中就有5A级风景区,九寨沟。距离震中最近的还有8公里左右的爱情海景区。30公里范围内还有一个4A级的阿坝州九寨沟县嫩恩桑措旅游景区。完整的列表表单如下所示:

风景区名称风景区级别距离(公里)
1、爱情海景区4A8.21
2、九寨沟风景名胜区5A10.46
3、阿坝州九寨沟县嫩恩桑措旅游景区4A22.90
4、九寨沟县九寨庄园景区3A39.79
5、九寨沟柴门关景区3A39.92
6、九寨县甲勿海景区3A40.48
7、松潘县奇峡沟冰雪欢乐景区3A42.98
8、上磨水乡2A45.16
9、天堂香谷2A46.01
10、岷江源景区3A50.13
11、松潘县川主寺旅游景区4A50.29
12、黄龙国家级风景名胜区5A52.12
13、松潘县松州古城3A64.51
14、文县白马河民俗风情旅游景区4A65.44
15、舟曲县亚哈藏民俗旅游文化生态园景区2A66.19
16、涪阳古镇3A72.53
17、若尔盖县巴西会议红色旅游景区3A77.09
18、舟曲县拉尕山景区4A78.08
19、舟曲县土桥子国家景区3A81.56
20、舟曲特大山洪泥石流灾害纪念园3A82.49
21、舟曲县各皂坝国家景区3A82.96
22、舟曲县翠峰山景区2A84.63
23、迭部县茨日那毛主席旧居景区3A85.71
24、文县天池旅游景区4A85.98
25、武都区朝阳洞旅游景区3A86.05
26、若尔盖县花湖生态旅游区4A86.56
27、舟曲县巴寨沟国家景区3A87.94
28、迭部县俄界景区4A88.51
29、宕昌县山湾梦谷古羌民俗旅游景区3A90.58
30、黄河九曲第一湾4A91.27
31、西部牧场3A93.17
32、阿坝州红原县日干乔景区4A97.69
33、迭部县白云景区3A98.42

四、总结

        以上就是本文的主要内容,本文使用Java开发语言,使用PostGIS空间数据库,构建这样一个空间范围分析模型,输出震中百公里影响景点。将作为下一步的数据分析基础提供数据支撑。通过构建源点位与目标点位的实际距离,构建模型分析的基本要素之一,感兴趣的朋友可以看看本文,了解相关的知识。

        文章通过对空间数据库表的设计以及空间分析查询语句的编写,让大家掌握如何在PostGIS数据库中进行空间分析,最后使用Leaflet组件调用Java服务完成了震中附近风景区列表的分析实战。行文仓促,定有不足之处,不当之处,还请各位专家博主在评论区批评指正,万分感谢。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/871556
推荐阅读
相关标签
  

闽ICP备14008679号