From d41024c55f6b7515d3880457d83be99fbbcf6622 Mon Sep 17 00:00:00 2001
From: guoshilong <123456>
Date: Mon, 06 Feb 2023 10:46:44 +0800
Subject: [PATCH] 水文水环境分析-洪水淹没:画线进行分析修改为画多边形进行分析
---
widgets/FloodAnalysis/Widget copy.js | 469 +++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 365 insertions(+), 104 deletions(-)
diff --git a/widgets/FloodAnalysis/Widget copy.js b/widgets/FloodAnalysis/Widget copy.js
index f33de68..4762816 100644
--- a/widgets/FloodAnalysis/Widget copy.js
+++ b/widgets/FloodAnalysis/Widget copy.js
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////
-// Copyright © 2020 zhongsong. All Rights Reserved.
-// 模块描述:河流水面线分析
+// Copyright © 2022 guoshilong. All Rights Reserved.
+// 模块描述:洪水淹没分析
///////////////////////////////////////////////////////////////////////////
define([
'dojo/_base/declare',
@@ -10,19 +10,25 @@
'dojo/topic',
'jimu/BaseWidget',
'./Tooltip-div',
- './DynamicDraw'
+ './FloodAnalysis',
+ 'libs/layer/layer.js',
+ 'libs/turf/turf.min.js'
],
function (declare,
lang,
array,
html,
topic,
- BaseWidget
+ BaseWidget,
+ tooltip,
+ flood,
+ layer,
+ turf,
) {
return declare([BaseWidget], {
- baseClass: 'jimu-widget-DynamicRiver',
- name: 'DynamicRiver',
- riverWidth: 200,
+ baseClass: 'jimu-widget-FloodAnalysis',
+ name: 'FloodAnalysis',
+ riverWidth: 300,
riverHeight: 10,
speed: 10,
positions: [],
@@ -30,8 +36,13 @@
riverPrimitive: null,
material: null,
drawingPolyline: null,
- // 增加waterData 用来存放列表数据
- waterData: null,
+ //绘制的多边形数组
+ polygonCartesianArray:[],
+ //canvas转换后的图片
+ canvasImage:null,
+ //房屋人口
+ peoplePositionArray:[],
+ myWaterPrimitive:null,
startup: function () {
this.inherited(arguments);
var self = this;
@@ -39,106 +50,82 @@
this.map.scene.globe.depthTestAgainstTerrain = true;
//取消双击事件
this.map.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
-
-
- // 点击地图上绘制水面线,并且显示水面线详细数据
- $('.water-analysis-content').on('click', '.content-right', function (e) {
-
- var dataIndex = $(e.target).parent().index();
- var cartesians = [];
-
- self.map.camera.flyTo({
- destination: Cesium.Cartesian3.fromDegrees(Number(self.waterData[dataIndex].zb[0].jd), Number(self.waterData[dataIndex].zb[0].wd), 5000),
- easingFunction: Cesium.EasingFunction.QUADRACTIC_IN_OUT
+ //绘制水面事件
+ $("#flood_hzsm_headtab").click(function () {
+ DrawDynamicClampGround.startDrawingPolyline(self.map, function (cartesians) {
+ if (self.drawingPolyline != undefined)
+ self.map.entities.remove(self.drawingPolyline);
+ var lineOpts = {
+ polyline: {
+ positions: cartesians,
+ clampToGround: true,
+ width: 3,
+ color: "#279a9a"
+ }
+ };
+ self.drawingPolyline = self.map.entities.add(lineOpts);
+ cartesians.splice(cartesians.length - 1, cartesians.length);
+ self.drawLines(cartesians);
+ self.movehandLer()
+ self.showDetail(true)
});
+ });
- $('.dynamicriver-result-sname').text(self.waterData[dataIndex].sname);
- $('.dynamicriver-result-ctime').text(self.waterData[dataIndex].ctime.substring(0, 10));
- $('.dynamicriver-result-ltime').text(self.waterData[dataIndex].ltime.substring(0, 10));
-
- if (e.target.nodeName == 'SPAN') {
- $('.dynamicriver-result').stop().show();
- $('.dynamicriver-main').stop().hide();
- }
-
-
- // $('.jimu-widget-DynamicRiver .dynamicriver-result').fadeIn();
- self.waterData[dataIndex].zb.forEach(function (item, index) {
- cartesians.push(Cesium.Cartesian3.fromDegrees(item.jd, item.wd, item.elevation))
- })
- // self.drawLines(cartesians);
- // DrawDynamicClampGround.startDrawingPolyline(self.map, function (cartesians) {
- if (self.drawingPolyline != undefined)
- self.map.entities.remove(self.drawingPolyline);
- var lineOpts = {
- polyline: {
- positions: cartesians,
- clampToGround: true,
- width: 3,
- color: "#279a9a"
- }
- };
- self.drawingPolyline = self.map.entities.add(lineOpts);
- cartesians.splice(cartesians.length - 1, cartesians.length);
- self.drawLines(cartesians);
- // });
-
- })
-
-
- $('.close-dynamicriver').click(function () {
- $('.jimu-widget-DynamicRiver').stop().hide();
- })
-
- // 关闭详细信息事件
- $('.close-dynamicriver-result').click(function () {
- $('.dynamicriver-result').stop().hide();
- $('.dynamicriver-main').stop().show();
-
+ $('#flood_qcsmx_headtab').click(function () {
self.map.entities.remove(self.drawingPolyline);
self.map.scene.primitives.remove(self.riverPrimitive);
-
- self.map.camera.flyTo({
- destination: Cesium.Cartesian3.fromDegrees(115.257787, 25.885506, 549263.35),
- easingFunction: Cesium.EasingFunction.QUADRACTIC_IN_OUT
- });
+ self.showDetail(false)
})
+ // $("#thematic_hlkd_headtab").change(function (e) {
+ // self.riverWidth = Number($(this).val());
+ // self.resetPos();
+ // });
+ $("#flood_analysis_sw_headtab").change(function (e) {
+ self.riverHeight = Number($(this).val());
+ self.resetPos();
+ });
+ // $("#thematic_sls_headtab").change(function (e) {
+ // self.speed = Number($(this).val());
+ // self.resetPos();
+ // });
+ //
+ // $("#thematic_smsz_headtab").click(function () {
+ // self.offsetHeight(Number($("#thematic_bhz_headtab").val()), 5);
+ // });
+ //
+ // $("#thematic_smxj_headtab").click(function () {
+ // self.offsetHeight(-Number($("#thematic_bhz_headtab").val()), 5);
+ // });
+ $('#flood-detail-ksfx').click(function () {
+ self.floodAnalysisPopup()
+ })
-
- /*for(var e = [
- [115.907543, 30.441563, 541.47],
- [115.904337, 30.439412, 491.79],
- [115.900612, 30.438483, 449.11],
- [115.896375, 30.439377, 388.29],
- [115.890586, 30.442215, 345.94],
- [115.876946, 30.444641, 292.73]
- ], r = [], i = 0; i < e.length; i++) r.push(Cesium.Cartesian3.fromDegrees(e[i][0], e[i][1], e[i][2]));
-
- this.positions = r;
-
- this.init();*/
},
+
init: function () {
this.prepareVertex();
if (this.sideRes) {
this.material = this.prepareMaterial();
this.riverPrimitive && this.map.scene.primitives.remove(this.riverPrimitive);
this.riverPrimitive = this.createPrimitive();
- this.map.scene.primitives.add(this.riverPrimitive);
+ this.myWaterPrimitive = this.map.scene.primitives.add(this.riverPrimitive);
}
},
+
prepareVertex: function () {
if (this.positions.length > 0) {
this.sideRes = this._lines2Plane(this.positions, this.riverWidth, this.riverHeight);
}
},
+
setPositions: function (e) {
this.positions = e;
this.init();
},
+
resetPos: function () {
this.sideRes = this._lines2Plane(this.positions, this.riverWidth, this.riverHeight);
if (this.sideRes) {
@@ -148,14 +135,16 @@
this.map.scene.primitives.add(this.riverPrimitive);
}
},
+
drawLines: function (r) {
this.setPositions(r);
},
+
prepareMaterial: function () {
var e = new Cesium.Material({
fabric: {
uniforms: {
- image: "widgets/DynamicRiver/images/movingRiver.png",
+ image: "widgets/ThematicDynamicRiver/images/movingRiver.png",
alpha: 0.5,
moveVar: new Cesium.Cartesian3(50, 1, 100),
reflux: -1,
@@ -168,6 +157,7 @@
});
return e
},
+
createPrimitive: function () {
var t = new Float64Array(this.sideRes.vertexs),
i = new Cesium.GeometryAttributes;
@@ -201,9 +191,11 @@
})
})
},
+
offsetHeight: function (height, time) {
this.startDH(height, time)
},
+
startDH: function (height, time) {
if (height && time && this.riverPrimitive) {
for (var i = this, r = 0, n = height / (20 * time), o = this.sideRes.self, s = new Cesium.Cartesian3, l = 0, u = o.length; l < u; l++) {
@@ -221,6 +213,7 @@
}, this.map.clock.onTick.addEventListener(this.dhEvent)
}
},
+
//水面线转成水面
_lines2Plane: function (positions, width, height) {
function n(point, height) {
@@ -302,6 +295,17 @@
D.push(v[H].x), D.push(v[H].y), D.push(v[H].z), k.push(B.high.x), k.push(B.high.y), k.push(B.high.z), A.push(B.low.x), A.push(B.low.y), A.push(B.low.z), O.push(0, 0)
}
+ this.polygonCartesianArray = []
+ for (let i = 0; i < y.length; i++) {
+ this.polygonCartesianArray.push(y[i])
+ }
+ for (let i = 0; i < v.length; i++) {
+ this.polygonCartesianArray.push(v[i])
+ }
+ //计算polygon面积
+ this.getPolygonArea(this.getPositionArray(this.polygonCartesianArray),this.polygonCartesianArray)
+
+
return {
left: v,
right: y,
@@ -313,34 +317,29 @@
uvs: new Float32Array(O)
}
},
+
onOpen: function () {
//面板打开的时候触发 (when open this panel trigger)
+ this.map.scene.globe.baseColor = Cesium.Color.BLACK;
+ //初始化点
+ this.addPoint()
+ //切换底图
+ $($('div.cesium-viewer').find('.cesium-baseLayerPicker-choices')[0]).children('div:eq(0)').trigger('click');
+ $($('div.cesium-viewer').find('.cesium-baseLayerPicker-choices')[1]).children('div:eq(2)').trigger('click');
- // 发送请求获得到水面线列表基本数据
- var self = this;
- $.ajax({
- url: 'http://localhost:82/blade-ycreal/waterline/querylist',
- dataType: 'json',
- type: 'get',
- success: function (data) {
- self.waterData = data.data;
- var lidom = null;
- var contentLeft = null;
- var contentRight = null;
- for (var i = 0; i < data.data.length; i++) {
- lidom = $('<li> </li>');
- contentLeft = $("<span class='content-left'></span>").text(data.data[i].sname);
- contentRight = $("<span class='content-right'></span>");
- lidom.prepend(contentLeft);
- lidom.append(contentRight);
- $('.water-analysis-content').append(lidom);
- }
- }
- })
+ this.map.camera.setView({
+ destination: Cesium.Cartesian3.fromDegrees(116.016905,25.884684, 10000),
+ });
+
+ this.showDetail(false)
+
},
onClose: function () {
//面板关闭的时候触发 (when this panel is closed trigger)
+ this.map.entities.remove(this.drawingPolyline);
+ this.map.scene.primitives.remove(this.riverPrimitive);
+ this.map.entities.removeAll()
},
onMinimize: function () {
@@ -360,7 +359,269 @@
//todo
//do something before this func
this.inherited(arguments);
+ },
+
+ //Cartesian3转换为经纬度
+ getPositionArray:function (cartesiansArray){
+ var positionArray = []
+
+ if (cartesiansArray.length>0){
+ for (let i = 0; i < cartesiansArray.length; i++) {
+ //获取的对象中的经纬度为弧度
+ let cartographic= Cesium.Cartographic.fromCartesian(cartesiansArray[i])
+ //弧度转换
+ let longitude = Cesium.Math.toDegrees(cartographic.longitude)
+ let latitude = Cesium.Math.toDegrees(cartographic.latitude)
+ let height = cartographic.height
+ positionArray.push({
+ lon:longitude,
+ lat:latitude,
+ hei:height,
+ })
+ }
+ }
+ return positionArray
+ },
+
+ //获取多边形面积
+ getPolygonArea:function (points,positions){
+ let radiansPerDegree = Math.PI / 180.0;//角度转化为弧度(rad)
+ let degreesPerRadian = 180.0 / Math.PI;//弧度转化为角度
+
+ //计算多边形面积
+ function getArea(points) {
+ let res = 0;
+ //拆分三角曲面
+
+ for (let i = 0; i < points.length - 2; i++) {
+ let j = (i + 1) % points.length;
+ let k = (i + 2) % points.length;
+ let totalAngle = Angle(points[i], points[j], points[k]);
+ let dis_temp1 = distance(positions[i], positions[j]);
+ let dis_temp2 = distance(positions[j], positions[k]);
+ res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle)) ;
+ }
+
+
+ return (res/1000000.0).toFixed(4);
+ }
+
+ /*角度*/
+ function Angle(p1, p2, p3) {
+ let bearing21 = Bearing(p2, p1);
+ let bearing23 = Bearing(p2, p3);
+ let angle = bearing21 - bearing23;
+ if (angle < 0) {
+ angle += 360;
+ }
+ return angle;
+ }
+ /*方向*/
+ function Bearing(from, to) {
+ let lat1 = from.lat * radiansPerDegree;
+ let lon1 = from.lon * radiansPerDegree;
+ let lat2 = to.lat * radiansPerDegree;
+ let lon2 = to.lon * radiansPerDegree;
+ let angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
+ if (angle < 0) {
+ angle += Math.PI * 2.0;
+ }
+ angle = angle * degreesPerRadian;//角度
+ return angle;
+ }
+
+ //计算距离
+ function distance(point1,point2){
+ let point1cartographic = Cesium.Cartographic.fromCartesian(point1);
+ let point2cartographic = Cesium.Cartographic.fromCartesian(point2);
+ /**根据经纬度计算出距离**/
+ let geodesic = new Cesium.EllipsoidGeodesic();
+ geodesic.setEndPoints(point1cartographic, point2cartographic);
+ let s = geodesic.surfaceDistance;
+ //console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));
+ //返回两点之间的距离
+ s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
+ return s;
+ }
+
+ console.log(getArea(points)+"平方公里","777")
+
+ },
+
+ //鼠标事件
+ movehandLer: function movehandLer() {
+ // 取消默认双击事件
+ this.map.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
+ // 获取鼠标事件
+ this.mountainHandler = new Cesium.ScreenSpaceEventHandler(this.map.scene.canvas);
+ // 给鼠标左键添加事件函数
+ // this.mountainHandler.setInputAction(lang.hitch(this, this.clickHand), Cesium.ScreenSpaceEventType.LEFT_CLICK);
+ },
+
+ //点击事件
+ clickHand:function (click){
+ var pickedObjects = this.map.scene.pick(click.position);
+ if (pickedObjects && pickedObjects.primitive instanceof Cesium.Primitive) {
+ // this.canvasToImage()
+ this.floodAnalysisPopup()
+ }
+ },
+
+ //洪水分析弹窗
+ floodAnalysisPopup:function (){
+ var self = this
+ var inPolygon = []
+ for (let i = 0; i < this.peoplePositionArray.length; i++) {
+ let isIn = this.isPointInPolygon(this.peoplePositionArray[i])
+ if (isIn){
+ inPolygon.push(this.peoplePositionArray[i])
+ }
+ }
+ var jsonStr = JSON.stringify(inPolygon)
+
+ var url = './corelib/common/popup/floodAnalysis.html';
+ var urlEvaluate = './corelib/common/popup/evaluateAnalysis.html'
+ var top = ($(window).height() - 600) / 2;
+ var left = ($(window).width() - 1300 - 340) / 2 + 340;
+ layer.open({
+ title:'评估分析',
+ type: 2,
+ maxmin: false, //开启最大化最小化按钮
+ area: ['1100px', '600px'],
+ skin: 'floodAnalysis',
+ offset: [top, left],
+ content: urlEvaluate + "?data=" + encodeURIComponent(jsonStr),//使用encodeURIComponent转码,避免中文字符乱码,避免url截取错误
+ id: "floodAnalysisLayer",
+ closeBtn: 1,
+ //把父页面数据传递给子弹窗并渲染
+ success: function(layero, index) {
+ //绑定父子之间的关系,用于数据传递,缺少则无法传递
+ var body = layer.getChildFrame("body",index);
+ //得到iframe页的窗口对象
+ var iframeWin = window[layero.find('iframe')[0]['name']];
+ // //渲染子页面中的img
+ // iframeWin.$('#canvasImage')[0].src = self.canvasImage;
+ var table = ""
+ var house = 0
+ var people = 0
+ var area = 0
+ var money = 0
+ for (let i = 0; i < inPolygon.length; i++) {
+ table += '<tr>'+
+ '<td><div>' + inPolygon[i].name + '</div></td>' +
+ '<td><div>' + inPolygon[i].house + '</div></td>' +
+ '<td><div>' + inPolygon[i].people + '</div></td>' +
+ '<td><div>' + inPolygon[i].area + '</div></td>' +
+ '<td><div>' + inPolygon[i].money + '</div></td>' +
+ '</tr>'
+
+ house += inPolygon[i].house
+ people += inPolygon[i].people
+ area += inPolygon[i].area
+ money += inPolygon[i].money
+ }
+ iframeWin.$('#evaluate-tbody').html(table)
+
+ iframeWin.$(".house").html(house + '户')
+ iframeWin.$(".people").html(people + '人')
+ iframeWin.$(".area").html(area + 'km²')
+ iframeWin.$(".money").html(money + '万元')
+
+ },
+ });
+ },
+
+ //添加点
+ addPoint:function (){
+ const url = './widgets/FloodAnalysis/data.json'
+ this.getJsonUrl(url)
+ },
+
+ showDetail:function(show){
+ //显示详情
+ if (show){
+ $('.flood-detail').show()
+ }else {
+ $('.flood-detail').hide()
+ }
+ },
+
+ //判断点是否在多边形内部
+ isPointInPolygon : function (point){
+ //获取经纬度
+ var polygonPosition = this.getPositionArray(this.polygonCartesianArray)
+ //turf要求首尾闭合
+ var turfPolygon = []
+ polygonPosition.forEach(e=>{
+ var temp = [e.lon,e.lat]
+ turfPolygon.push(temp)
+ })
+ turfPolygon.push([polygonPosition[0].lon,polygonPosition[0].lat])
+
+ var poly= turf.polygon([turfPolygon])
+ var pt = turf.point([point.LGTD,point.LTTD])
+ return turf.booleanPointInPolygon(pt,poly)
+ },
+
+ //获取json对象,测试用
+ getJsonUrl: function getJsonUrl(url) {
+ var self = this;
+ $.ajax({
+ url: url,
+ dataType: 'json',
+ type: 'get',
+ success: function success(data) {
+ const viewer = self.map
+ var dataArray = data.data
+ dataArray.forEach(e=>{
+ e.house = Number(e.house)
+ e.people = Number(e.people)
+ e.area = Number(e.area)
+ e.money = Number(e.money)
+ })
+ self.peoplePositionArray = []
+ self.peoplePositionArray = dataArray
+ for (let i = 0; i < dataArray.length; i++) {
+ var temp = viewer.entities.add({
+ position: Cesium.Cartesian3.fromDegrees(dataArray[i].LGTD, dataArray[i].LTTD),
+ point: {
+ color: Cesium.Color.RED,
+ pixelSize: 16,
+ //防止地形遮挡住点
+ disableDepthTestDistance: Number.POSITIVE_INFINITY
+ },
+ });
+ }
+ }
+ });
+ },
+
+ //canvas转换为image
+ canvasToImage:function (){
+ var canvas = this.map.scene.canvas
+ let image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
+ this.canvasImage = image
+ // //导出看效果
+ // let link = document.createElement("a");
+ // let blob = this.dataURLtoBlob(image);
+ // let objurl = URL.createObjectURL(blob);
+ // link.download = "scene.png";
+ // link.href = objurl;
+ // link.click();
+ },
+
+ dataURLtoBlob:function (dataurl) {
+ let arr = dataurl.split(','),
+ mime = arr[0].match(/:(.*?);/)[1],
+ bstr = atob(arr[1]),
+ n = bstr.length,
+ u8arr = new Uint8Array(n);
+ while (n--) {
+ u8arr[n] = bstr.charCodeAt(n);
}
+ return new Blob([u8arr], { type: mime });
+ },
+
});
});
--
Gitblit v1.9.3