1. 启动cesium第一个例子

259 阅读3分钟

0. 前言

之前的项目中如果使用地图,我都是用的antv L7,因为我们的项目并不是GIS行业,所以只需要展示就行了,L7封装好了很多功能也能满足需求。

但是对于cesium久仰大名,L7能做的cesium肯定能做,万一有什么L7不能做的,学会cesium也是好事。

不得不说cesium学习资料相当多,但是很难找到循序渐进且持续更新的教程。

而且使用cesium大多数还是着重于GIS行业的需求,还有数字孪生,我目前并不需要。还好有gpt边问边学。

开始我们实现下面的东西,大屏常见的背景地图。 image.png

1. 实现

安装依赖

yarn add cesium

完整代码

import * as Cesium from 'cesium';
import { useLayoutEffect } from 'react';
import './App.css';
const App = () => {
  useLayoutEffect(() => {
    // 创建Cesium Viewer实例
    const viewer = new Cesium.Viewer('cesiumContainer', {
      baseLayer: false, // 不加载任何底图
      baseLayerPicker: false, // 隐藏底图选择器
      animation: false, // 隐藏动画控件
      timeline: false, // 隐藏时间线控件
      geocoder: false, // 隐藏地名查找控件
      homeButton: false, // 隐藏返回初始位置按钮
      infoBox: false, // 隐藏信息框
      sceneModePicker: false, // 隐藏视角模式选择器
      selectionIndicator: false, // 隐藏选择指示器
      navigationHelpButton: false, // 隐藏导航帮助按钮
      fullscreenButton: false, // 隐藏全屏按钮
      vrButton: false, // 隐藏 VR 按钮
      sceneMode: Cesium.SceneMode.COLUMBUS_VIEW, // 2.5D模式
      contextOptions: {
        // 开启webgl alpha混合
        webgl: {
          alpha: true,
        },
      },
    });
    viewer.cesiumWidget.creditContainer.remove(); // 隐藏版权信息
    viewer.scene.skyBox.show = false; // 隐藏天空
    viewer.scene.skyAtmosphere.show = false; // 隐藏大气层
    viewer.scene.sun.show = false; // 隐藏太阳
    viewer.scene.moon.show = false; // 隐藏月亮

    // 透明背景
    viewer.scene.globe.translucency.enabled = true;
    viewer.scene.globe.baseColor = Cesium.Color.TRANSPARENT;
    viewer.scene.backgroundColor = Cesium.Color.TRANSPARENT;

    // 重设鼠标操作
    const controller = viewer.scene.screenSpaceCameraController;
    controller.zoomEventTypes = [Cesium.CameraEventType.WHEEL]; // 仅保留滚轮缩放
    controller.tiltEventTypes = [Cesium.CameraEventType.RIGHT_DRAG];

    // 加载本地GeoJSON数据
    Cesium.GeoJsonDataSource.load('/mapData/地图数据.json', {
      stroke: Cesium.Color.YELLOW, // 线条颜色
      fill: Cesium.Color.DARKGOLDENROD, // 填充颜色
      strokeWidth: 3, // 线条宽度
      clampToGround: false, // 贴地显示
    }).then(function (dataSource) {
      viewer.dataSources.add(dataSource);
      viewer.flyTo(dataSource, { duration: 0.5 }); // 飞到数据范围
    });

    return () => {
      viewer.destroy();
    };
  }, []);

  return <div id="cesiumContainer" className={'bg'}></div>;
};
export default App;

完整代码已经有注释,下面主要记录下坑。

1.1. cesium静态资源加载错误

如果直接运行上面代码,在网络控制台会看到很多资源加载错误

image.png 官方博客解决方法 这是因为默认情况下cesium的资源是相对包的文件夹,也就是请求路径不对。这种错误会出现在所有有打包工具的项目中。

1.1.1. 引入css文件

全局css中引入cesium的样式文件

@import "cesium/Build/Cesium/Widgets/widgets.css";

1.1.2. 修改cesium静态文件读取地址

文章中是使用插件,将静态文件复制到指定文件夹,我这里是直接复制的文件夹,原理都是一样的。

image.png 将包里的这四个文件夹复制到项目静态资源文件夹中。

然后在windows上修改全局变量

// '/cesiumStatic'就是我放静态资源的文件夹
window.CESIUM_BASE_URL = '/cesiumStatic';

image.png

1.2. 去掉所有不需要的自带组件、样式

对于一般的大屏,肯定不需要自带的那些组件和样式,这里需要关闭一大堆东西,大部分在代码注释中有。

1.2.1. 透明背景

21~27行和34~37行,首先开启了webglalpha混合,实际上就是让背景和dom元素混合颜色,然后设置背景色为透明就能显示出背景图片了。

当然也可以直接设置skybox的背景,但是需要设置6个方向的图片太麻烦了。

2.总结

这个专栏可能不会涉及3D瓦片,3D建筑的知识,目前目标是可以实现一般大屏的一些功能,什么点击弹窗、高亮标记、简单的动画效果。

希望能给和我一样需求的人一点帮助