圆绘制示例
这个示例演示如何使用 DMap3D SDK 在地图上交互式绘制圆形。
效果预览
用户先点击确定圆心,移动鼠标调整半径,再次点击完成绘制。
完整代码
src/components/CircleDrawing.tsx
import { useEffect, useRef, useState } from 'react'
import * as Cesium from 'cesium'
import DMap3D from 'dmap3d'
import './CircleDrawing.css'
function CircleDrawing() {
const containerRef = useRef<HTMLDivElement>(null)
const viewerRef = useRef<Cesium.Viewer | null>(null)
const toolRef = useRef<any>(null)
const [isActive, setIsActive] = useState(false)
const [lastRadius, setLastRadius] = 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(116.4074, 39.9042, 5000),
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-45),
roll: 0,
},
})
// 创建圆绘制工具
const tool = new DMap3D.drawing.circle({
viewer,
style: {
fillColor: '#33fc05',
fillAlpha: 0.3,
outlineColor: '#FBFB00',
outlineWidth: 2,
outlineAlpha: 1.0,
},
clampToGround: true,
})
toolRef.current = tool
return () => {
tool.destroy()
viewer.destroy()
}
}, [])
const handleDraw = () => {
const tool = toolRef.current
if (!tool) return
tool.draw((entity: any, center: Cesium.Cartesian3, radius: number) => {
console.log('圆绘制完成,半径:', radius.toFixed(2), '米')
setLastRadius(radius)
setIsActive(false)
})
setIsActive(true)
}
const handleStop = () => {
toolRef.current?.deactivate()
setIsActive(false)
}
const handleClear = () => {
toolRef.current?.clear()
if (isActive) toolRef.current?.deactivate()
setIsActive(false)
setLastRadius(null)
}
// 从数据加载
const handleLoadData = () => {
const tool = toolRef.current
if (!tool) return
tool.loadFromData([116.4074, 39.9042, 0], 500) // 半径 500 米
setLastRadius(500)
}
return (
<div className="circle-drawing">
<div ref={containerRef} className="cesium-container" />
<div className="control-panel">
<h3>圆绘制</h3>
<p>点击确定圆心,移动确定半径,再次点击完成</p>
<div className="buttons">
<button onClick={handleDraw} disabled={isActive}>
{isActive ? '绘制中...' : '开始绘制'}
</button>
<button onClick={handleStop} disabled={!isActive}>停止</button>
<button onClick={handleClear}>清除</button>
</div>
<button className="load-btn" onClick={handleLoadData}>
加载示例圆(半径500米)
</button>
{lastRadius !== null && (
<div className="result">
<p>半径: {lastRadius.toFixed(2)} 米</p>
<p>面积: {(Math.PI * lastRadius * lastRadius).toFixed(2)} 平方米</p>
</div>
)}
</div>
</div>
)
}
export default CircleDrawing
样式文件
src/components/CircleDrawing.css
.circle-drawing {
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; }
.load-btn {
width: 100%; padding: 8px; border: 1px solid #1890ff; border-radius: 4px;
background: white; color: #1890ff; cursor: pointer; font-size: 14px;
margin-bottom: 15px;
}
.load-btn:hover { background: #e6f7ff; }
.result { border-top: 1px solid #e8e8e8; padding-top: 10px; }
.result p { margin: 5px 0; font-size: 14px; color: #333; }
关键代码说明
1. 创建圆绘制工具
const tool = new DMap3D.drawing.circle({
viewer,
style: {
fillColor: '#33fc05', // 填充颜色
fillAlpha: 0.3, // 填充透明度
outlineColor: '#FBFB00', // 边框颜色
outlineWidth: 2, // 边框宽度
},
clampToGround: true,
})
2. 绘制回调
tool.draw((entity, center, radius) => {
// center: Cesium.Cartesian3 圆心坐标
// radius: 半径(米)
console.log('半径:', radius, '米')
})
3. 从数据加载
// 经纬度 + 半径
tool.loadFromData([116.4074, 39.9042, 0], 500)
// Cartesian3 + 半径
tool.loadFromData(
Cesium.Cartesian3.fromDegrees(116.4074, 39.9042),
500
)
扩展功能
- 半径输入 - 通过输入框精确设定半径
- 缓冲区 - 结合缓冲区分析功能
- 同心圆 - 绘制多个同心圆
- 椭圆绘制 - 扩展为椭圆绘制