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