Skip to main content

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')
})
FieldDescription
cutVolumeVolume to be excavated (m3)
fillVolumeVolume to be filled (m3)
baseHeightBase plane height (m)
baseAreaBase area (sq m)