Skip to main content

Distance Measurement Example

This example demonstrates how to perform spatial distance measurement using the DMap3D SDK.

Preview

The user clicks multiple points on the map in sequence, with real-time display of distances between adjacent points and the total distance.

Complete Code

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

// Set initial view
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,
},
})

// Create spatial distance measurement tool
const tool = new DMap3D.measurement.spaceDistance(viewer, {
lineColor: '#ffff00',
pointColor: '#ff0000',
fontColor: '#ffffff',
fontSize: 16,
})
toolRef.current = tool

// Listen for measurement completion
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)
}

// Format distance
const formatDistance = (meters: number): string => {
if (meters >= 1000) {
return `${(meters / 1000).toFixed(2)} km`
}
return `${meters.toFixed(2)} m`
}

return (
<div className="distance-measurement">
<div ref={containerRef} className="cesium-container" />

<div className="control-panel">
<h3>Distance Measurement</h3>
<p>Left-click to add measurement points, right-click to finish</p>

<div className="buttons">
<button onClick={handleStart} disabled={isActive}>
{isActive ? 'Measuring...' : 'Start Measurement'}
</button>
<button onClick={handleStop} disabled={!isActive}>Stop</button>
<button onClick={handleClear}>Clear</button>
</div>

{totalDistance !== null && (
<div className="result">
<h4>Measurement Result</h4>
<p>Total Distance: {formatDistance(totalDistance)}</p>
</div>
)}

<div className="tip">
<h4>Measurement Types</h4>
<ul>
<li><strong>Spatial Distance</strong> - Straight-line distance between two points</li>
<li><strong>Horizontal Distance</strong> - Distance projected onto the horizontal plane</li>
<li><strong>Surface Distance</strong> - Distance along the terrain surface</li>
</ul>
</div>
</div>
</div>
)
}

export default DistanceMeasurement

Stylesheet

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;
}

Key Code Explanation

1. Create Distance Measurement Tool

const tool = new DMap3D.measurement.spaceDistance(viewer, {
lineColor: '#ffff00', // Measurement line color
pointColor: '#ff0000', // Measurement point color
fontColor: '#ffffff', // Label text color
fontSize: 16, // Label font size
})

DMap3D provides three types of distance measurement tools:

ToolDescription
DMap3D.measurement.spaceDistanceSpatial straight-line distance (multi-point polyline)
DMap3D.measurement.horizontalDistanceHorizontal projected distance (two points)
DMap3D.measurement.surfaceDistanceSurface distance (along terrain)

2. Activate and Deactivate

// Start measurement (enter interactive mode)
tool.activate()

// Stop measurement (exit interactive mode, keep results)
tool.deactivate()

// Clear all measurement results
tool.clear()

3. Listen for Measurement Completion

tool.onMeasureEnd((result) => {
console.log('Total distance:', result.totalDistance, 'meters')
})

Extended Features

  1. Unit Switching - Support meters, kilometers, miles, and other units
  2. Continuous Measurement - Measure multiple polyline segments and accumulate total distance
  3. Elevation Labels - Label the elevation at each measurement point
  4. Data Export - Export measurement point coordinates and distance data