[cesium] | 地形挖方分析

效果

github上看到一个挖方的插件,准备改造完善填挖方功能,引入即可使用。

 

本地示例代码

           /**
             * 创建方量分析
             * @param {*} options 
             */
            createCutVolumeAnalysis(options) {
                options = options || {}
                if (this._viewer && options) {
                    var $this = this;
                    $this.drawWallGraphics({ //绘制贴地线 返回positions
                        callback: function (wall, wallobj) {

                            var _cutVolumeAnalysis = new CutVolumeAnalysis({

                                positions:                                                             
                                $this.transformWGS84ArrayToCartesianArray(wall, 100),
                                that: $this
                            })

                            if (typeof options.callback === 'function') {
                                options.callback(_cutVolumeAnalysis)
                            }
                        }
                    })
                }
            } 
        /**
         * 方量分析
         * @param {*} params 
         */
        function CutVolumeAnalysis(params) {

            if (params && params.positions && params.that) {

                var that = params.that, positions = params.positions
                    , _debugShowSubTriangles = true, $this = this;


                computeCutVolume()
            }
            /**
             * 计算多边形的重心点
             * @param {*} positions 
             */
            function computeCentroidOfPolygon(positions) {
                var x = [];
                var y = [];

                for (var i = 0; i < positions.length; i++) {
                    var cartographic = Cesium.Cartographic.fromCartesian(positions[i]);

                    x.push(cartographic.longitude);
                    y.push(cartographic.latitude);
                }

                var x0 = 0.0, y0 = 0.0, x1 = 0.0, y1 = 0.0;
                var signedArea = 0.0;
                var a = 0.0;
                var centroidx = 0.0, centroidy = 0.0;

                for (i = 0; i < positions.length; i++) {
                    x0 = x[i];
                    y0 = y[i];

                    if (i == positions.length - 1) {
                        x1 = x[0];
                        y1 = y[0];
                    } else {
                        x1 = x[i + 1];
                        y1 = y[i + 1];
                    }

                    a = x0 * y1 - x1 * y0;
                    signedArea += a;
                    centroidx += (x0 + x1) * a;
                    centroidy += (y0 + y1) * a;
                }

                signedArea *= 0.5;
                centroidx /= (6.0 * signedArea);
                centroidy /= (6.0 * signedArea);

                return new Cesium.Cartographic(centroidx, centroidy);
            }

            /**
             * 计算三角形的面积
             * @param {*} pos1 
             * @param {*} pos2 
             * @param {*} pos3 
             */
            function computeAreaOfTriangle(pos1, pos2, pos3) {
                var a = Cesium.Cartesian3.distance(pos1, pos2);
                var b = Cesium.Cartesian3.distance(pos2, pos3);
                var c = Cesium.Cartesian3.distance(pos3, pos1);

                var S = (a + b + c) / 2;

                return Math.sqrt(S * (S - a) * (S - b) * (S - c));
            }
            /**
             * 计算方量
             */
            function computeCutVolume() {

                var tileAvailability = that._viewer.terrainProvider.availability;
                if (!tileAvailability) {
                    alert("未获取到地形")
                    return false;
                }
                var maxLevel = 0;
                var minHeight = 15000;
                // 计算差值点
                for (var i = 0; i < positions.length; i++) {
                    var cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
                    var height = that._viewer.scene.globe.getHeight(cartographic);

                    if (minHeight > height)
                        minHeight = height;

                    var level = tileAvailability.computeMaximumLevelAtPosition(cartographic);

                    if (maxLevel < level)
                        maxLevel = level;
                }

                var granularity = Math.PI / Math.pow(2, 11);
                granularity = granularity / (64);
                var polygonGeometry = new Cesium.PolygonGeometry.fromPositions(
                    {
                        positions: positions,
                        vertexFormat: Cesium.PerInstanceColorAppearance.FLAT_VERTEX_FORMAT,
                        granularity: granularity
                    }
                );

                //polygon subdivision

                var geom = new Cesium.PolygonGeometry.createGeometry(polygonGeometry);

                var totalCutVolume = 0;
                var maxHeight = 0;

                var i0, i1, i2;
                var height1, height2, height3;
                var p1, p2, p3;
                var bottomP1, bottomP2, bottomP3;
                var scratchCartesian = new Cesium.Cartesian3();
                var cartographic;
                var bottomArea;
                var subTrianglePositions;


                for (i = 0; i < geom.indices.length; i += 3) {
                    i0 = geom.indices[i];
                    i1 = geom.indices[i + 1];
                    i2 = geom.indices[i + 2];

                    subTrianglePositions = geom.attributes.position.values;

                    scratchCartesian.x = subTrianglePositions[i0 * 3];
                    scratchCartesian.y = subTrianglePositions[i0 * 3 + 1];
                    scratchCartesian.z = subTrianglePositions[i0 * 3 + 2];

                    cartographic = Cesium.Cartographic.fromCartesian(scratchCartesian);

                    height1 = that._viewer.scene.globe.getHeight(cartographic);

                    p1 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, height1);
                    bottomP1 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0);

                    if (maxHeight < height1)
                        maxHeight = height1;

                    scratchCartesian.x = subTrianglePositions[i1 * 3];
                    scratchCartesian.y = subTrianglePositions[i1 * 3 + 1];
                    scratchCartesian.z = subTrianglePositions[i1 * 3 + 2];

                    cartographic = Cesium.Cartographic.fromCartesian(scratchCartesian);

                    height2 = that._viewer.scene.globe.getHeight(cartographic);

                    p2 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, height2);
                    bottomP2 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0);

                    if (maxHeight < height2)
                        maxHeight = height2;

                    scratchCartesian.x = subTrianglePositions[i2 * 3];
                    scratchCartesian.y = subTrianglePositions[i2 * 3 + 1];
                    scratchCartesian.z = subTrianglePositions[i2 * 3 + 2];

                    cartographic = Cesium.Cartographic.fromCartesian(scratchCartesian);

                    height3 = that._viewer.scene.globe.getHeight(cartographic);

                    p3 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, height3);
                    bottomP3 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0);

                    if (maxHeight < height3)
                        maxHeight = height3;

                    bottomArea = computeAreaOfTriangle(bottomP1, bottomP2, bottomP3);

                    totalCutVolume = totalCutVolume + bottomArea * (height1 - minHeight + height2 - minHeight + height3 - minHeight) / 3;

                    if (_debugShowSubTriangles) {
                        var positionsarr = [];

                        positionsarr.push(p1);
                        positionsarr.push(p2);
                        positionsarr.push(p3);

                        var drawingPolygon = {
                            polygon: {
                                hierarchy: {
                                    positions: positionsarr
                                },
                                extrudedHeight: 0,
                                perPositionHeight: true,
                                material: Cesium.Color.fromRandom().withAlpha(0.5),
                                outline: true,
                                closeTop: true,
                                closeBottom: true,
                                outlineColor: Cesium.Color.WHITE,
                                outlineWidth: 2
                            }
                        };

                        that._analysisLayer.entities.add(drawingPolygon);
                    }

                }
                var centroid = computeCentroidOfPolygon(positions);
                $this._volumeLabel = that._analysisLayer.entities.add({
                    position: Cesium.Cartesian3.fromRadians(centroid.longitude, centroid.latitude, maxHeight + 1000),
                    label: {
                        text: 'Cut Volume ' + totalCutVolume.toString() + 'm3'
                    }
                });

                return maxHeight;
            };
        }

在线调用示例

// 在引入的cesiumJS下面引入d3kit插件
<script src="http://zhangticcc.gitee.io/d3kit/d3kit.js"></script>
<script>
    
 // 初始化 Cesium.Viewer
 let viewer = new Cesium.Viewer("d3map");
 // 初始化 d3kit
 let d3kit = new Cesium.D3Kit(viewer)
 
 // 开启世界地形
 viewer.terrainProvider = Cesium.createWorldTerrain();

 // 挖方示例 在地形上绘制小块多边形 切割多边形计算面积比较耗资源
 d3kit.createCutVolumeAnalysis()
 
</script>

地址: 传送门 

  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: 在Vue项目中使用Cesium实现填挖方分析,需要做以下几个步骤: 1.引入Cesium和Vue组件 在Vue项目中使用Cesium,可以通过引入cesium和Vue-Cesium组件库来实现。在Vue组件中使用Cesium的方法是在组件中引入CesiumViewer组件,然后通过ref获取到CesiumViewer对象,就可以使用Cesium的API来实现填挖方分析了。 2.加载地形数据和模型数据 Cesium可以加载各种地形和模型数据,包括STL、OBJ、COLLADA、GeoJSON等格式的数据,在Vue项目中也可以使用Vue组件的方式加载数据,并且可以通过Vue的数据绑定功能灵活变换模型的颜色、大小等属性。 3.计算填挖方体积 为了实现填挖方分析,需要对地形和模型数据进行计算,得到填挖方体积。这可以通过使用Cesium提供的各种计算API来实现,例如Cesium.CesiumTerrainProvider计算地形数据的高度信息,Cesium.GeometryPipeline计算模型的体积和质心信息等。 4.实现可视化效果 最后,将计算得到的填挖方体积结果可视化展示出来,可以通过使用Vue-Cesium提供的组件库中的几何体Visible和Primitive实现。使用这些组件可以创建几何体、修改其颜色和透明度等属性,以展示填挖方体积的分析结果。 综上所述,在Vue项目中使用Cesium实现填挖方分析需要进行地形和模型数据加载、计算填挖方体积和实现可视化效果等步骤。需要在Vue组件中利用Cesium的API,从而实现填挖方分析并将其呈现出来。 ### 回答2: Vue项目中使用Cesium实现填挖方分析需要的基本步骤如下: 1.导入Cesium的相关库,包括Cesium.js、Cesium.css等。 2.通过vue-cli创建一个Vue项目,然后在项目中集成cesium。 3.在项目中引入Cesium相关的组件,如Viewer、ImageryLayer、Terrain、Camera、CzmlDataSource等。 4.加载地图数据和创建3D场景。 5.通过Cesium提供的API,将填挖方分析所需的数据添加到场景中,如体积数据、地面模型等。 6.根据需要配置分析参数,如忽略地形高度、设置填挖面属性等。 7.使用Cesium提供的分析工具对填挖面进行分析,获取分析结果。 8.将分析结果以图表、图像或地图形式呈现在页面中。 在实现填挖方分析时,可参考Cesium官方提供的示例代码和文档,根据自己的需求进行定制化和扩展。通过使用Cesium实现填挖方分析,可以有效提高数据可视化和交互性,同时增加用户体验和操作效率。 ### 回答3: Vue.js 是一款流行的JavaScript框架,而Cesium则是一款基于WebGL的开源虚拟地球引擎,它能够制作具有高度精细度的3D地图。在Vue项目中集成Cesium可以使得地图数据更加直观生动,针对填挖方分析需求,我们可以通过Cesium在Vue项目中实现这个功能。 首先,我们需要将Cesium引入Vue项目,可以通过npm install cesium安装Cesium依赖,然后在.vue文件中通过import引入cesium。 接下来,我们需要准备地形数据并加载Cesium地形服务。在.vue文件中,我们可以通过Cesium中的ImageryProvider、terrainProvider类来实现加载地形。通过ImageryProvider,可以加载卫星图像作为底图,并同时指定terrainProvider来加载高程数据。在这里,我们需要加载高程数据来计算填挖方量,因此我们需要调用Cesium的terrainProvider来加载高程数据。加载高程数据之后,我们需要根据需求进行数据处理,如根据地区进行裁剪,计算出填挖方量等。 最后,我们需要将处理后的数据传递给Cesium来展示在地图上。可以通过调用Cesium中的entity、primitive等实例来展示数据。例如,我们可以通过entity来展示填方区域,通过primitive来展示填方边界等。 综上所述,在Vue项目中使用Cesium实现填挖方分析需要以下步骤:引入Cesium依赖,加载地形数据,数据处理与计算,数据展示。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值