WEBGL 体积计算方法

WEBGL 体积土方量计算方法

    • 测算效果图
    • 代码实现

本文主要介绍了 基于 Cesium 实现体积计算的方法介绍,前几天做项目时候遇到客户提出加入体积计算的项目要求,琢磨了几天,终于搞出来了,在此将一些经验进行

测算效果图

WEBGL 体积计算方法_第1张图片
本工具实现的鼠标选取区域并进行体积计算功能。

代码实现

首先记录选取区域 代码片.

//装载鼠标点迹集合
        dataSource = new Cesium.CustomDataSource("volumeEntity");
        Cesium.Viewer.dataSources.add(this.dataSource);

根据选取区域进行体积土方量计算核心代码 代码片.

   //计算体积
      function VolumeAnalysis (points) {
        var minHeight = 15000, lonlats = [];
        for (var i = 0; i < points.length; i++) {
            var cartographic = Cesium.Cartographic.fromCartesian(points[i]);
            var height = this.map.scene.globe.getHeight(cartographic);
            if (minHeight > height)
                minHeight = height;
            //经纬度值
            var lng = Cesium.Math.toDegrees(cartographic.longitude),
                lat = Cesium.Math.toDegrees(cartographic.latitude);
            lonlats.push(lng, lat, 0);
        }
        //设置网格粒度
        var granularity = Math.PI / Math.pow(2, 11);
        granularity = granularity / (64);
        //创建多边形平面几何体
        var polygonGeometry = new Cesium.PolygonGeometry.fromPositions(
            {
                positions: points,
                vertexFormat: Cesium.PerInstanceColorAppearance.FLAT_VERTEX_FORMAT,
                granularity: granularity
            }
        );
        //创建多边形平面几何体
        var geom = new Cesium.PolygonGeometry.createGeometry(polygonGeometry);
        var totalVolume = 0;
        var maxHeight = 0;
        var i0, i1, i2;
        var height1, height2, height3;
        var p1, p2, p3;
        var cartesian;
        var cartographic;
        var bottomArea;
        //循环计算网格的节点, indices顶点索引数据,用于确定几何中的基元
        for (var i = 0; i < geom.indices.length; i += 3) {
            i0 = geom.indices[i];
            i1 = geom.indices[i + 1];
            i2 = geom.indices[i + 2];
            //获取几何体三角面第一个面点
            cartesian = new Cesium.Cartesian3(geom.attributes.position.values[i0 * 3],
                geom.attributes.position.values[i0 * 3 + 1],
                geom.attributes.position.values[i0 * 3 + 2]);
            cartographic = Cesium.Cartographic.fromCartesian(cartesian);
            height1 = this.map.scene.globe.getHeight(cartographic);
            p1 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0);
            if (maxHeight < height1)
                maxHeight = height1;
            //获取几何体三角面第二个面点
            cartesian = new Cesium.Cartesian3(geom.attributes.position.values[i1 * 3],
                geom.attributes.position.values[i1 * 3 + 1],
                geom.attributes.position.values[i1 * 3 + 2]);
            cartographic = Cesium.Cartographic.fromCartesian(cartesian);
            //从网格的节点计算地面高度
            height2 = this.map.scene.globe.getHeight(cartographic);
            p2 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0);
            if (maxHeight < height2)
                maxHeight = height2;
            //获取几何体三角面第三个面点
            cartesian = new Cesium.Cartesian3(geom.attributes.position.values[i2 * 3],
                geom.attributes.position.values[i2 * 3 + 1],
                geom.attributes.position.values[i2 * 3 + 2]);
            cartographic = Cesium.Cartographic.fromCartesian(cartesian);
            height3 = this.map.scene.globe.getHeight(cartographic);
            p3 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0);
            if (maxHeight < height3)
                maxHeight = height3;
            //计算三角面的面积
            bottomArea = computeAreaOfTriangle(p1, p2, p3);
            //计算体积
            totalVolume = totalVolume + bottomArea * (height1 - minHeight + height2 - minHeight + height3 - minHeight) / 3;
        }
        //计算测量图形的中心点
        var centroid = computeCentroidOfPolygon(points);
        //创建体积文字
        this.dataSource.entities.add({
            position: Cesium.Cartesian3.fromRadians(centroid.longitude, centroid.latitude, maxHeight + 30),
            label: {
                text: '' + totalVolume.toFixed(1) + '立方米',
                font: '12pt Microsoft YaHei',
                showBackground: true,
                backgroundColor: Cesium.Color.RED.withAlpha(0.5),
            }
        });
        this.wallHeight = maxHeight;
        //创建体积墙
        this.createWall(lonlats);
    };
    

** 更多资料可以加我QQ:2082108430 **

你可能感兴趣的:(javascript)