Cesium(六)淹没分析(polygon版本)

淹没分析是三维分析常用的的其中一种分析,本文借鉴已有资料通过在地形图上动态拉伸polygon达到淹没分析的效果,下面给出淹没分析的主要代码:

效果:

一、容器创建&添加地形服务、

        var currentHeight = null, maxValue=null;
        //创建地形图层
        var rectangle = new Cesium.Rectangle(Cesium.Math.toRadians(5.9993076), Cesium.Math.toRadians(-0.00025749207),
            Cesium.Math.toRadians(7.00078), Cesium.Math.toRadians(1.001215));
        var terrainLayer = new Cesium.CesiumTerrainProvider({
            url: 'http://localhost:9002/api/wmts/terrain/671bf0e4425e421a8fbe701e2b4db959',
            requestWaterMask: true,
            credit: 'http://www.bjxbsj.cn',
        });
        //创建容器
        var viewer = new Cesium.Viewer('cesiumContainer', {
            selectionIndicator: false,
            infoBox: false,
            terrainProvider: terrainLayer
        });
        viewer.scene.globe.depthTestAgainstTerrain = true;
        //定位到目标地形
        viewer.scene.camera.flyTo({ destination: rectangle });

二、动态画贴地面(借鉴官网)

 var entityPolygon = null;
        var points = null;
        //取消左键双击事件
        var drawingMode = 'polygon';
        var activeShapePoints = [];
        var activeShape;
        var floatingPoint;
        viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
        //淹没分析entity
        function createPoint(worldPosition) {
            var point = viewer.entities.add({
                position: worldPosition,
                point: {
                    pixelSize: 10,
                    color: Cesium.Color.YELLOW,
                    //disableDepthTestDistance: Number.POSITIVE_INFINITY,
                    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
                },
            });
            points = point;
            return point;
        }
        function drawShape(positionData) {
            var shape;
            if (drawingMode === 'line') {
                shape = viewer.entities.add({

                    polyline: {
                        positions: positionData,
                        clampToGround: true,
                        arcType: Cesium.ArcType.RHUMB,
                        material: Cesium.Color.GREEN,
                        width: 5,
                        //zIndex:1
                    }
                });
            }
            else if (drawingMode === 'polygon') {
                shape = viewer.entities.add({
                    polygon: {
                        hierarchy: positionData,
                        material: new Cesium.ColorMaterialProperty(Cesium.Color.LIGHTSKYBLUE.withAlpha(0.7))
                    }
                });
            }
            else if (drawingMode === 'point') {
                shape= viewer.entities.add({
                    position: worldPosition,
                    point: {
                        pixelSize: 10,
                        color: Cesium.Color.YELLOW,
                        //disableDepthTestDistance: Number.POSITIVE_INFINITY,
                        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND//是否贴地
                    },
                });
            }
            return shape;
        }
        var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
        handler.setInputAction(function (event) {
            if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) {
                console.log('This browser does not support polylines on terrain.');
                return;
            }
            // 使用viewer.scene.pickPosition` 来代替`viewer.camera.pickEllipsoid` 这样当鼠标掠过terrain能得到正确的坐标
            var earthPosition = viewer.scene.pickPosition(event.position);
            if (Cesium.defined(earthPosition)) {
                if (activeShapePoints.length === 0) {
                    floatingPoint = createPoint(earthPosition);
                    activeShapePoints.push(earthPosition);
                    var dynamicPositions = new Cesium.CallbackProperty(function () {
                        return activeShapePoints;
                    }, false);
                    activeShape = drawShape(dynamicPositions);
                }
                activeShapePoints.push(earthPosition);
                createPoint(earthPosition);
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        handler.setInputAction(function (event) {
            if (Cesium.defined(floatingPoint)) {
                var newPosition = viewer.scene.pickPosition(event.endPosition);
                if (Cesium.defined(newPosition)) {
                    floatingPoint.position.setValue(newPosition);
                    activeShapePoints.pop();
                    activeShapePoints.push(newPosition);
                }
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        // Redraw the shape so it's not dynamic and remove the dynamic shape.
        function terminateShape() {
            activeShapePoints.pop();
             entityPolygon = drawShape(activeShapePoints);
            if (entityPolygon.polygon!=null) {

                thisWidget.drawOk(entityPolygon);
            }            
            viewer.entities.remove(floatingPoint);
            viewer.entities.remove(activeShape); 
            entityPolygon = null;
            floatingPoint = undefined;
            activeShape = undefined;
            activeShapePoints = [];
        }
        handler.setInputAction(function (event) {
            terminateShape();
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

三、淹没分析核心代码(借鉴火星科技)

//淹没分析核心代码
        var thisWidget = {
            entity: null,
            drawOk: function (e) {
                this.entity = e;
                var t = this.computePolygonHeightRange(e.polygon.hierarchy.getValue());
                currentHeight = t.minHeight, maxValue = t.maxHeight;
            },
            computePolygonHeightRange: function (e) {
                var t = []
                for (var i = 0; i < e.length; i++) t.push(e[i].clone());
                var a, n, r, o, s, u, l, h = 0,
                    g = 9999,
                    c = Math.PI / Math.pow(2, 11) / 64,
                    m = new Cesium.PolygonGeometry.fromPositions({
                        positions: t,
                        vertexFormat: Cesium.PerInstanceColorAppearance.FLAT_VERTEX_FORMAT,
                        granularity: c
                    }),
                    
                    d = new Cesium.PolygonGeometry.createGeometry(m);
                for (i = 0; i < d.indices.length; i += 3) a = d.indices[i],
                    n = d.indices[i + 1],
                    r = d.indices[i + 2],
                    l = new Cesium.Cartesian3(d.attributes.position.values[3 * a], d.attributes.position.values[3 * a + 1], d.attributes.position.values[3 * a + 2]),
                    (o = viewer.scene.globe.getHeight(Cesium.Cartographic.fromCartesian(l))) < g && (g = o),
                    h < o && (h = o),
                    l = new Cesium.Cartesian3(d.attributes.position.values[3 * n], d.attributes.position.values[3 * n + 1], d.attributes.position.values[3 * n + 2]),
                    (s = viewer.scene.globe.getHeight(Cesium.Cartographic.fromCartesian(l))) < g && (g = s),
                    h < s && (h = s),
                    l = new Cesium.Cartesian3(d.attributes.position.values[3 * r], d.attributes.position.values[3 * r + 1], d.attributes.position.values[3 * r + 2]),
                    (u = viewer.scene.globe.getHeight(Cesium.Cartographic.fromCartesian(l))) < g && (g = u),
                    h < u && (h = u);
                return {
                    maxHeight: h,
                    minHeight: g
                }
            },
            startFx: function (e) {
                viewer.scene.globe.depthTestAgainstTerrain = !0;
                var t = this;
                this.extrudedHeight = e,
                    this.entity.polygon.extrudedHeight = new Cesium.CallbackProperty(function (e) {
                        return t.extrudedHeight
                    }, false);

                for (var i = this.entity.polygon.hierarchy.getValue(), a = [], n = 0; n < i.length; n++) {
                    var r = Cesium.Ellipsoid.WGS84.cartesianToCartographic(i[n]),
                        o = {
                            lon: Cesium.Math.toDegrees(r.longitude),
                            lat: Cesium.Math.toDegrees(r.latitude),
                            hgt: e
                        },
                        s = [o.lon, o.lat, o.hgt];
                    a = a.concat(s)
                }
                return i = Cesium.Cartesian3.fromDegreesArrayHeights(a),
                    this.entity.polygon.hierarchy = new Cesium.CallbackProperty(function (e) {
                    return i;
                    },false),
                    !0
            },
            clear: function () {
                viewer.scene.globe.depthTestAgainstTerrain = !1,
                    this.entity = null
            },
            updateHeight: function (e) {
                this.entity.polygon.extrudedHeight = e
            }
        }
        function stopFX() {
            self.clearInterval(int);
        }
        window.flood = function () {
            currentHeight > maxValue ? stopFX() : (thisWidget.updateHeight(currentHeight), currentHeight += 1);
        };

四、调用示例

  $("#drawplygon").click(function () {
            //thisWidget.clear();
            viewer.entities.remove(thisWidget.entity);
            entityPolygon = null; 
            viewer.entities.remove(points);
            //terminateShape();
            drawingMode = 'polygon';
            entityPolygon = null; 


        });
        $("#floodanalyis").click(function () {
            console.log(viewer.entities.values.length);
            int = self.setInterval(flood, 100);                
        });

五、防止首次模拟淹没分析闪屏

 //为了防止第一次分析闪屏
        var greenCylinder = viewer.entities.add({
            name: 'Green cylinder with black outline',
            position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 200000.0),
            cylinder: {
                length: 400000.0,
                topRadius: 200000.0,
                bottomRadius: 200000.0,
                material: Cesium.Color.GREEN.withAlpha(0.5),
                outline: true,
                outlineColor: Cesium.Color.DARK_GREEN
            },
            show:false
        });

参考文章:
1、https://blog.csdn.net/sunycnb/article/details/85047605
2、http://support.supermap.com.cn:8090/webgl/examples/editor.html#floodex

你可能感兴趣的:(Ceisum)