/////////////////////////////////////////////////////////////////////////// // Copyright © 2022 guoshilong. All Rights Reserved. // 模块描述:洪水淹没分析 /////////////////////////////////////////////////////////////////////////// define(['dojo/_base/declare', 'dojo/_base/lang', 'dojo/_base/array', 'dojo/_base/html', "dojo/topic", 'jimu/BaseWidget', 'dojo/on', 'dstore/Memory', 'dstore/Trackable', 'dgrid/Grid', 'dgrid/Keyboard', 'dgrid/Selection', 'dstore/RequestMemory', 'dgrid/test/data/createSyncStore', "libs/echarts/v4/echarts.min", 'libs/layer/layer.js', 'libs/turf/turf.min.js'], function (declare, lang, array, html, topic, BaseWidget, on, Memory, Trackable, Grid, Keyboard, Selection, RequestMemory, createSyncStore, echarts, layer, turf) { return declare([BaseWidget], { baseClass: 'jimu-widget-FloodAnalysis', name: 'FloodAnalysis', //人员数据点位 peoplePositionArray: [], peoplePositionEntity:[], //绘制多边形的顶点经纬度 polygonPositionArray: [], startup: function startup() { // 数组用于存放添加点的Id删除实体点的时候会用到 var pointId = []; // 鼠标事件 var waterEntity; // 点击绘制按钮开始绘制 var that = this; var yanmo; var flag = false; var flagScend = false; // 海拔 var altitude = []; var drawingMode = 'polygon'; var activeShape; var boildOne = null; var boildTwo = null; var boildThree = null; // 向三维场景中添加的点的集合 var tempPoints = []; var positions = []; var handler = new Cesium.ScreenSpaceEventHandler(that.map.scene.canvas); var shape; //打开页面,隐藏分析按钮,防止点击绘制区域还未绘制完成时点击分析引发bug $('#dong_start').css('visibility', 'hidden') $('#dong_draw').click(function () { that.deleteEntitys(that, pointId, shape, boildOne, boildTwo, boildThree, waterEntity); //隐藏详情框 that.showDetail(false) that.clearData() $('#dong_time').val(0.5); $('.dong-progress .container #progress_bar').width(0); $('.dong-progress').stop().hide(); $('#dong_echarts').stop().hide(); $('.jimu-widget-AnalysisOfBarrierLake p').stop().hide(); //打开页面,隐藏分析按钮,防止点击绘制区域还未绘制完成时点击分析引发bug $('#dong_start').css('visibility', 'hidden') //if (handler != null) handler.destroy(); handler = new Cesium.ScreenSpaceEventHandler(that.map.scene.canvas); function drawShape(positionData) { if (drawingMode == 'polygon') { shape = that.map.entities.add({ polygon: { hierarchy: positionData, material: Cesium.Color.fromBytes(252, 193, 10, 130) } }); } that.fixedShape = shape; return shape; } clearInterval(yanmo); yanmo = null; positions = []; var polygon = null; var cartesian = null; var floatingPoint; //浮动点 var activeShapePoints = []; var active = null; tempPoints = []; altitude = []; that.map.scene.globe.depthTestAgainstTerrain = false; // handler = new Cesium.ScreenSpaceEventHandler(that.map.scene.canvas); // 取消双击事件-追踪该位置 that.map.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); // 鼠标左键点击事件 handler.setInputAction(function (movement) { // 给鼠标点击增加的点添加随机的ID便于删除 var randomId = Math.random() * 100 + 8 + (Math.random() * 500 + 102); var ray = that.map.camera.getPickRay(movement.position); cartesian = that.map.scene.globe.pick(ray, that.map.scene); if (positions.length == 0) { positions.push(cartesian.clone()); flagScend = true; } // positions.pop(); positions.push(cartesian); // 向三维场景中添加点 var cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 1]); var longitudeString = Cesium.Math.toDegrees(cartographic.longitude); var latitudeString = Cesium.Math.toDegrees(cartographic.latitude); var heightString = cartographic.height; tempPoints.push({ lon: longitudeString, lat: latitudeString, hei: heightString }); altitude.push(Math.round(cartographic.height)); if (Cesium.defined(cartesian)) { if (activeShapePoints.length === 0) { floatingPoint = that.map.entities.add({ // 给实体点添加ID id: '1a-2b-3c', name: '多边形面积', position: positions[positions.length - 1], point: { pixelSize: 6, color: Cesium.Color.RED, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND } }); pointId.push('1a-2b-3c'); activeShapePoints.push(cartesian); var dynamicPositions = new Cesium.CallbackProperty(function () { if (drawingMode === 'polygon') { return new Cesium.PolygonHierarchy(activeShapePoints); } return activeShapePoints; }, false); active = drawShape(dynamicPositions); //绘制动态图 } activeShapePoints.push(cartesian); floatingPoint = that.map.entities.add({ // 给实体点添加ID id: randomId, name: '多边形面积', position: positions[positions.length - 1], point: { pixelSize: 6, color: Cesium.Color.RED, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND } }); pointId.push(randomId); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); // 鼠标移动事件 handler.setInputAction(function (event) { if (positions.length == 0) { that.map.entities.remove(boildOne); var pick1 = new Cesium.Cartesian2(event.endPosition.x, event.endPosition.y); var newPosition = that.map.scene.globe.pick(viewer.camera.getPickRay(pick1), that.map.scene); boildOne = that.map.entities.add({ position: newPosition, label: { show: true, text: '单击开始绘制', font: '16px', pixelOffset: new Cesium.Cartesian2(80, 0), showBackground: true, backgroundColor: Cesium.Color.fromBytes(126, 126, 126, 210) } }); } if (positions.length == 2) { that.map.entities.remove(boildOne); that.map.entities.remove(boildTwo); var pick1 = new Cesium.Cartesian2(event.endPosition.x, event.endPosition.y); var newPosition = that.map.scene.globe.pick(viewer.camera.getPickRay(pick1), that.map.scene); boildTwo = that.map.entities.add({ position: newPosition, label: { show: true, text: '单击增加点', font: '16px', pixelOffset: new Cesium.Cartesian2(80, 0), showBackground: true, backgroundColor: Cesium.Color.fromBytes(126, 126, 126, 210) } }); } if (positions.length > 2) { that.map.entities.remove(boildOne); that.map.entities.remove(boildTwo); that.map.entities.remove(boildThree); var pick1 = new Cesium.Cartesian2(event.endPosition.x, event.endPosition.y); var newPosition = that.map.scene.globe.pick(viewer.camera.getPickRay(pick1), that.map.scene); boildThree = that.map.entities.add({ position: newPosition, label: { show: true, text: '单击增加点,右键点击完成绘制', font: '16px', pixelOffset: new Cesium.Cartesian2(120, 0), showBackground: true, backgroundColor: Cesium.Color.fromBytes(126, 126, 126, 210) } }); } if (Cesium.defined(floatingPoint)) { var pick1 = new Cesium.Cartesian2(event.endPosition.x, event.endPosition.y); var newPosition = that.map.scene.globe.pick(viewer.camera.getPickRay(pick1), that.map.scene); if (Cesium.defined(newPosition)) { floatingPoint.position.setValue(newPosition); activeShapePoints.pop(); activeShapePoints.push(newPosition); } } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); // 鼠标右键点击事件 handler.setInputAction(function (movement) { var cartographic = Cesium.Cartographic.fromCartesian(that.map.scene.globe.pick(that.map.camera.getPickRay(movement.position), that.map.scene)); // 向三维场景中添加点 var longitudeString = Cesium.Math.toDegrees(cartographic.longitude); var latitudeString = Cesium.Math.toDegrees(cartographic.latitude); var heightString = cartographic.height; tempPoints.push({ lon: longitudeString, lat: latitudeString, hei: heightString }); that.polygonPositionArray = tempPoints positions.push(activeShapePoints[activeShapePoints.length - 1]); if (positions.length >= 2) { if (!Cesium.defined(polygon)) { polygon = new PolygonPrimitive(positions); } else { positions.pop(); positions.push(cartesian); } } if (activeShapePoints.length) { activeShape = drawShape(activeShapePoints); //绘制最终图 } // that.map.entities.remove(floatingPoint); that.map.entities.remove(active); that.map.entities.remove(boildOne); that.map.entities.remove(boildTwo); that.map.entities.remove(boildThree); if (!flagScend) return; flagScend = false; altitude.push(Math.round(cartographic.height)); altitude.sort(function (a, b) { if (a > b) return 1; else if (a < b) return -1; else return 0; }); $('#dong_max_height').val(altitude[altitude.length - 1]); $('#dong_min_height').val(altitude[0]); handler.destroy(); flag = true; //结束绘制显示分析按钮 $('#dong_start').css('visibility', 'visible') return; }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); var PolygonPrimitive = function () { function _(positions) { this.options = { name: '多边形', polygon: { hierarchy: [], material: Cesium.Color.WHITE.withAlpha(0) } }; this.positions = positions; this._init(); } _.prototype._init = function () { var _self = this; //实时更新polygon.hierarchy this.options.polygon.hierarchy = new Cesium.CallbackProperty(function () { return new Cesium.PolygonHierarchy(positions); }, false); waterEntity = that.map.entities.add(this.options); that.fixedWaterEntity = waterEntity; }; return _; }(); }); // 点击开始分析按钮,开始分析 $('#dong_start').click(function () { //宽度设置为0 隐藏进度条 $('.dong-progress .container #progress_bar').width(0); //隐藏div $('.dong-progress').stop().hide(); $('#dong_echarts').stop().hide(); $('.jimu-widget-AnalysisOfBarrierLake p').stop().hide(); if (flag != true) { if (yanmo != null) { layer.msg('请等待绘制完成', { time: 1000 }); return; } layer.msg('请先选择绘制区域', { time: 1000 }); return; } // 提取坐标信息 var list = waterEntity.polygon.hierarchy.getValue().positions; // 存放坐标信息,做请求数据使用 var echartRings = [[]]; // 处理坐标信息,将世界坐标转换成经纬度 for (var i = 1; i < list.length; i++) { var cartographic = Cesium.Cartographic.fromCartesian(list[i]); var lat = Cesium.Math.toDegrees(cartographic.latitude); var lng = Cesium.Math.toDegrees(cartographic.longitude); echartRings[0].push([lng, lat]); } that.map.entities.remove(activeShape); // 最高海拔 var maxHet = Number($('#dong_max_height').val()); // 最低海拔 var minHet = Number($('#dong_min_height').val()); // 每秒上升海拔 var time = Number($('#dong_time').val()); // 动态获取最低海拔 $('#dong_min_height').change(function () { minHet = $(this).val(); }); // 总淹没体积 var textArea = parseInt(getArea(tempPoints) * (maxHet - minHet) / 100000); var seriesData = []; var altitude = (maxHet - minHet) / 20; var altitudeHet = 0; // 1秒后开始进入淹没分析 setTimeout(function () { flag = false; if (waterEntity) { that.map.scene.globe.depthTestAgainstTerrain = true; waterEntity.polygon.perPositionHeight = true, waterEntity.polygon.material = Cesium.Color.fromBytes(33, 122, 193, 220); var h = minHet - 50 || altitude[0] - 50; waterEntity.polygon.extrudedHeight = minHet - 50 || altitude[0] - 50; //需要提前设置 不然会全部出现 yanmo = setInterval(function () { h = h + time || 1; if (h >= (maxHet || altitude[altitude.length - 1])) { h = maxHet || altitude[altitude.length - 1]; //给个最大值 waterEntity.polygon.extrudedHeight = h; clearTimeout(yanmo); flag = true; // //显示div // $('.dong-progress').stop().show(); // // 总长度 // var totalWidth = $('.dong-progress .container').width(); // // 过度长度 // var excessiveWidth = totalWidth / 100; // var watchWidth = 0; // // 进度条的定时器 // var proTime = setInterval(function () { // watchWidth += excessiveWidth; // if (watchWidth > totalWidth) { // watchWidth = totalWidth; // } // $('.dong-progress .container #progress_bar').width(watchWidth); // }, 22); return; } waterEntity.polygon.extrudedHeight = h; }, 100); that.showDetail(true) } }, 1000); }); $('#dong_delet').click(function () { that.showDetail(false) that.clearData() that.deleteEntitys(that, pointId, shape, boildOne, boildTwo, boildThree, waterEntity); handler.destroy(); $('.dong-progress .container #progress_bar').width(0); $('.dong-progress').stop().hide(); $('#dong_echarts').stop().hide(); $('.jimu-widget-AnalysisOfBarrierLake p').stop().hide(); //隐藏分析按钮,防止点击绘制区域还未绘制完成时点击分析引发bug $('#dong_start').css('visibility', 'hidden') clearInterval(yanmo); yanmo = null; }); $('#flood-detail-ckxq').click(function () { that.floodAnalysisPopup() }) var radiansPerDegree = Math.PI / 180.0; //角度转化为弧度(rad) var degreesPerRadian = 180.0 / Math.PI; //弧度转化为角度 function getArea(points) { var res = 0; //拆分三角曲面 for (var i = 0; i < points.length - 2; i++) { var j = (i + 1) % points.length; var k = (i + 2) % points.length; var totalAngle = Angle(points[i], points[j], points[k]); var dis_temp1 = distance(positions[i], positions[j]); var 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) { var bearing21 = Bearing(p2, p1); var bearing23 = Bearing(p2, p3); var angle = bearing21 - bearing23; if (angle < 0) { angle += 360; } return angle; } /*方向*/ function Bearing(from, to) { var lat1 = from.lat * radiansPerDegree; var lon1 = from.lon * radiansPerDegree; var lat2 = to.lat * radiansPerDegree; var lon2 = to.lon * radiansPerDegree; var 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) { var point1cartographic = Cesium.Cartographic.fromCartesian(point1); var point2cartographic = Cesium.Cartographic.fromCartesian(point2); /**根据经纬度计算出距离**/ var geodesic = new Cesium.EllipsoidGeodesic(); geodesic.setEndPoints(point1cartographic, point2cartographic); var s = geodesic.surfaceDistance; //返回两点之间的距离 s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2)); return s; } this.closeDeleteEntity = function () { handler.destroy(); that.deleteEntitys(that, pointId, shape, boildOne, boildTwo, boildThree, waterEntity); }; }, onOpen: function onOpen() { //面板打开的时候触发 (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'); //设置地图初始位置 this.map.camera.setView({ destination: Cesium.Cartesian3.fromDegrees(116.016905, 25.884684, 10000), }); }, onClose: function onClose() { this.closeDeleteEntity(); //面板关闭的时候触发 (when this panel is closed trigger) $('.dong-progress .container #progress_bar').width(0); $('.dong-progress').stop().hide(); $('#dong_echarts').stop().hide(); $('.jimu-widget-AnalysisOfBarrierLake p').stop().hide(); //隐藏分析按钮,防止点击绘制区域还未绘制完成时点击分析引发bug $('#dong_start').css('visibility', 'hidden') //隐藏详情框 this.showDetail(false) this.peoplePositionEntity.forEach(e=>{ this.map.entities.remove(e) }) this.map.scene.globe.baseColor = Cesium.Color.WHITE; }, onMinimize: function onMinimize() { this.resize(); }, onMaximize: function onMaximize() { this.resize(); }, resize: function resize() { }, destroy: function destroy() { //销毁的时候触发 //todo //do something before this func this.inherited(arguments); }, deleteEntitys: function deleteEntitys(that, pointId, shape, boildOne, boildTwo, boildThree, waterEntity) { if (pointId !== []) { for (var i = 0; i < pointId.length; i++) { that.map.entities.removeById(pointId[i]); } pointId = []; } that.map.entities.remove(shape); that.map.entities.remove(boildOne); that.map.entities.remove(boildTwo); that.map.entities.remove(boildThree); if (waterEntity != null) { that.map.entities.removeById(waterEntity._id); } }, //添加点 addPoint: function () { const url = './widgets/FloodAnalysis/data.json' this.getJsonUrl(url) }, //获取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, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND }, }); self.peoplePositionEntity.push(temp) } } }); }, //是否显示详情框 showDetail: function (show) { //显示详情 if (show) { $('.flood-detail').show() } else { $('.flood-detail').hide() } }, //洪水分析弹窗 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 inPolygonStr = JSON.stringify(inPolygon) var url = './corelib/common/popup/floodAnalysis.html'; var urlEvaluate = './corelib/common/popup/evaluateAnalysis.html' var top = ($(window).height() - 750) / 2; var left = ($(window).width() - 1300 - 340) / 2 + 340; layer.open({ title: '评估分析', type: 2, maxmin: false, //开启最大化最小化按钮 area: ['1100px', '800px'], skin: 'floodAnalysis', offset: [top, left], content: urlEvaluate + "?data=" + encodeURIComponent(inPolygonStr),//使用encodeURIComponent转码,避免中文字符乱码,避免url截取错误 id: "floodAnalysisLayer", closeBtn: 1, }); }, //判断点是否在多边形内部 isPointInPolygon: function (point) { //获取经纬度 var polygonPosition = this.polygonPositionArray //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) }, //清除框内数据 clearData:function (){ $('#dong_max_height').val(0); $('#dong_min_height').val(0); }, }); });