Cut-Fill Analysis Example
This example demonstrates how to perform cut and fill volume calculations using the DMap3D SDK.
Preview
The user draws an analysis area, and the system automatically calculates the required cut and fill volumes, with visual result display.
Complete Code
src/components/CutFillAnalysis.tsx
import { useEffect, useRef, useState } from 'react'
import * as Cesium from 'cesium'
import DMap3D from 'dmap3d'
import './CutFillAnalysis.css'
interface CutFillResult {
cutVolume: number
fillVolume: number
baseHeight: number
minHeight: number
maxHeight: number
baseArea: number
}
function CutFillAnalysis() {
const containerRef = useRef<HTMLDivElement>(null)
const viewerRef = useRef<Cesium.Viewer | null>(null)
const toolRef = useRef<any>(null)
const [isActive, setIsActive] = useState(false)
const [result, setResult] = useState<CutFillResult | 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,
terrain: Cesium.Terrain.fromWorldTerrain(),
})
viewerRef.current = viewer
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(86.925, 27.988, 30000),
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-60),
roll: 0,
},
})
// Create cut-fill analysis tool
const tool = new DMap3D.analysis.cutFill(viewer, {
showTriangle: true,
showRangeBox: true,
showBasePlane: true,
showResultLabel: true,
})
toolRef.current = tool
tool.onAnalysisEnd((data: CutFillResult) => {
setIsActive(false)
setResult(data)
})
return () => {
tool.destroy()
viewer.destroy()
}
}, [])
const handleStart = () => {
toolRef.current?.activate()
setIsActive(true)
setResult(null)
}
const handleClear = () => {
toolRef.current?.deactivate()
toolRef.current?.clear()
setIsActive(false)
setResult(null)
}
return (
<div className="cut-fill-analysis">
<div ref={containerRef} className="cesium-container" />
<div className="control-panel">
<h3>Cut-Fill Analysis</h3>
<p>Draw an area to calculate cut and fill volumes</p>
<div className="buttons">
<button onClick={handleStart} disabled={isActive}>
{isActive ? 'Drawing...' : 'Start Analysis'}
</button>
<button onClick={handleClear}>Clear</button>
</div>
{result && (
<div className="result">
<h4>Analysis Result</h4>
<div className="result-item">
<span>Cut Volume:</span>
<span>{result.cutVolume.toFixed(2)} m3</span>
</div>
<div className="result-item">
<span>Fill Volume:</span>
<span>{result.fillVolume.toFixed(2)} m3</span>
</div>
<div className="result-item">
<span>Base Height:</span>
<span>{result.baseHeight.toFixed(2)} m</span>
</div>
<div className="result-item">
<span>Highest Point:</span>
<span>{result.maxHeight.toFixed(2)} m</span>
</div>
<div className="result-item">
<span>Lowest Point:</span>
<span>{result.minHeight.toFixed(2)} m</span>
</div>
<div className="result-item">
<span>Base Area:</span>
<span>{result.baseArea.toFixed(2)} sq m</span>
</div>
</div>
)}
</div>
</div>
)
}
export default CutFillAnalysis
Stylesheet
src/components/CutFillAnalysis.css
.cut-fill-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; }
.result { border-top: 1px solid #e8e8e8; padding-top: 15px; }
.result h4 { margin: 0 0 10px 0; font-size: 16px; }
.result-item { display: flex; justify-content: space-between; margin: 8px 0; font-size: 14px; }
Key Code Explanation
1. Create Cut-Fill Analysis Tool
const tool = new DMap3D.analysis.cutFill(viewer, {
showTriangle: true, // Show triangulated mesh
showRangeBox: true, // Show range box
showBasePlane: true, // Show base plane
showResultLabel: true, // Show result labels
})
2. Analysis Results
tool.onAnalysisEnd((result) => {
console.log('Cut volume:', result.cutVolume, 'm3')
console.log('Fill volume:', result.fillVolume, 'm3')
console.log('Base height:', result.baseHeight, 'm')
})
| Field | Description |
|---|---|
cutVolume | Volume to be excavated (m3) |
fillVolume | Volume to be filled (m3) |
baseHeight | Base plane height (m) |
baseArea | Base area (sq m) |