vue3初始化cesium,加载自定义TMS瓦片地图

前言

Cesium 是一个用于构建高性能 3D 地理空间应用程序的开源 JavaScript 库,主要用于可视化地球、地图、地形、3D 模型和各种地理数据;可在一些大屏场景下完成一下三维地图交互功能。

本文使用的cesium版本为:v1.123.0,前端框架为:vue3+vite,本文中示例地图为涠洲岛。

1.安装cesium

npm install cesium vite-plugin-cesium

2.配置cesium

vite.config.js

import cesium from 'vite-plugin-cesium';

3.创建一个cesium容器

<div ref="cesiumContainerRef" id="cesiumContainer"></div>

4.初始化cesium配置

    new Cesium.Viewer("cesiumContainer", {
            infoBox: false,             // 关闭cesium右下角的信息框
            animation: false,           // 隐藏动画控件
            baseLayerPicker: false,     // 隐藏图层选择控件
            fullscreenButton: false,    // 隐藏全屏按钮
            vrButton: false,            // 隐藏VR按钮,默认false
            geocoder: false,            // 隐藏地名查找控件
            homeButton: false,          // 隐藏Home按钮
            sceneModePicker: false,     // 隐藏场景模式选择控件
            selectionIndicator: true,   // 显示实体对象选择框,默认true
            timeline: false,            // 隐藏时间线控件
            navigationHelpButton: false, // 隐藏帮助按钮
            // scene3DOnly: true,          // 每个几何实例将只在3D中呈现,以节省GPU内存
            shouldAnimate: true,        // 开启动画自动播放
            sceneMode: Cesium.SceneMode.COLUMBUS_VIEW,               //SCENE2D, COLUMBUS_VIEW ,SCENE3D,MORPHING  
            requestRenderMode: true,    // 减少Cesium渲染新帧总时间并减少Cesium在应用程序中总体CPU使用率
            // 如场景中的元素没有随仿真时间变化,请考虑将设置maximumRenderTimeChange为较高的值,例如Infinity
            maximumRenderTimeChange: Infinity,
            imageryProvider: new Cesium.SingleTileImageryProvider({
                url: "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==",
                tileWidth: dom.width,
                tileHeight: dom.height
            }),
            //需要纯色背景必须设置
            contextOptions: {
                webgl: {
                    alpha: true,
                }
            },
        })

5.其他设置,可自行选择配置

        //背景设置为全黑
        viewer.scene.backgroundColor = new Cesium.Color(0.0, 0.0, 0.0, 1.0);

        //关闭大气
        viewer.scene.skyAtmosphere.show = false
        //抗锯齿
        viewer.scene.fxaa = true;
        viewer.scene.postProcessStages.fxaa.enabled = true;

        //关闭天空月亮
        viewer.scene.sun.show = false; 
        viewer.scene.moon.show = false;
        //关闭天空盒,否则会显示天空颜色
        viewer.scene.skyBox.show = false;
        //隐藏地球
        viewer.scene.undergroundMode = true;
        viewer.scene.globe.baseColor = new Cesium.Color(0, 0, 0, 1);
        viewer._cesiumWidget._creditContainer.style.display = "none";  //去掉logo

6.鼠标按键设置

        // 鼠标右键 倾斜操作
        viewer.scene.screenSpaceCameraController.tiltEventTypes = [
            Cesium.CameraEventType.RIGHT_DRAG
        ];
        // 鼠标滑轮 放缩操作
        viewer.scene.screenSpaceCameraController.zoomEventTypes = [
            Cesium.CameraEventType.WHEEL,
        ];
        // 鼠标左键 平移
        viewer.scene.screenSpaceCameraController.rotateEventTypes = [
            Cesium.CameraEventType.LEFT_DRAG
        ];

7.添加坐标拾取监听

        // 坐标拾取
        viewer.screenSpaceEventHandler.setInputAction((movement) => {
            const pick = viewer.scene.pickPosition(movement.position);
            if (Cesium.defined(pick)) {
                const cartesian = viewer.scene.pickPosition(movement.position);
                if (Cesium.defined(cartesian)) {
                    // 将笛卡尔坐标转换为地理坐标(经纬度)
                    const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
                    const longitude = Cesium.Math.toDegrees(cartographic.longitude);
                    const latitude = Cesium.Math.toDegrees(cartographic.latitude);
                    const height = cartographic.height;
                    console.log(`经度: ${longitude}, 纬度: ${latitude}, 高度: ${height}`);
                }
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

8.加载自定义瓦片

自定义TMS瓦片

            const tms = await Cesium.TileMapServiceImageryProvider.fromUrl(
                "tms地址", {
                fileExtension: 'png',
            });
            viewer.imageryLayers.addImageryProvider(tms);

geoServer

            const tifLayer = await new Cesium.WebMapServiceImageryProvider({
                url: 'geoserver服务地址',        // geoserver服务地址
                layers: '工作区名:图层名',       // 工作区名:图层名
                parameters: {
                    service: 'WMS',
                    format: 'image/png',
                    transparent: true
                },
                srs: 'EPSG:4326',
                crs: 'EPSG:4326',
            });
            viewer.imageryLayers.addImageryProvider(tifLayer);

9.如果有地形数据

            const terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl(
                "terrain地形切片地址", {
                requestWaterMask: true,
                requestVertexNormals: true,
            });
            viewer.terrainProvider = terrainProvider;

10.设置相机默认位置

        viewer.camera.setView({
            destination: Cesium.Cartesian3.fromDegrees(114.08246, 10.92367, 8000.0),   // 地图中选经纬度和高度
            orientation: {
                heading: Cesium.Math.toRadians(0), // 方位角  
                pitch: Cesium.Math.toRadians(-90.0), // 俯仰角,从上往下看为-90  
                roll: Cesium.Math.toRadians(0.0)     // 翻滚角  
            }
        });

11.完整代码

<template>
    <div class="content cesiumMap">
        <div ref="cesiumContainerRef" id="cesiumContainer"></div>
    </div>
</template>
<script setup>
    import { getCurrentInstance, onMounted, ref, reactive } from 'vue'
    const { proxy } = getCurrentInstance()
    import * as Cesium from 'cesium';

    let cesiumContainerRef = ref(null)
    let viewer = '';
    let dom = reactive({
        width: 0,
        height: 0
    })

    //初始化cesium
    const initCesium = async () => {
        viewer = new Cesium.Viewer("cesiumContainer", {
            infoBox: false,             // 关闭cesium右下角的信息框
            animation: false,           // 隐藏动画控件
            baseLayerPicker: false,     // 隐藏图层选择控件
            fullscreenButton: false,    // 隐藏全屏按钮
            vrButton: false,            // 隐藏VR按钮,默认false
            geocoder: false,            // 隐藏地名查找控件
            homeButton: false,          // 隐藏Home按钮
            sceneModePicker: false,     // 隐藏场景模式选择控件
            selectionIndicator: true,   // 显示实体对象选择框,默认true
            timeline: false,            // 隐藏时间线控件
            navigationHelpButton: false, // 隐藏帮助按钮
            // scene3DOnly: true,          // 每个几何实例将只在3D中呈现,以节省GPU内存
            shouldAnimate: true,        // 开启动画自动播放
            sceneMode: Cesium.SceneMode.COLUMBUS_VIEW,               //SCENE2D, COLUMBUS_VIEW ,SCENE3D,MORPHING  
            requestRenderMode: true,    // 减少Cesium渲染新帧总时间并减少Cesium在应用程序中总体CPU使用率
            // 如场景中的元素没有随仿真时间变化,请考虑将设置maximumRenderTimeChange为较高的值,例如Infinity
            maximumRenderTimeChange: Infinity,
            imageryProvider: new Cesium.SingleTileImageryProvider({
                url: "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==",
                tileWidth: dom.width,
                tileHeight: dom.height
            }),
            //需要纯色背景必须设置
            contextOptions: {
                webgl: {
                    alpha: true,
                }
            },
        })

        //背景设置为全黑
        viewer.scene.backgroundColor = new Cesium.Color(0.0, 0.0, 0.0, 1.0);

        //关闭大气
        viewer.scene.skyAtmosphere.show = false
        //抗锯齿
        viewer.scene.fxaa = true;
        viewer.scene.postProcessStages.fxaa.enabled = true;

        //关闭天空月亮
        viewer.scene.sun.show = false; 
        viewer.scene.moon.show = false;
        viewer.scene.skyBox.show = false;
        //隐藏地球
        viewer.scene.undergroundMode = true; 
        viewer.scene.globe.baseColor = new Cesium.Color(0, 0, 0, 1);
        viewer._cesiumWidget._creditContainer.style.display = "none";  //去掉logo

        // 鼠标右键 倾斜操作
        viewer.scene.screenSpaceCameraController.tiltEventTypes = [
            Cesium.CameraEventType.RIGHT_DRAG
        ];
        // 鼠标滑轮 放缩操作
        viewer.scene.screenSpaceCameraController.zoomEventTypes = [
            Cesium.CameraEventType.WHEEL,
        ];
        // 鼠标左键 
        viewer.scene.screenSpaceCameraController.rotateEventTypes = [
            Cesium.CameraEventType.LEFT_DRAG
        ];

        // 坐标拾取
        viewer.screenSpaceEventHandler.setInputAction((movement) => {
            const pick = viewer.scene.pickPosition(movement.position);
            if (Cesium.defined(pick)) {
                const cartesian = viewer.scene.pickPosition(movement.position);
                if (Cesium.defined(cartesian)) {
                    // 将笛卡尔坐标转换为地理坐标(经纬度)
                    const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
                    const longitude = Cesium.Math.toDegrees(cartographic.longitude);
                    const latitude = Cesium.Math.toDegrees(cartographic.latitude);
                    const height = cartographic.height;
                    console.log(`经度: ${longitude}, 纬度: ${latitude}, 高度: ${height}`);
                }
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        // 解决倾斜飘漂移,但是会损耗性能
        viewer.scene.globe.depthTestAgainstTerrain = true;
    }

    //初始化地图显示
    const initMap = async () => {
        // 加载瓦片地图
        try {
            // 加载oss自定义瓦片地图
            const tms = await Cesium.TileMapServiceImageryProvider.fromUrl(
                "tms地址", {
                fileExtension: 'png',
            }
            );
            viewer.imageryLayers.addImageryProvider(tms);
        } catch (error) {
            console.log(`tif加载失败: ${error}`);
        }

        // 添加地形数据
        // try {
        //     const terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl(
        //         "terrain地址", {
        //         requestWaterMask: true,
        //         requestVertexNormals: true,
        //     });
        //     viewer.terrainProvider = terrainProvider;
        // } catch (error) {
        //     console.log(`terrain加载失败: ${error}`);
        // }

        //设置相机位置
        viewer.camera.setView({
            destination: Cesium.Cartesian3.fromDegrees(109.11282,21.049105, 14000.0),   // 经纬度和高度
            orientation: {
                heading: Cesium.Math.toRadians(0), // 方位角  
                pitch: Cesium.Math.toRadians(-90.0), // 俯仰角,从上往下看为-90  
                roll: Cesium.Math.toRadians(0.0)     // 翻滚角  
            }
        });
    }


    const resize = () => {
        // 获取 DOM 元素的宽度和高度
        const container = cesiumContainerRef.value;
        const width = container.offsetWidth;
        const height = container.offsetHeight;
        dom.width = width;
        dom.height = height;
    }

    onMounted(() => {
        resize();
        // 初始化cesium
        initCesium();
        initMap();
    })
</script>

12.成功示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值