Cesium倾斜摄影分层效果

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>cesium示例</title>

    <script src="Cesium/Cesium.js"></script>
    <style type="text/css">
        @import url(Cesium/Widgets/widgets.css);

        html,
        body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            background-image: linear-gradient(to right, skyblue, #fff);
        }

        .container {
            height: 100%;
            display: flex;
            flex-direction: column;
        }

        #app .title {
            font-size: 20px;
            width: 100%;
            height: 40px;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .container .right {
            flex: 1;
            display: flex;
            flex-direction: row;
        }

        .container .right .title {
            height: 30px;
            width: 100%;
            display: flex;
            justify-content: center;
        }

        .container .title .home {
            width: 30px;
            height: 30px;
            position: absolute;
            right: 40px;
            cursor: pointer;
            background: url("image/home.png") no-repeat;
            background-size: contain;
        }

        .floor {
            position: absolute;
            width: 200px;
            height: 100px;
            top: 50px;
            z-index: 999;
            background: aliceblue;
        }
    </style>

</head>

<body>
    <div id="app" class="container">
        <div class="title">三维SDK示例
            <div class="home" title="返回首页" onclick="window.location.href='3DGIS.html'"></div>
        </div>
        <div class="right">
            <div style="flex: 1;position: relative;">
                <div id="map" style="position: absolute;width: 100%;height: 100%;">
                    <div class="floor">
                        <div>办公楼-四层</div>
                        <div>办公楼-三层</div>
                        <div>办公楼-二层</div>
                        <div>办公楼-一层</div>
                        <div onclick="fun()">全图</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script type="text/javascript">

        Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3ZjQ5ZGUzNC1jNWYwLTQ1ZTMtYmNjYS05YTY4ZTVmN2I2MDkiLCJpZCI6MTE3MTM4LCJpYXQiOjE2NzY0NDUyODB9.ZaNSBIfc1sGLhQd_xqhiSsc0yr8oS0wt1hAo9gbke6M'
        const viewer = new Cesium.Viewer('map', {});
        // 开启帧率
        viewer.scene.debugShowFramesPerSecond = true;

        function highlightFeature(feature) {
            // 示例:改变材质颜色(需要先获取tileset的tile)
            const tile = feature // 获取包含该feature的tile对象
            if (tile) {
                tile.color = new Cesium.Color(1.0, 0.0, 0.0, 0.5); // 红色半透明着色
            }
        }

        function clearHighlight() {
            // 清除高亮或恢复默认颜色
            tileset.style = undefined; // 移除所有自定义样式或恢复默认样式设置
        }


        // 递归遍历 Cesium3DTileset 的所有 tile
        function getAllTiles(tileset) {
            const tiles = []; // 用于存储所有 tile

            // 递归函数
            function traverse(tile) {
                if (!tile) return;

                // 将当前 tile 添加到数组中
                tiles.push(tile);

                // 遍历子 tile
                if (tile.children) {
                    for (let i = 0; i < tile.children.length; i++) {
                        traverse(tile.children[i]);
                    }
                }
            }

            // 从根 tile 开始遍历
            traverse(tileset.root);

            return tiles;
        }

        const tileset = new Cesium.Cesium3DTileset({
            url: "./data/kjg/tileset.json",
        });
        var allTiles
        tileset.readyPromise
            .then(function (tileset) {
                viewer.scene.primitives.add(tileset);
                tileSetAll(tileset, 114.34, 38, 0, 0, 0, 0, 1)
                viewer.zoomTo(tileset)

                const boundingSphere = tileset.boundingSphere;
                const halfAxes = Cesium.Matrix3.fromScale(new Cesium.Cartesian3(
                    boundingSphere.radius, // 东方向半轴长度
                    boundingSphere.radius, // 北方向半轴长度
                    boundingSphere.radius  // 上方向半轴长度
                ));
                const boundingBox = Cesium.OrientedBoundingBox(
                    boundingSphere.center, // 中心点
                    halfAxes // 半轴向量
                );

                // 绘制包围盒
                boundingBoxEntity = viewer.entities.add({
                    position: boundingSphere.center,
                    box: {
                        dimensions: new Cesium.Cartesian3(
                            halfAxes[0],
                            halfAxes[4],
                            halfAxes[8]
                        ),
                        material: Cesium.Color.RED.withAlpha(0.5),
                        outline: true,
                        outlineColor: Cesium.Color.RED,
                    },
                    show: false, // 初始隐藏
                });

                allTiles = getAllTiles(tileset);
                console.log("所有 tile 的数量:", allTiles.length);
                console.log("所有 tile:", allTiles);

                console.log(tileset);

            })
            .otherwise(function (error) {
                console.log(error);
            });

        // 0、取消默认的单击和双击事件,右上角弹窗很丑
        viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
        viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

        let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

        /*鼠标移动选择开始*/
        var silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage();
        silhouetteBlue.uniforms.color = Cesium.Color.BLUE;
        silhouetteBlue.uniforms.length = 0.05;
        silhouetteBlue.selected = [];

        var silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage();
        silhouetteGreen.uniforms.color = Cesium.Color.LIME;
        silhouetteGreen.uniforms.length = 0.05;
        silhouetteGreen.selected = [];
        viewer.scene.postProcessStages.add(Cesium.PostProcessStageLibrary.createSilhouetteStage([silhouetteBlue, silhouetteGreen]));

        viewer.screenSpaceEventHandler.setInputAction(function onMouseMove(movement) {
            var pickedFeature = viewer.scene.pick(movement.endPosition);
            if (Cesium.defined(pickedFeature)) {
                if (pickedFeature == silhouetteGreen.selected[0]) {
                    silhouetteBlue.selected = [];
                } else {
                    silhouetteBlue.selected = [pickedFeature];
                }
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        function tileSetAll(tileset, longitude, latitude, height, rotateX, rotateY, rotateZ, scale) {
            //旋转角度设置

            var mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(rotateX));
            var my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(rotateY));
            var mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(rotateZ));
            var rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
            var rotationY = Cesium.Matrix4.fromRotationTranslation(my);
            var rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
            //平移 修改经纬度
            var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
            var transform = Cesium.Transforms.eastNorthUpToFixedFrame(position);
            //旋转、平移矩阵相乘
            Cesium.Matrix4.multiply(transform, rotationX, transform);
            Cesium.Matrix4.multiply(transform, rotationY, transform);
            Cesium.Matrix4.multiply(transform, rotationZ, transform);
            //缩放 修改缩放比例
            var scale1 = Cesium.Matrix4.fromUniformScale(scale);
            Cesium.Matrix4.multiply(transform, scale1, transform);
            //赋值给tileset
            tileset._root.transform = transform;
        }

        function fun() {
            selectedFeature.forEach(function (item) {
                item.show = true
            })
        }



        // 保存点击过的tile
        var selectedFeature = [];

        // 定义层级偏移量
        const layerOffsets = {
            "办公楼-四层": new Cesium.Cartesian3(50, 0, 0), // Layer 1 向右偏移50米
            // "办公楼-三层": new Cesium.Cartesian3(50, 0, 0), // Layer 2 向前偏移50米
            // "办公楼-二层": new Cesium.Cartesian3(50, 0, 0)  // Layer 3 向上偏移50米
        };

        // 存储当前偏移的tile
        let offsetTile = null;

        viewer.screenSpaceEventHandler.setInputAction(function leftClick(movement) {
            var pickedFeature = viewer.scene.pick(movement.position);
            if (Cesium.defined(pickedFeature)) {
                silhouetteGreen.selected = [pickedFeature];
                console.log(silhouetteGreen.selected);

                // 显示单体信息
                let feature = pickedFeature
                feature.show = false
                console.log("隐藏 tile:", feature);

                selectedFeature.push(feature)
                const properties = feature.getPropertyNames();

                let list = []
                properties.forEach((property) => {
                    const value = feature.getProperty(property);
                    list.push({
                        key: property,
                        value: value
                    })
                    console.log(`${property}: ${value}`);
                });
                console.log(list);

                // const layer = feature.getProperty('name'); // 假设层级属性为'layer'

                // if (layer && layerOffsets[layer]) {
                //     // 恢复之前偏移的tile
                //     if (offsetTile) {
                //         offsetTile._content._tile.transform = Cesium.Matrix4.IDENTITY;
                //     }
                //     // 应用新的偏移
                //     const offset = layerOffsets[layer];
                //     feature._content._tile.transform = Cesium.Matrix4.fromTranslation(offset);
                //     offsetTile = feature;
                // } else {
                //     // 如果点击的是空白区域,恢复偏移
                //     if (offsetTile) {
                //         offsetTile._content._tile.transform = Cesium.Matrix4.IDENTITY;
                //         offsetTile = null;
                //     }
                // }


            }

            console.log(tileset);

        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        /*鼠标移动选择结束*/

    </script>
</body>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值