【可视化学习】40-手把手实现cesium实现智慧城市(一)
发表于:2023-09-08 |

前言

本文将使用react和cesium进行智慧城市的实现,本篇主要讲解项目的初始化

初始化项目

1
npm init vite

然后选择react初始化项目
初始化项目

安装初始化依赖

打开项目后进行依赖安装

1
npm install/yarn install

启动

1
npm run dev/yarn dev

项目启动

安装cesium

此时我们的项目就已经启动了,接下来我们安装我们的cesium
cesium的版本不宜过新
我这里安装”cesium”: “^1.93.0”这个版本
依赖安装

注册账号申请token

这里是cesium申请的地址https://ion.cesium.com/signin
通过create Token来创建一个token
cesium

调整目录结构

接下来node_modules将cesium目录下的Build/Cesium4个目录拷贝到public,然后将widgets目录拷贝一份到src下
目录迁移

初始化项目

初始化样式

去除多余的css,仅保留

1
2
3
4
5
6
7
8
* {
margin: 0;
padding: 0;
}
#cesiumContainer {
width: 100vw;
height: 100vh;
}

修改main.jsx

去除包裹App的中的这部分代码
去除包裹代码

修改app.jsx

这里使用react的useEffect等待dom加载完毕,使用[]代表仅初始化渲染一次,这个具体的可以参考react文档,我这里就不多阐述了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { useEffect } from "react"
import * as Cesium from "cesium";
import "./Widgets/widgets.css";
// 设置cesium token
Cesium.Ion.defaultAccessToken =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhMzNkNTE5Zi1mMjY4LTRiN2QtOTRlZC1lOTUyM2NhNDYzNWYiLCJpZCI6NTU0OTYsImlhdCI6MTYyNTAyNjMyOX0.a2PEM4hQGpeuMfeB9-rPp6_Gkm6O-02Dm4apNbv_Dlk";

// 设置cesium静态资源路径
window.CESIUM_BASE_URL = "/";

function App() {
// 仅初始化调用一次
useEffect(()=>{
var viewer = new Cesium.Viewer("cesiumContainer")
},[])
return (
<div id="cesiumContainer"></div>
)
}

export default App

初始化

拆分出去初始化js

获取方位

首先我们去获取一下想做地方的方位,可以通过这个网址https://lbs.qq.com/getPoint/
获取方位

初始化viewer

  • src/cesium/initViewer.js
    根据上一步得到的方位进行适当微调
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    import * as Cesium from "cesium";

    export default function initViewer() {
    // 设置cesium token
    Cesium.Ion.defaultAccessToken =
    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhMzNkNTE5Zi1mMjY4LTRiN2QtOTRlZC1lOTUyM2NhNDYzNWYiLCJpZCI6NTU0OTYsImlhdCI6MTYyNTAyNjMyOX0.a2PEM4hQGpeuMfeB9-rPp6_Gkm6O-02Dm4apNbv_Dlk";

    // 设置cesium静态资源路径
    window.CESIUM_BASE_URL = "/";

    // 设置cesium默认视角
    Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
    // 西边的经度
    89.5,
    // 南边维度
    20.4,
    // 东边经度
    110.4,
    // 北边维度
    61.2
    );

    var viewer = new Cesium.Viewer("cesiumContainer", {
    // 是否显示信息窗口
    // infoBox: false,
    // 是否显示查询按钮
    geocoder: false,
    // 不显示home按钮
    homeButton: false,
    // 控制查看器的显示模式
    sceneModePicker: false,
    // 是否显示图层选择
    baseLayerPicker: false,
    // 是否显示帮助按钮
    navigationHelpButton: false,
    // 是否播放动画
    animation: false,
    // 是否显示时间轴
    timeline: false,
    // 是否显示全屏按钮
    fullscreenButton: false,
    // 初始化动画
    shouldAnimate: true,
    });

    // 设置沙箱允许使用js
    var iframe = document.getElementsByClassName("cesium-infoBox-iframe")[0];
    iframe.setAttribute(
    "sandbox",
    "allow-same-origin allow-scripts allow-popups allow-forms"
    );
    iframe.setAttribute("src", "");

    // 隐藏logo
    viewer.cesiumWidget.creditContainer.style.display = "none";

    viewer.scene.globe.enableLighting = true;
    // 取消天空盒显示
    viewer.scene.skyBox.show = false;
    // 设置背景为黑色
    viewer.scene.backgroundColor = Cesium.Color.BLACK;
    // 设置抗锯齿
    viewer.scene.postProcessStages.fxaa.enabled = true;

    // 天一广场
    // 29.86961,121.5539
    var postion = Cesium.Cartesian3.fromDegrees(
    // 经度
    121.5739,
    // 纬度
    29.85561,
    // 高度
    1500
    );
    viewer.camera.flyTo({
    destination: postion,
    orientation: {
    heading: Cesium.Math.toRadians(-45),
    pitch: Cesium.Math.toRadians(-30),
    roll: 0,
    },
    duration: 2,
    });
    return viewer;
    }

添加3D建筑

  • src/cesium/modeifyBuild
    1
    2
    3
    4
    5
    6
    7
    import * as Cesium from "cesium";

    export default function modifyBuild(viewer) {
    // 添加3D建筑
    let tiles3d = new Cesium.createOsmBuildings();
    const osmBuildings = viewer.scene.primitives.add(tiles3d);
    }

引入

在App.jsx中引入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { useEffect } from "react"
import * as Cesium from "cesium";
import "./Widgets/widgets.css";
import initViewer from "./cesium/initViewer"
import modifyBuild from "./cesium/modeifyBuild"
function App() {
// 仅初始化调用一次
useEffect(()=>{
// 初始化cesium
var viewer = initViewer()
// 创建建筑
modifyBuild(viewer);
},[])
return (
<div id="cesiumContainer"></div>
)
}

export default App

效果图

获取经纬度在右下角展示

鼠标位置获取经纬度

  • src/cesium/MousePosition.js
    根据我们之前学过数据转化的知识,我们可以通过鼠标的位置获取经纬度
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    import * as Cesium from "cesium";
    export default class MousePosition {
    constructor(viewer) {
    this.divDom = document.createElement("div");
    this.divDom.style.cssText = `
    position: fixed;
    bottom:0;
    right:0;
    width:200px;
    height:40px;
    background-color: rgba(0,0,0,0.5);
    color: #fff;
    font-size: 14px;
    line-height: 40px;
    text-align: center;
    z-index: 100;
    `;
    document.body.appendChild(this.divDom);

    // 监听鼠标的移动事件
    const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

    handler.setInputAction((movement) => {
    // 获取鼠标的坐标
    const cartesian = viewer.camera.pickEllipsoid(
    movement.endPosition,
    viewer.scene.globe.ellipsoid
    );
    if (cartesian) {
    // 转换成经纬度
    const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
    const longitudeString = Cesium.Math.toDegrees(
    cartographic.longitude
    ).toFixed(2);
    const latitudeString = Cesium.Math.toDegrees(
    cartographic.latitude
    ).toFixed(2);
    const heightString = cartographic.height;
    // 显示经纬度
    // console.log(
    // `经度:${longitudeString} 纬度:${latitudeString} 高度:${heightString}`
    // );
    this.divDom.innerHTML = `经度:${longitudeString} 纬度:${latitudeString} `;
    }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    }
    }

    引入

    在App.jsx中引入
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    import { useEffect } from "react"
    import * as Cesium from "cesium";
    import "./Widgets/widgets.css";
    import initViewer from "./cesium/initViewer"
    import modifyBuild from "./cesium/modeifyBuild"
    import MousePosition from "./cesium/MousePosition";
    function App() {
    // 仅初始化调用一次
    useEffect(()=>{
    // 初始化cesium
    var viewer = initViewer()
    // 创建建筑
    modifyBuild(viewer);
    // 根据鼠标位置生成经纬度值
    let mousePosition = new MousePosition(viewer);
    },[])
    return (
    <div id="cesiumContainer"></div>
    )
    }

    export default App

    效果图

初始化罗盘

安装依赖

1
npm install --save cesium-navigation-es6

引入

在App.jsx中引入

1
import CesiumNavigaion from "cesium-navigation-es6";

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
// 设置导航罗盘的配置
var options = {
// 启用罗盘
enableCompass: true,
// 是否启用缩放
enableZoomControls: false,
// 是否启用指南针外环
enableCompassOuterRing: true,
// 是否启用距离的图例
// enableDistanceLegend: false,
};
// 初始化导航罗盘
let navigation = new CesiumNavigaion(viewer, options);

效果图

好了,项目的基础配置我就介绍到这里了,下一篇我们将开始进行各种效果的添加

上一篇:
【可视化学习】41-手把手实现cesium实现智慧城市(二)
下一篇:
npm包的发布(一)