React集成Cesium地图需要注意软件兼容性问题,可以从官网或者百度文章查询React和Cesium地图的版本兼容性,
(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
npx create-react-app react-test
- cd react-test
- npm run start
npm i cesium@1.62.0 --save
npm i copy-webpack-plugin@5 -D
Cesium静态资源需要webpack配置,执行npm run eject可以生成webpack配置,运行前先查看当前git版本是否有提交,如果未提交,需要先本地提交git,否则npm run eject会执行失败。
(1)提交git(如果版本已经提交,无需执行)
- git add .
- git commit -m "React Init"
(2)执行npm run eject
- npm run eject
-
- // 执行成功后,生成的文件列表
- // config/
- // jest/
- // webpack/
- // env.js
- // getHttpsConfig.js
- // modules.js
- // paths.js
- // webpack.config.js
- // webpackDevServer.config.js
-
- // scripts/
- // build.js
- // start.js
- // test.js
- // 1、引入copy-webpack-plugin
- const CopyWebpackPlugin = require('copy-webpack-plugin');
-
- // 2、引入Cesium静态资源
- const cesiumSource = "node_modules/cesium/Source";
- const cesiumWorkers = '../Build/Cesium/Workers';
- const fileFolder = "src";
-
- // 3、在return下的output对象中添加配置
- sourcePrefix: '',
-
- // 4、在return下的output对象后添加配置(与output对象同级)
- amd: {
- toUrlUndefined: true
- },
-
- // 5、在return下的resolve对象下的alias对象中添加配置
- cesium: path.resolve(cesiumSource),
-
- // 6、在return下的module对象中添加配置
- unknownContextCritical: false,
-
- // 7、在return下的plugins数组中添加配置
- new CopyWebpackPlugin([{
- from: path.join(cesiumSource, cesiumWorkers),
- to: "Workers"
- }]),
- new CopyWebpackPlugin([{
- from: path.join(cesiumSource, 'Assets'),
- to: 'Assets'
- }]),
- new CopyWebpackPlugin([{
- from: path.join(cesiumSource, 'Widgets'),
- to: 'Widgets'
- }]),
-
- new CopyWebpackPlugin([
- { from: path.join(fileFolder, 'static'), to: 'Static' }
- ]),
- new webpack.DefinePlugin({
- CESIUM_BASE_URL: JSON.stringify('')
- }),
(1)路由文件配置
在src/创建一个名为router.js的文件(文件名称和位置可以自己规划)
- // 引入组件
- import App from "./App";
- import CesiumMapFunction from './components/CesiumMapFunction';
- import CesiumMapClass from './components/CesiumMapClass';
-
- import { createBrowserRouter } from "react-router-dom";
-
- const router = createBrowserRouter([
- {
- path: "/",
- element: <App />,
- children: [
- {
- path: "",
- element: <CesiumMapFunction />
- },
- {
- path: "/cesiumFunction",
- element: <CesiumMapFunction />
- },
- {
- path: "/cesiumClass",
- element: <CesiumMapClass />
- }
- ]
- },
- ])
-
- export default router
(2)index.js文件配置
- import React from 'react';
- import ReactDOM from 'react-dom/client';
- import './index.css';
- import App from './App';
- import reportWebVitals from './reportWebVitals';
- import { RouterProvider } from 'react-router-dom';
- import router from './router';
-
- const root = ReactDOM.createRoot(document.getElementById('root'));
- root.render(
- //
// 注意注释React严格模式 - <RouterProvider router={router}>
- <App />
- RouterProvider>
- //
- );
-
- reportWebVitals();
(3)App.js文件配置
- import './App.css';
- import Header from './components/Header';
- import { Outlet, useNavigate } from 'react-router-dom';
- import { useState } from 'react';
-
- function App() {
- const [isActive, setIsActive] = useState(1)
- const navigate = useNavigate()
-
- function clickMenu(path, menuId) {
- if (isActive === menuId) {
- return
- }
- // 保存当前点击的菜单ID
- setIsActive(menuId)
- // 跳转路由
- navigate(path)
- }
-
- return (
- <div className="App">
- <Header clickMenu={clickMenu} active={isActive}>Header>
- <div className="content">
- <Outlet />
- div>
- div>
- );
- }
-
- export default App;
(1)Header.js配置
- // css文件
- import "./css/Header.css"
-
- // 数据来源
- const menuData = [
- {
- id: 1,
- label: "函数组件Cesium",
- path: "/cesiumFunction"
- },
- {
- id: 2,
- label: "类组件Cesium",
- path: "/cesiumClass"
- }
- ]
-
- // 数据过滤
- function FilterData({ clickList, isActive }) {
- return menuData.map(row => {
- return (
- <li className={isActive === row.id ? 'isActive' : ''} onClick={() => { clickList(row.path, row.id) }} key={row.id} >
- {row.label}
-
- )
- })
- }
-
- // 渲染页面
- export default function Header({ clickMenu, active }) {
- return (
- <ul className="menuList">
- <FilterData clickList={clickMenu} isActive={active} />
- ul>
- )
- }
(2)函数组件(CesiumMapFunction.js)
- import Cesium from 'cesium/Cesium'
- import 'cesium/Widgets/widgets.css'
- import { useEffect } from "react";
- import "./css/CesiumMap.css"
-
- export default function CesiumMapFunction() {
-
- useEffect(() => {
- Cesium.Ion.defaultAccessToken = "your_map_token";
-
- // 初始化Cesium
- const viewer = new Cesium.Viewer('cesiumContainer', {
- geocoder: false, //右上角搜索
- homeButton: false, //右上角home
- sceneModePicker: false, //右上角2D/3D切换
- baseLayerPicker: false, //右上角地形
- navigationHelpButton: false, //右上角帮助
- animation: false, //左下角圆盘动画控件
- timeline: true, //底部时间轴
- fullscreenButton: false, //右下角全屏控件
- vrButton: false, //如果设置为true,将创建VRButton小部件。
- scene3DOnly: false, // 每个几何实例仅以3D渲染以节省GPU内存
- infoBox: false, //隐藏点击要素后的提示信息
- imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
- url: "your_map_url",
- }), //地图地址
- })
-
- // 隐藏左下角商标信息
- viewer._cesiumWidget._creditContainer.style.display = "none";
- // 隐藏底部时间轴
- viewer.timeline.container.style.display = "none";
- //开启深度检测
- viewer.scene.globe.depthTestAgainstTerrain = false;
- // 启用光照
- viewer.scene.globe.enableLighting = true;
-
- // 设置相机初始位置
- viewer.camera.setView({
- destination: Cesium.Cartesian3.fromDegrees(
- 110,
- 30,
- 10000
- ),
- // 设置相机方向,俯视和仰视的视角
- orientation: {
- heading: Cesium.Math.toRadians(0), //坐标系旋转0度
- pitch: Cesium.Math.toRadians(-90), //设置俯仰角度为-90度
- },
- });
-
- return () => {
- console.log("组件销毁前执行")
- }
- }, [])
-
- return (
- <div className='cesiumMap'>
- <div id="cesiumContainer" />
- div>
- );
- }
(3)类组件(CesiumMapClass.js)
- import React, { Component } from 'react'
- import Cesium from 'cesium/Cesium'
- import 'cesium/Widgets/widgets.css'
- import './css/CesiumMap.css'
-
- Cesium.Ion.defaultAccessToken = "your_map_token"
-
- export default class App extends Component {
- componentDidMount() {
- const viewer = new Cesium.Viewer("cesiumContainer", {
- geocoder: false, //右上角搜索
- homeButton: false, //右上角home
- sceneModePicker: false, //右上角2D/3D切换
- baseLayerPicker: false, //右上角地形
- navigationHelpButton: false, //右上角帮助
- animation: false, //左下角圆盘动画控件
- timeline: true, //底部时间轴
- fullscreenButton: false, //右下角全屏控件
- vrButton: false, //如果设置为true,将创建VRButton小部件。
- scene3DOnly: false, // 每个几何实例仅以3D渲染以节省GPU内存
- infoBox: false, //隐藏点击要素后的提示信息
- imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
- url: "your_map_url",
- }), //地图地址
- })
-
- // 隐藏左下角商标信息
- viewer._cesiumWidget._creditContainer.style.display = "none";
- // 隐藏底部时间轴
- viewer.timeline.container.style.display = "none";
- //开启深度检测
- viewer.scene.globe.depthTestAgainstTerrain = false;
- // 启用光照
- viewer.scene.globe.enableLighting = true;
-
- // 设置相机初始位置
- viewer.camera.setView({
- destination: Cesium.Cartesian3.fromDegrees(
- 110,
- 30,
- 10000
- ),
- // 设置相机方向,俯视和仰视的视角
- orientation: {
- heading: Cesium.Math.toRadians(0), //坐标系旋转0度
- pitch: Cesium.Math.toRadians(-90), //设置俯仰角度为-90度
- },
- });
- }
- render() {
- return (
- <div className='cesiumMap'>
- <div id="cesiumContainer">
- div>
- div>
- )
- }
- }