Circle Drawing Example
This example demonstrates how to interactively draw circles on the map using the DMap3D SDK.
Preview
The user first clicks to set the center, moves the mouse to adjust the radius, and clicks again to finish drawing.
Complete Code
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,
},
})
// Create circle drawing tool
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('Circle drawing complete, radius:', radius.toFixed(2), 'm')
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)
}
// Load from data
const handleLoadData = () => {
const tool = toolRef.current
if (!tool) return
tool.loadFromData([116.4074, 39.9042, 0], 500) // Radius 500 m
setLastRadius(500)
}
return (
<div className="circle-drawing">
<div ref={containerRef} className="cesium-container" />
<div className="control-panel">
<h3>Circle Drawing</h3>
<p>Click to set center, move to set radius, click again to finish</p>
<div className="buttons">
<button onClick={handleDraw} disabled={isActive}>
{isActive ? 'Drawing...' : 'Start Drawing'}
</button>
<button onClick={handleStop} disabled={!isActive}>Stop</button>
<button onClick={handleClear}>Clear</button>
</div>
<button className="load-btn" onClick={handleLoadData}>
Load Sample Circle (radius 500m)
</button>
{lastRadius !== null && (
<div className="result">
<p>Radius: {lastRadius.toFixed(2)} m</p>
<p>Area: {(Math.PI * lastRadius * lastRadius).toFixed(2)} sq m</p>
</div>
)}
</div>
</div>
)
}
export default CircleDrawing
Stylesheet
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; }
Key Code Explanation
1. Create Circle Drawing Tool
const tool = new DMap3D.drawing.circle({
viewer,
style: {
fillColor: '#33fc05', // Fill color
fillAlpha: 0.3, // Fill opacity
outlineColor: '#FBFB00', // Outline color
outlineWidth: 2, // Outline width
},
clampToGround: true,
})
2. Drawing Callback
tool.draw((entity, center, radius) => {
// center: Cesium.Cartesian3 center coordinate
// radius: Radius (meters)
console.log('Radius:', radius, 'm')
})
3. Load from Data
// Longitude-latitude + radius
tool.loadFromData([116.4074, 39.9042, 0], 500)
// Cartesian3 + radius
tool.loadFromData(
Cesium.Cartesian3.fromDegrees(116.4074, 39.9042),
500
)
Extended Features
- Radius Input - Set precise radius via input box
- Buffer Zone - Combine with buffer analysis functionality
- Concentric Circles - Draw multiple concentric circles
- Ellipse Drawing - Extend to ellipse drawing