/** * 水淹没分析 */ (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);