• React项目-Cesium地图初始化


    一、环境描述

            React集成Cesium地图需要注意软件兼容性问题,可以从官网或者百度文章查询React和Cesium地图的版本兼容性,

    1、软件版本

            (1)create-react-app创建项目;

            (2)React版本:18.3.1;

            (3)Cesium版本:1.62.0;

            (4)copy-webpack-plugin:5.1.2;

            (5)Node版本:14.21.3

    二、创建React项目

    1、创建项目
    npx create-react-app react-test
    2、启动项目
    1. cd react-test
    2. npm run start
    3、安装Cesium
    npm i cesium@1.62.0 --save
    4、安装copy-webpack-plugin
    npm i copy-webpack-plugin@5 -D
    5、运行npm run eject

            Cesium静态资源需要webpack配置,执行npm run eject可以生成webpack配置,运行前先查看当前git版本是否有提交,如果未提交,需要先本地提交git,否则npm run eject会执行失败。

    (1)提交git(如果版本已经提交,无需执行

    1. git add .
    2. git commit -m "React Init"

    (2)执行npm run eject

    1. npm run eject
    2. // 执行成功后,生成的文件列表
    3. // config/
    4. // jest/
    5. // webpack/
    6. // env.js
    7. // getHttpsConfig.js
    8. // modules.js
    9. // paths.js
    10. // webpack.config.js
    11. // webpackDevServer.config.js
    12. // scripts/
    13. // build.js
    14. // start.js
    15. // test.js

    三、webpack配置

    1、修改webpack.config.js文件
    1. // 1、引入copy-webpack-plugin
    2. const CopyWebpackPlugin = require('copy-webpack-plugin');
    3. // 2、引入Cesium静态资源
    4. const cesiumSource = "node_modules/cesium/Source";
    5. const cesiumWorkers = '../Build/Cesium/Workers';
    6. const fileFolder = "src";
    7. // 3、在return下的output对象中添加配置
    8. sourcePrefix: '',
    9. // 4、在return下的output对象后添加配置(与output对象同级)
    10. amd: {
    11. toUrlUndefined: true
    12. },
    13. // 5、在return下的resolve对象下的alias对象中添加配置
    14. cesium: path.resolve(cesiumSource),
    15. // 6、在return下的module对象中添加配置
    16. unknownContextCritical: false,
    17. // 7、在return下的plugins数组中添加配置
    18. new CopyWebpackPlugin([{
    19. from: path.join(cesiumSource, cesiumWorkers),
    20. to: "Workers"
    21. }]),
    22. new CopyWebpackPlugin([{
    23. from: path.join(cesiumSource, 'Assets'),
    24. to: 'Assets'
    25. }]),
    26. new CopyWebpackPlugin([{
    27. from: path.join(cesiumSource, 'Widgets'),
    28. to: 'Widgets'
    29. }]),
    30. new CopyWebpackPlugin([
    31. { from: path.join(fileFolder, 'static'), to: 'Static' }
    32. ]),
    33. new webpack.DefinePlugin({
    34. CESIUM_BASE_URL: JSON.stringify('')
    35. }),

    四、项目配置

    1、路由配置

    (1)路由文件配置

            在src/创建一个名为router.js的文件(文件名称和位置可以自己规划)

    1. // 引入组件
    2. import App from "./App";
    3. import CesiumMapFunction from './components/CesiumMapFunction';
    4. import CesiumMapClass from './components/CesiumMapClass';
    5. import { createBrowserRouter } from "react-router-dom";
    6. const router = createBrowserRouter([
    7. {
    8. path: "/",
    9. element: <App />,
    10. children: [
    11. {
    12. path: "",
    13. element: <CesiumMapFunction />
    14. },
    15. {
    16. path: "/cesiumFunction",
    17. element: <CesiumMapFunction />
    18. },
    19. {
    20. path: "/cesiumClass",
    21. element: <CesiumMapClass />
    22. }
    23. ]
    24. },
    25. ])
    26. export default router

    (2)index.js文件配置

    1. import React from 'react';
    2. import ReactDOM from 'react-dom/client';
    3. import './index.css';
    4. import App from './App';
    5. import reportWebVitals from './reportWebVitals';
    6. import { RouterProvider } from 'react-router-dom';
    7. import router from './router';
    8. const root = ReactDOM.createRoot(document.getElementById('root'));
    9. root.render(
    10. // // 注意注释React严格模式
    11. <RouterProvider router={router}>
    12. <App />
    13. RouterProvider>
    14. //
    15. );
    16. reportWebVitals();

    (3)App.js文件配置

    1. import './App.css';
    2. import Header from './components/Header';
    3. import { Outlet, useNavigate } from 'react-router-dom';
    4. import { useState } from 'react';
    5. function App() {
    6. const [isActive, setIsActive] = useState(1)
    7. const navigate = useNavigate()
    8. function clickMenu(path, menuId) {
    9. if (isActive === menuId) {
    10. return
    11. }
    12. // 保存当前点击的菜单ID
    13. setIsActive(menuId)
    14. // 跳转路由
    15. navigate(path)
    16. }
    17. return (
    18. <div className="App">
    19. <Header clickMenu={clickMenu} active={isActive}>Header>
    20. <div className="content">
    21. <Outlet />
    22. div>
    23. div>
    24. );
    25. }
    26. export default App;
    2、地图组件配置

     (1)Header.js配置

    1. // css文件
    2. import "./css/Header.css"
    3. // 数据来源
    4. const menuData = [
    5. {
    6. id: 1,
    7. label: "函数组件Cesium",
    8. path: "/cesiumFunction"
    9. },
    10. {
    11. id: 2,
    12. label: "类组件Cesium",
    13. path: "/cesiumClass"
    14. }
    15. ]
    16. // 数据过滤
    17. function FilterData({ clickList, isActive }) {
    18. return menuData.map(row => {
    19. return (
    20. <li className={isActive === row.id ? 'isActive' : ''} onClick={() => { clickList(row.path, row.id) }} key={row.id} >
    21. {row.label}
  • )
  • })
  • }
  • // 渲染页面
  • export default function Header({ clickMenu, active }) {
  • return (
  • <ul className="menuList">
  • <FilterData clickList={clickMenu} isActive={active} />
  • ul>
  • )
  • }
  • (2)函数组件(CesiumMapFunction.js)

    1. import Cesium from 'cesium/Cesium'
    2. import 'cesium/Widgets/widgets.css'
    3. import { useEffect } from "react";
    4. import "./css/CesiumMap.css"
    5. export default function CesiumMapFunction() {
    6. useEffect(() => {
    7. Cesium.Ion.defaultAccessToken = "your_map_token";
    8. // 初始化Cesium
    9. const viewer = new Cesium.Viewer('cesiumContainer', {
    10. geocoder: false, //右上角搜索
    11. homeButton: false, //右上角home
    12. sceneModePicker: false, //右上角2D/3D切换
    13. baseLayerPicker: false, //右上角地形
    14. navigationHelpButton: false, //右上角帮助
    15. animation: false, //左下角圆盘动画控件
    16. timeline: true, //底部时间轴
    17. fullscreenButton: false, //右下角全屏控件
    18. vrButton: false, //如果设置为true,将创建VRButton小部件。
    19. scene3DOnly: false, // 每个几何实例仅以3D渲染以节省GPU内存
    20. infoBox: false, //隐藏点击要素后的提示信息
    21. imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
    22. url: "your_map_url",
    23. }), //地图地址
    24. })
    25. // 隐藏左下角商标信息
    26. viewer._cesiumWidget._creditContainer.style.display = "none";
    27. // 隐藏底部时间轴
    28. viewer.timeline.container.style.display = "none";
    29. //开启深度检测
    30. viewer.scene.globe.depthTestAgainstTerrain = false;
    31. // 启用光照
    32. viewer.scene.globe.enableLighting = true;
    33. // 设置相机初始位置
    34. viewer.camera.setView({
    35. destination: Cesium.Cartesian3.fromDegrees(
    36. 110,
    37. 30,
    38. 10000
    39. ),
    40. // 设置相机方向,俯视和仰视的视角
    41. orientation: {
    42. heading: Cesium.Math.toRadians(0), //坐标系旋转0度
    43. pitch: Cesium.Math.toRadians(-90), //设置俯仰角度为-90度
    44. },
    45. });
    46. return () => {
    47. console.log("组件销毁前执行")
    48. }
    49. }, [])
    50. return (
    51. <div className='cesiumMap'>
    52. <div id="cesiumContainer" />
    53. div>
    54. );
    55. }

    (3)类组件(CesiumMapClass.js)

    1. import React, { Component } from 'react'
    2. import Cesium from 'cesium/Cesium'
    3. import 'cesium/Widgets/widgets.css'
    4. import './css/CesiumMap.css'
    5. Cesium.Ion.defaultAccessToken = "your_map_token"
    6. export default class App extends Component {
    7. componentDidMount() {
    8. const viewer = new Cesium.Viewer("cesiumContainer", {
    9. geocoder: false, //右上角搜索
    10. homeButton: false, //右上角home
    11. sceneModePicker: false, //右上角2D/3D切换
    12. baseLayerPicker: false, //右上角地形
    13. navigationHelpButton: false, //右上角帮助
    14. animation: false, //左下角圆盘动画控件
    15. timeline: true, //底部时间轴
    16. fullscreenButton: false, //右下角全屏控件
    17. vrButton: false, //如果设置为true,将创建VRButton小部件。
    18. scene3DOnly: false, // 每个几何实例仅以3D渲染以节省GPU内存
    19. infoBox: false, //隐藏点击要素后的提示信息
    20. imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
    21. url: "your_map_url",
    22. }), //地图地址
    23. })
    24. // 隐藏左下角商标信息
    25. viewer._cesiumWidget._creditContainer.style.display = "none";
    26. // 隐藏底部时间轴
    27. viewer.timeline.container.style.display = "none";
    28. //开启深度检测
    29. viewer.scene.globe.depthTestAgainstTerrain = false;
    30. // 启用光照
    31. viewer.scene.globe.enableLighting = true;
    32. // 设置相机初始位置
    33. viewer.camera.setView({
    34. destination: Cesium.Cartesian3.fromDegrees(
    35. 110,
    36. 30,
    37. 10000
    38. ),
    39. // 设置相机方向,俯视和仰视的视角
    40. orientation: {
    41. heading: Cesium.Math.toRadians(0), //坐标系旋转0度
    42. pitch: Cesium.Math.toRadians(-90), //设置俯仰角度为-90度
    43. },
    44. });
    45. }
    46. render() {
    47. return (
    48. <div className='cesiumMap'>
    49. <div id="cesiumContainer">
    50. div>
    51. div>
    52. )
    53. }
    54. }

  • 相关阅读:
    用MiniPC搭建个人服务器
    mysql - <choose>多条件判断 (等同于switch,case,default)
    【拯救大学生计划】:我做了一个QQ分组神器
    地理位置数据存储方案——Redis GEO
    uboot启动流程-board_init_r函数执行过程
    chapter6——流水线的艺术
    从小码农到大厂Offer收割机
    在Mac M2本地注册GitLab runner
    MySQL ——多条件查询(like)
    坦克大战游戏开发中的设计模式总结
  • 原文地址:https://blog.csdn.net/StupidlyGrass/article/details/139586883