距离测量示例
这个示例演示如何使用 DMap3D SDK 进行空间距离测量。
效果预览
用户在地图上依次点击多个点,实时显示相邻点之间的距离及总距离。
完整代码
src/components/DistanceMeasurement.tsx
import { useEffect, useRef, useState } from 'react'
import * as Cesium from 'cesium'
import DMap3D from 'dmap3d'
import './DistanceMeasurement.css'
function DistanceMeasurement() {
const containerRef = useRef<HTMLDivElement>(null)
const viewerRef = useRef<Cesium.Viewer | null>(null)
const toolRef = useRef<any>(null)
const [isActive, setIsActive] = useState(false)
const [totalDistance, setTotalDistance] = useState<number | null>(null)
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,
terrainProvider: new Cesium.EllipsoidTerrainProvider({}),
})
viewerRef.current = viewer
// 设置初始视角
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(112.94, 28.23, 5000),
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-45),
roll: 0,
},
})
// 创建空间距离测量工具
const tool = new DMap3D.measurement.spaceDistance(viewer, {
lineColor: '#ffff00',
pointColor: '#ff0000',
fontColor: '#ffffff',
fontSize: 16,
})
toolRef.current = tool
// 监听测量完成
tool.onMeasureEnd((result: { totalDistance: number }) => {
setIsActive(false)
setTotalDistance(result.totalDistance)
})
return () => {
tool.destroy()
viewer.destroy()
}
}, [])
const handleStart = () => {
const tool = toolRef.current
if (!tool) return
tool.activate()
setIsActive(true)
setTotalDistance(null)
}
const handleStop = () => {
const tool = toolRef.current
if (!tool) return
tool.deactivate()
setIsActive(false)
}
const handleClear = () => {
const tool = toolRef.current
if (!tool) return
tool.clear()
setTotalDistance(null)
setIsActive(false)
}
// 格式化距离
const formatDistance = (meters: number): string => {
if (meters >= 1000) {
return `${(meters / 1000).toFixed(2)} 公里`
}
return `${meters.toFixed(2)} 米`
}
return (
<div className="distance-measurement">
<div ref={containerRef} className="cesium-container" />
<div className="control-panel">
<h3>距离测量</h3>
<p>左键点击添加测量点,右键结束测量</p>
<div className="buttons">
<button onClick={handleStart} disabled={isActive}>
{isActive ? '测量中...' : '开始测量'}
</button>
<button onClick={handleStop} disabled={!isActive}>停止</button>
<button onClick={handleClear}>清除</button>
</div>
{totalDistance !== null && (
<div className="result">
<h4>测量结果</h4>
<p>总距离: {formatDistance(totalDistance)}</p>
</div>
)}
<div className="tip">
<h4>测量类型</h4>
<ul>
<li><strong>空间距离</strong> - 两点间直线距离</li>
<li><strong>水平距离</strong> - 投影到水平面的距离</li>
<li><strong>贴地距离</strong> - 沿地形表面的距离</li>
</ul>
</div>
</div>
</div>
)
}
export default DistanceMeasurement
样式文件
src/components/DistanceMeasurement.css
.distance-measurement {
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: 250px;
}
.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: 8px;
margin-bottom: 15px;
}
.buttons button {
flex: 1;
padding: 8px 12px;
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;
}
.result {
border-top: 1px solid #e8e8e8;
padding-top: 15px;
margin-bottom: 15px;
}
.result h4 {
margin: 0 0 10px 0;
font-size: 16px;
}
.result p {
margin: 5px 0;
font-size: 14px;
color: #333;
}
.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.measurement.spaceDistance(viewer, {
lineColor: '#ffff00', // 测量线颜色
pointColor: '#ff0000', // 测量点颜色
fontColor: '#ffffff', // 标签文字颜色
fontSize: 16, // 标签字号
})
DMap3D 提供三种距离测量工具:
| 工具 | 说明 |
|---|---|
DMap3D.measurement.spaceDistance | 空间直线距离(多点折线) |
DMap3D.measurement.horizontalDistance | 水平投影距离(两点) |
DMap3D.measurement.surfaceDistance | 贴地距离(沿地形) |
2. 激活与停用
// 开始测量(进入交互模式)
tool.activate()
// 停止测量(退出交互模式,保留结果)
tool.deactivate()
// 清除所有测量结果
tool.clear()
3. 监听测量完成
tool.onMeasureEnd((result) => {
console.log('总距离:', result.totalDistance, '米')
})
扩展功能
- 单位切换 - 支持米、公里、英里等单位
- 连续测量 - 测量多段折线并累计总距离
- 海拔标注 - 在每个测量点标注海拔高度
- 导出数据 - 导出测量点坐标和距离数据