Cesium 介绍之 实现创建三维底图

550 阅读2分钟

Cesium 介绍之创建三维底图

本文主要介绍 vue 中如何基于 cesium 创建三维底图、申请 cesium_token、加载比例尺工具、加载三维模型、进行 2D/2.5D/3D 底图切换和强制贴地等。

  1. cesium 官网 上申请 CESIUM_TOKEN
  2. 初始化视图

    cesium 底图和比例尺控件配置文件

export const MAP_STATIC_CONFIG = {
    timeline: false, // 是否显示时间轴
    sceneModePicker: false, // 是否显示3D/2D选择器
    baseLayerPicker: false, // 是否显示图层选择器
    geocoder: false, // 搜索
    scene3DOnly: false, // 如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
    animation: false, // 左下角仪表盘
    navigationHelpButton: false, // 右上角的帮助按钮
    homeButton: false, // 是否显示Home按钮
    infoBox: false, // 气泡卡片
    fullscreenButton: false, // 是否显示全屏按钮
    selectionIndicator: false, // Cesium 关闭点击绿色框
    showRenderLoopErrors: true // 是否显示渲染错误
};

export const MAP__STATIC_SCALE_TOOL = {
    // 罗盘
    enableCompass: false,
    // 缩放控件
    enableZoomControls: false,
    // 距离图例
    enableDistanceLegend: true,
    // 指南针外环
    enableCompassOuterRing: false
};
export const SCENE_MODE = {
    "2d": SceneMode.SCENE2D,
    "2.5d": SceneMode.COLUMBUS_VIEW,
    "3d": SceneMode.SCENE3D
};

主要实现代码(初始化 viewer 后可以将其挂载在 window 或者 Vue 原型 prototype 上)

<template>
    <div id="cesiumContainer" class="earth-map" />
</template>
export default{
    methods:{
        initViewer(){
            Ion.defaultAccessToken = CESIUM_TOKEN;
            const viewer = new Viewer(
                "cesiumContainer",
                Object.assign({}, MAP_STATIC_CONFIG, {
                    // 高德影像数据
                    imageryProvider: new UrlTemplateImageryProvider(
                        {
                            url // 影像地图地址
                        },
                        {
                            terrainProvider: new CesiumTerrainProvider({
                                url// 地形的入口文件所在服务器目录
                            })
                        }
                    )
                })
            );
            // 隐藏版权信息
            viewer._cesiumWidget._creditContainer.style.display = "none";
            // 更改地图展示模式
            viewer.scene.mode = SCENE_MODE["3d"];
            // 新增文字标注
            viewer.imageryLayers.addImageryProvider(
                new UrlTemplateImageryProvider({
                    url // 影像地图文字标注地址
                })
            );
            this.initScale(viewer);
            if (this.mapMode === "3d") {
                // 三维地图下加载三维模型——倾斜摄影
                this.add3DTileset(viewer);
            }
        },
        // 初始化比例尺
        initScale(viewer) {
            const options = Object.assign({}, MAP__STATIC_SCALE_TOOL, {
                // 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和Cesium.Rectangle.
                defaultResetView: Cartographic.fromDegrees(110, 30, 2000000)
            });
            new CesiumNavigation(viewer, options);
        },
         // 添加三维模型
        add3DTileset(viewer) {
            const tileset = viewer.scene.primitives.add(
                new Cesium3DTileset({
                    url: get3DTilesetData(this.$route.query.entid)
                    // maximumMemoryUsage: 1000
                })
            );
            tileset.readyPromise.then(tileset => {
                // 未加地形时,三维模型会飘到天上,需要对其设置贴地
                // this.changeHeight(tileset, 0);
                // 默认展示到当前模型的范围
                viewer.camera.viewBoundingSphere(
                    tileset.boundingSphere,
                    new HeadingPitchRange(0, -3.0, 0)
                );
                viewer.camera.lookAtTransform(Matrix4.IDENTITY);
            });
        },
        // 设置3dtiles模型所处高度
        changeHeight(tileset, height) {
            height = Number(height);
            if (isNaN(height)) return;
            const {
                longitude,
                latitude,
                height: cartographicHeight
            } = Cartographic.fromCartesian(tileset.boundingSphere.center);
            const surface = Cartesian3.fromRadians(
                longitude,
                latitude,
                cartographicHeight
            );
            const offset = Cartesian3.fromRadians(longitude, latitude, height);
            const translation = Cartesian3.subtract(
                offset,
                surface,
                new Cartesian3()
            );
            tileset.modelMatrix = Matrix4.fromTranslation(translation);
        }
    }
}