压平分析示例
这个示例演示如何使用 DMap3D SDK 对 3DTiles 模型进行区域压平。
效果预览
用户在 3DTiles 模型上绘制多边形区域,该区域内的模型被压平到指定高度,支持动态调整压平高度。
完整代码
src/components/FlattenAnalysis.tsx
import { useEffect, useRef, useState } from 'react'
import * as Cesium from 'cesium'
import DMap3D from 'dmap3d'
import './FlattenAnalysis.css'
function FlattenAnalysis() {
const containerRef = useRef<HTMLDivElement>(null)
const viewerRef = useRef<Cesium.Viewer | null>(null)
const toolRef = useRef<any>(null)
const tilesetRef = useRef<Cesium.Cesium3DTileset | null>(null)
const [isActive, setIsActive] = useState(false)
const [height, setHeight] = useState(0)
useEffect(() => {
if (!containerRef.current) return
Cesium.Ion.defaultAccessToken = 'your-cesium-ion-token'
const viewer = new Cesium.Viewer(containerRef.current, {
animation: false,
fullscreenButton: false,
geocoder: false,
homeButton: false,
sceneModePicker: false,
selectionIndicator: false,
timeline: false,
navigationHelpButton: false,
infoBox: false,
baseLayerPicker: false,
terrain: Cesium.Terrain.fromWorldTerrain(),
})
viewerRef.current = viewer
// 加载 3DTiles 模型
const loadTileset = async () => {
const tileset = await Cesium.Cesium3DTileset.fromUrl(
'/3DTiles/model/tileset.json'
)
viewer.scene.primitives.add(tileset)
viewer.zoomTo(tileset)
tilesetRef.current = tileset
}
loadTileset()
// 创建压平工具
const tool = new DMap3D.analysis.flattenAnalysis(viewer)
toolRef.current = tool
return () => {
tool.destroy()
viewer.destroy()
}
}, [])
const handleStart = () => {
const tool = toolRef.current
const tileset = tilesetRef.current
if (!tool || !tileset) return
tool.activate(tileset, height)
setIsActive(true)
}
const handleClear = () => {
toolRef.current?.clear()
setIsActive(false)
}
const handleHeightChange = (value: number) => {
setHeight(value)
if (isActive) {
toolRef.current?.setHeight(value)
}
}
return (
<div className="flatten-analysis">
<div ref={containerRef} className="cesium-container" />
<div className="control-panel">
<h3>压平分析</h3>
<p>在 3DTiles 模型上绘制区域进行压平</p>
<div className="buttons">
<button onClick={handleStart} disabled={isActive}>
{isActive ? '已激活' : '开始压平'}
</button>
<button onClick={handleClear}>清除</button>
</div>
<div className="settings">
<div className="setting-item">
<label>压平高度: {height} 米</label>
<input type="range" min="-50" max="50" value={height}
onChange={(e) => handleHeightChange(Number(e.target.value))} />
</div>
</div>
<div className="tip">
<h4>说明</h4>
<ul>
<li>需要先加载 3DTiles 模型</li>
<li>绘制多边形区域后自动压平</li>
<li>高度值为相对多边形中心的偏移</li>
</ul>
</div>
</div>
</div>
)
}
export default FlattenAnalysis
样式文件
src/components/FlattenAnalysis.css
.flatten-analysis { position: relative; width: 100%; height: 100vh; }
.cesium-container { width: 100%; height: 100%; }
.control-panel {
position: absolute; top: 20px; right: 20px;
background: rgba(255, 255, 255, 0.95); padding: 20px;
border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); min-width: 260px;
}
.control-panel h3 { margin: 0 0 10px 0; font-size: 18px; }
.control-panel p { margin: 0 0 15px 0; color: #666; font-size: 14px; }
.buttons { display: flex; gap: 10px; margin-bottom: 15px; }
.buttons button {
flex: 1; padding: 8px 16px; border: none; border-radius: 4px;
background: #1890ff; color: white; cursor: pointer; font-size: 14px;
}
.buttons button:hover { background: #40a9ff; }
.buttons button:disabled { background: #d9d9d9; cursor: not-allowed; }
.settings { border-top: 1px solid #e8e8e8; padding-top: 15px; margin-bottom: 15px; }
.setting-item label { display: block; font-size: 13px; color: #333; margin-bottom: 4px; }
.setting-item input[type="range"] { width: 100%; }
.tip { border-top: 1px solid #e8e8e8; padding-top: 15px; }
.tip h4 { margin: 0 0 8px 0; font-size: 14px; color: #666; }
.tip ul { padding-left: 20px; margin: 0; }
.tip li { font-size: 13px; margin: 4px 0; color: #666; }
关键代码说明
1. 创建压平工具
const tool = new DMap3D.analysis.flattenAnalysis(viewer)
2. 激活压平
// tileset: 3DTiles 模型实例
// height: 压平高度偏移(米)
tool.activate(tileset, height)
3. 动态调整高度
tool.setHeight(10) // 正值向上偏移,负值向下
4. 前提条件
压平分析需要已加载的 3DTiles 模型:
const tileset = await Cesium.Cesium3DTileset.fromUrl('/3DTiles/model/tileset.json')
viewer.scene.primitives.add(tileset)