Cesium淹没分析(polygon版本)

Posted hpugisers

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

以上是关于Cesium淹没分析(polygon版本)的主要内容,如果未能解决你的问题,请参考以下文章

Cesium 50个实例集合,讲解、分析(内附源码)

Cesium在Terrain动态绘制线和面

Cesium 1.50重量级新功能测评

Cesium矢量地图插件发布新版本

Cesium专栏-空间分析之地形等高线(附源码下载)

Cesium对3dtile单个feature进行特效处理