一、环境描述
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、创建项目
javascript
npx create-react-app react-test
2、启动项目
javascript
cd react-test
npm run start
3、安装Cesium
javascript
npm i cesium@1.62.0 --save
4、安装copy-webpack-plugin
javascript
npm i copy-webpack-plugin@5 -D
5、运行npm run eject
Cesium静态资源需要webpack配置,执行npm run eject可以生成webpack配置,运行前先查看当前git版本是否有提交,如果未提交,需要先本地提交git,否则npm run eject会执行失败。
(1)提交git(如果版本已经提交,无需执行)
javascript
git add .
git commit -m "React Init"
(2)执行npm run eject
javascript
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
三、webpack配置
1、修改webpack.config.js文件
javascript
// 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、路由配置
(1)路由文件配置
在src/创建一个名为router.js的文件(文件名称和位置可以自己规划)
javascript
// 引入组件
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文件配置
javascript
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.StrictMode> // 注意注释React严格模式
<RouterProvider router={router}>
<App />
</RouterProvider>
// </React.StrictMode>
);
reportWebVitals();
(3)App.js文件配置
javascript
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;
2、地图组件配置
(1)Header.js配置
javascript
// 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}
</li >
)
})
}
// 渲染页面
export default function Header({ clickMenu, active }) {
return (
<ul className="menuList">
<FilterData clickList={clickMenu} isActive={active} />
</ul>
)
}
(2)函数组件(CesiumMapFunction.js)
javascript
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)
javascript
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>
)
}
}