/**
|
* 水淹没分析
|
*/
|
(function (window) {
|
'use strict';
|
|
function define_CesiumFlood() {
|
//Main object
|
var CesiumFlood = {};
|
|
CesiumFlood.viewer = null;
|
CesiumFlood.isTerrain = true;
|
CesiumFlood.handler = null;
|
CesiumFlood.tempEntities = [];
|
CesiumFlood.polygonEntities = [];
|
CesiumFlood.linePositionList = [];
|
CesiumFlood.tempPoints = [];
|
CesiumFlood.extrudedHeight = null;
|
CesiumFlood.height_max = null;
|
CesiumFlood.height_min = null;
|
CesiumFlood.speed = null;
|
CesiumFlood.map_type = null;
|
CesiumFlood.polygon_degrees = [
|
110.15, 34.56,
|
110.25, 34.56,
|
110.25, 34.54,
|
110.15, 34.54
|
];
|
|
// var CesiumFlood = {
|
// viewer = null,
|
// isTerrain = null,
|
// handler = null,
|
// tempEntities = [],
|
// polygonEntities = [],
|
// linePositionList = [],
|
// tempPoints = [],
|
// extrudedHeight = height_min,
|
// height_max = null,
|
// height_min = null,
|
// speed = null,
|
// map_type = null,
|
// polygon_degrees = [
|
// 115.8784, 40.0198,
|
// 115.9473, 40.0381,
|
// 115.9614, 40.0073,
|
// 115.9042, 39.9912
|
// ]
|
// };
|
|
CesiumFlood.create = function (viewer, isTerrain, height_max, height_min, speed, map_type) {
|
this.viewer = viewer;
|
this.isTerrain = isTerrain;
|
this.extrudedHeight = height_min;
|
this.height_max = height_max;
|
this.height_min = height_min;
|
this.speed = speed;
|
this.map_type = map_type;
|
this.initViewStatus(this.viewer);
|
this.addDisListener();
|
};
|
|
CesiumFlood.initViewStatus = function (viewer) {
|
var scene = viewer.scene
|
scene.globe.depthTestAgainstTerrain = true
|
// viewer.camera.flyTo({
|
// // scene.camera.setView({
|
// // 摄像头的位置
|
// destination: Cesium.Cartesian3.fromDegrees(110.2, 34.55, 5000.0),
|
// orientation: {
|
// heading: Cesium.Math.toRadians(0.0),//默认朝北0度,顺时针方向,东是90度
|
// pitch: Cesium.Math.toRadians(-90), //默认朝下看-90,0为水平看,
|
// roll: Cesium.Math.toRadians(0)//默认0
|
// }
|
// });
|
viewer.skyAtmosphere = false
|
};
|
|
CesiumFlood.getHeatMap = function (viewer, data = null, bounds = null, opts = null) {
|
var heatMap = window.CesiumHeatmap.create(
|
viewer, // your cesium viewer
|
bounds, // bounds for heatmap layer
|
opts ? opts : {
|
backgroundColor: "rgba(255,0,0,0)",
|
radius: 50,
|
maxOpacity: .93,
|
minOpacity: 0,
|
blur: .75
|
}
|
);
|
this.heatMap = heatMap
|
let values = data.map(d => d.value)
|
let valueMin = Math.min(...values);
|
let valueMax = Math.max(...values);
|
|
// add data to heatmap
|
heatMap.setWGS84Data(valueMin, valueMax, data);
|
// 因为大片都是空的啊,所以只是一小块数据,一个坑,如果范围小,会导致绘制出错
|
viewer.zoomTo(heatMap._layer);
|
};
|
|
CesiumFlood.heatMapShow = function (s) {
|
this.heatMap.show(s);
|
};
|
|
CesiumFlood.heatMapUpdate = function (data) {
|
let values = data.map(d => d.value)
|
let valueMin = Math.min(...values);
|
let valueMax = Math.max(...values);
|
|
// add data to heatmap
|
this.heatMap.setWGS84Data(valueMin, valueMax, data);
|
// 因为大片都是空的啊,所以只是一小块数据
|
this.viewer.zoomTo(this.heatMap._layer);
|
};
|
|
CesiumFlood.getPoints = function (xmin, xmax, ymin, ymax) {
|
const x_count = 10
|
const y_count = 10
|
let cartesians = new Array(x_count * y_count);
|
const x_d = (xmax - xmin) / x_count
|
for (var i = 0; i < x_count; ++i) {
|
const start_pt = { x: xmin + i * x_d, y: ymax }
|
const end_pt = { x: xmin + i * x_d, y: ymin }
|
for (let j = 0; j < y_count; j++) {
|
const offset = j / (y_count - 1);
|
const x = Cesium.Math.lerp(start_pt.x, end_pt.x, offset);
|
const y = Cesium.Math.lerp(start_pt.y, end_pt.y, offset);
|
cartesians[j + i * y_count] = Cesium.Cartographic.fromDegrees(x, y);
|
}
|
}
|
return cartesians
|
};
|
|
CesiumFlood.getHeights = function (cartesians, extrudedHeight, callback) {
|
var terrainProvider = new Cesium.createWorldTerrain({
|
requestVertexNormals: true
|
})
|
// 根据地形计算某经纬度点的高度
|
var promise = Cesium.sampleTerrainMostDetailed(terrainProvider, cartesians);
|
Cesium.when(promise, function (updatedPositions) {
|
|
let positions = updatedPositions.filter(d => {
|
const cartographic = d
|
if (cartographic) {
|
const h_d = extrudedHeight - cartographic.height
|
return h_d > 0
|
}
|
})
|
positions = positions.map(d => {
|
const cartographic = d
|
let h = extrudedHeight - cartographic.height
|
return {
|
x: Cesium.Math.toDegrees(cartographic.longitude),
|
y: Cesium.Math.toDegrees(cartographic.latitude),
|
value: h
|
}
|
|
})
|
|
if (callback) {
|
|
callback(positions)
|
}
|
});
|
};
|
|
|
|
CesiumFlood.addDisListener = function () {
|
let viewer = this.viewer
|
let scene = viewer.scene
|
let linePositionList = this.linePositionList
|
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
|
this.handler = new Cesium.ScreenSpaceEventHandler(scene.canvas)
|
// 绘制线
|
this.drawLine(linePositionList)
|
// this.loadGrandCanyon()
|
// 绘制面
|
if (this.map_type) {
|
this.drawPoly(this.polygon_degrees)
|
} else {
|
// 得到插值网格
|
const bounds = {
|
west: 115.8784,
|
east: 115.9614,
|
south: 39.9912,
|
north: 40.0381
|
}
|
|
const positions_cartesian = this.getPoints(bounds.east, bounds.west, bounds.south, bounds.north)
|
this.getHeights(positions_cartesian, this.extrudedHeight, (d) => {
|
CesiumHeatmap.create(this.viewer, d, bounds);
|
})
|
}
|
|
};
|
CesiumFlood.reDraw = function () {
|
this.tempPoints = []
|
this.linePositionList.length = 0
|
this.areaPositionList.length = 0
|
for (let entity of this.tempEntities) {
|
this.viewer.entities.remove(entity)
|
}
|
this.tempEntities = []
|
};
|
|
CesiumFlood.drawLine = function (linePositionList) {
|
let lineStyle = {
|
width: 2,
|
material: Cesium.Color.CHARTREUSE
|
}
|
|
let entity = this.viewer.entities.add({
|
polyline: lineStyle,
|
})
|
|
entity.polyline.positions = new Cesium.CallbackProperty(function () {
|
return linePositionList
|
}, false)
|
|
this.polygonEntities.push(entity)
|
};
|
|
CesiumFlood.drawPoint = function (point_Cartesian3) {
|
let entity =
|
this.viewer.entities.add({
|
position: point_Cartesian3,
|
point: {
|
pixelSize: 10,
|
color: Cesium.Color.GOLD,
|
// disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
|
}
|
})
|
this.tempEntities.push(entity)
|
};
|
|
|
CesiumFlood.drawPoly = function (degrees) {
|
const that = this
|
let entity =
|
this.viewer.entities.add({
|
polygon: {
|
hierarchy: {},
|
material: new Cesium.Color.fromBytes(64, 157, 253, 100),
|
perPositionHeight: true,
|
|
}
|
})
|
entity.polygon.hierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(degrees))
|
entity.polygon.extrudedHeight = new Cesium.CallbackProperty(() => that.extrudedHeight, false)
|
this.polygonEntities.push(entity)
|
};
|
|
// 世界坐标转经纬坐标
|
CesiumFlood.car3ToLatLon = function (cartesian) {
|
let cartographic = Cesium.Cartographic.fromCartesian(cartesian)
|
let longitudeString = Cesium.Math.toDegrees(cartographic.longitude)
|
let latitudeString = Cesium.Math.toDegrees(cartographic.latitude)
|
return {
|
lon: longitudeString,
|
lat: latitudeString,
|
height: cartographic.height
|
}
|
};
|
|
//移除整个资源
|
CesiumFlood.remove = function () {
|
let viewer = this.viewer
|
for (let tempEntity of this.tempEntities) {
|
viewer.entities.remove(tempEntity)
|
}
|
for (let lineEntity of this.polygonEntities) {
|
viewer.entities.remove(lineEntity)
|
}
|
this.handler = this.handler && this.handler.destroy();
|
};
|
|
CesiumFlood.start = function () {
|
const that = this
|
this.timer = window.setInterval(() => {
|
if ((that.height_max > that.extrudedHeight) && (that.extrudedHeight >= that.height_min)) {
|
that.extrudedHeight = that.extrudedHeight + that.speed
|
} else {
|
that.extrudedHeight = that.height_min
|
}
|
if (!that.map_type) {
|
if (that.heatMap) {
|
const bounds = {
|
west: 115.8784,
|
east: 115.9614,
|
south: 39.9912,
|
north: 40.0381
|
}
|
const positions_cartesian = that.getPoints(bounds.east, bounds.west, bounds.south, bounds.north)
|
that.getHeights(positions_cartesian, that.extrudedHeight, (d) => {
|
that.heatMapUpdate(d);
|
})
|
}
|
}
|
}, 500);
|
if (this.map_type) {
|
this.drawPoly(this.polygon_degrees)
|
} else {
|
if (this.heatMap) { }
|
|
}
|
};
|
|
CesiumFlood.clear = function () {
|
let viewer = this.viewer
|
if (this.timer) {
|
window.clearInterval(this.timer)
|
this.timer = null
|
}
|
this.extrudedHeight = this.height_min;
|
if (this.heatMapObj)
|
this.heatMapObj.show(false)
|
for (let entity of this.polygonEntities) {
|
viewer.entities.remove(entity)
|
}
|
viewer.skyAtmosphere = true
|
};
|
|
CesiumFlood.changeMapType = function (type) {
|
if (!type) {
|
if (!this.heatMap) {
|
// 得到插值网格
|
const bounds = {
|
west: 115.8784,
|
east: 115.9614,
|
south: 39.9912,
|
north: 40.0381
|
}
|
const positions_cartesian = this.getPoints(bounds.east, bounds.west, bounds.south, bounds.north)
|
this.getHeights(positions_cartesian, this.extrudedHeight, (d) => {
|
CesiumHeatmap.create(this.viewer, d, bounds);
|
})
|
}
|
|
this.heatMap && this.heatMap.show(true)
|
for (let entity of this.polygonEntities) {
|
entity.show = false;
|
}
|
} else {
|
this.heatMap.show(false)
|
for (let entity of this.polygonEntities) {
|
entity.show = true;
|
}
|
}
|
};
|
|
// 切割一部分地形
|
CesiumFlood.loadGrandCanyon = function () {
|
var globe = this.viewer.scene.globe;
|
const viewer = this.viewer
|
// viewer.skyAtmosphere = false,
|
// Pick a position at the Grand Canyon
|
var position = Cesium.Cartographic.toCartesian(new Cesium.Cartographic.fromDegrees(115.9165534, 40.0139345, 100));
|
var distance = 3000.0;
|
var boundingSphere = new Cesium.BoundingSphere(position, distance);
|
|
globe.clippingPlanes = new Cesium.ClippingPlaneCollection({
|
modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(position),
|
planes: [
|
new Cesium.ClippingPlane(new Cesium.Cartesian3(1.0, 0.0, 0.0), distance),
|
new Cesium.ClippingPlane(new Cesium.Cartesian3(-1.0, 0.0, 0.0), distance),
|
new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 1.0, 0.0), distance),
|
new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, -1.0, 0.0), distance)
|
],
|
unionClippingRegions: true
|
});
|
globe.clippingPlanes.enabled = true;
|
viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0.5, -0.5, boundingSphere.radius * 5.0));
|
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
|
};
|
|
var drawpointArr = [];
|
var floodHandler;
|
CesiumFlood.drawFloodDraw = function (options) {
|
if ((options.viewer.entities.getById('measureFloodPolyGonGroundEntity') !== undefined)) {
|
options.viewer.entities.removeById('measureFloodPolyGonGroundEntity');
|
}
|
for (var i = 0; i < drawpointArr.length; i++) {
|
options.viewer.entities.remove(drawpointArr[i]);
|
}
|
drawpointArr = [];
|
|
var polygon = new Cesium.PolygonHierarchy();
|
var measureFloodPolyGonGroundEntity = options.viewer.entities.add({
|
id: 'measureFloodPolyGonGroundEntity',
|
polygon: {
|
material: new Cesium.ColorMaterialProperty(Cesium.Color.RED.withAlpha(0.3)),
|
classificationType: Cesium.ClassificationType.BOTH,
|
outline: true,
|
outlineColor: Cesium.Color.WHITE,
|
hierarchy: new Cesium.CallbackProperty(function () {
|
return polygon;
|
}, false)
|
},
|
});
|
|
floodHandler = floodHandler && floodHandler.destroy();
|
floodHandler = new Cesium.ScreenSpaceEventHandler(options.viewer.scene.canvas);
|
floodHandler.setInputAction(function (movement) {
|
var earthPosition = options.viewer.scene.pickPosition(movement.position);
|
var cartographic = Cesium.Cartographic.fromCartesian(earthPosition);
|
var height = cartographic.height; //模型高度
|
if (Number(height) < 0) {
|
var ray = options.viewer.camera.getPickRay(movement.position);
|
earthPosition = options.viewer.scene.globe.pick(ray, options.viewer.scene);
|
}
|
if (earthPosition && earthPosition.x) {
|
if (polygon.positions.length > 1) {
|
let last = polygon.positions[polygon.positions.length - 2];
|
if (Math.abs(earthPosition.x - last.x) > 0.000001 && Math.abs(earthPosition.y - last.y) > 0.000001) {
|
polygon.positions.push(earthPosition);
|
createPoint(earthPosition);
|
}
|
} else {
|
polygon.positions.push(earthPosition);
|
createPoint(earthPosition);
|
}
|
if (polygon.positions.length > 2) {
|
measureFloodPolyGonGroundEntity.show = true;
|
}
|
}
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
floodHandler.setInputAction(function (movement) {
|
var newPosition = options.viewer.scene.pickPosition(movement.endPosition);
|
var cartographic = Cesium.Cartographic.fromCartesian(newPosition);
|
var height = cartographic.height; //模型高度
|
if (Number(height) < 0) {
|
var ray = options.viewer.camera.getPickRay(movement.endPosition);
|
newPosition = options.viewer.scene.globe.pick(ray, options.viewer.scene);
|
}
|
if (newPosition && newPosition.x) {
|
polygon.positions.pop()
|
polygon.positions.push(newPosition);
|
}
|
if (polygon.positions.length > 2) {
|
measureFloodPolyGonGroundEntity.show = true;
|
}
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
floodHandler.setInputAction(function (movement) {
|
if(polygon.positions.length>1){
|
polygon.positions.splice(polygon.positions.length-2,1);
|
}
|
if (polygon.positions.length < 3) {
|
measureFloodPolyGonGroundEntity.show = false;
|
}
|
options.viewer.entities.remove(drawpointArr[drawpointArr.length - 1]);
|
drawpointArr.pop();
|
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
|
floodHandler.setInputAction(function (movement) {
|
polygon.positions.pop();
|
floodHandler = floodHandler && floodHandler.destroy();
|
if (polygon.positions.length < 3) {
|
options.viewer.entities.remove(measureFloodPolyGonGroundEntity);
|
} else {
|
CesiumFlood.polygon_degrees = [];
|
for (var pindex = 0; pindex < polygon.positions.length; pindex++) {
|
var cartographic = Cesium.Cartographic.fromCartesian(polygon.positions[pindex]);
|
var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
|
var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
|
CesiumFlood.polygon_degrees.push(longitudeString);
|
CesiumFlood.polygon_degrees.push(latitudeString);
|
}
|
}
|
for (let i in drawpointArr) {
|
options.viewer.entities.remove(drawpointArr[i]);
|
}
|
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
|
function createPoint(worldPosition) {
|
drawpointArr.push(options.viewer.entities.add({
|
position: worldPosition,
|
point: {
|
color: Cesium.Color.RED,
|
pixelSize: 10,
|
outlineWidth: 1,
|
outlineColor: Cesium.Color.WHITE,
|
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
}
|
}));
|
}
|
}
|
CesiumFlood.floodDrawClean = function(options) {
|
floodHandler = floodHandler && floodHandler.destroy();
|
if ((options.viewer.entities.getById('measureFloodPolyGonGroundEntity') !== undefined)) {
|
options.viewer.entities.removeById('measureFloodPolyGonGroundEntity');
|
}
|
for (var i = 0; i < drawpointArr.length; i++) {
|
options.viewer.entities.remove(drawpointArr[i]);
|
}
|
}
|
return CesiumFlood;
|
}
|
|
|
if (typeof (CesiumFlood) === 'undefined') {
|
window.CesiumFlood = define_CesiumFlood();
|
} else {
|
console.log("CesiumFlood already defined.");
|
}
|
})(window);
|