Skip to main content

Create Your First App

This tutorial will guide you step by step through creating a complete DMap3D application, including creating a 3D globe, configuring basemaps, adding markers, and using SDK tools.

Prerequisites

Make sure you have completed the steps in the Installation Guide and your project is configured with Cesium and DMap3D.

Step 1: Create a Basic Scene

Create a React component to initialize the 3D globe:

src/App.tsx
import { useEffect, useRef } from 'react'
import * as Cesium from 'cesium'
import 'cesium/Build/Cesium/Widgets/widgets.css'

function App() {
const containerRef = useRef<HTMLDivElement>(null)
const viewerRef = useRef<Cesium.Viewer | null>(null)

useEffect(() => {
if (!containerRef.current || viewerRef.current) return

// Configure Cesium Ion Token (register at https://ion.cesium.com to obtain)
Cesium.Ion.defaultAccessToken = 'your-cesium-ion-token'

// Create Viewer
const viewer = new Cesium.Viewer(containerRef.current, {
animation: false, // Hide animation widget
timeline: false, // Hide timeline
fullscreenButton: false, // Hide fullscreen button
geocoder: false, // Hide search box
homeButton: false, // Hide Home button
sceneModePicker: false, // Hide scene mode picker
selectionIndicator: false, // Hide selection indicator
navigationHelpButton: false,
infoBox: false,
baseLayerPicker: false,
})
viewerRef.current = viewer

// Set initial view (panoramic view of China)
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(104.0, 35.0, 5000000),
})

return () => {
if (viewerRef.current) {
viewerRef.current.destroy()
viewerRef.current = null
}
}
}, [])

return <div ref={containerRef} style={{ width: '100%', height: '100vh' }} />
}

export default App

Plain HTML Method

If not using a framework, you can use plain HTML:

index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DMap3D First App</title>
<script src="https://unpkg.com/cesium/Build/Cesium/Cesium.js"></script>
<link rel="stylesheet" href="https://unpkg.com/cesium/Build/Cesium/Widgets/widgets.css">
<style>
html, body, #cesiumContainer {
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
Cesium.Ion.defaultAccessToken = 'your-cesium-ion-token'
const viewer = new Cesium.Viewer('cesiumContainer', {
animation: false,
timeline: false,
baseLayerPicker: false,
})
</script>
</body>
</html>

After launching, you will see a 3D globe that you can rotate by dragging with the mouse and zoom with the scroll wheel.

Step 2: Configure Tianditu Basemap

The default basemap is Bing Maps, which can be slow to access in China. It is recommended to use Tianditu (you need to register at the Tianditu website to obtain a Token):

Using Tianditu Basemap
const viewer = new Cesium.Viewer(containerRef.current, {
// ... other options
baseLayerPicker: false,
baseLayer: Cesium.ImageryLayer.fromProviderAsync(
new Cesium.WebMapTileServiceImageryProvider({
url: 'https://t0.tianditu.gov.cn/img_w/wmts?tk=YOUR_TIANDITU_TOKEN',
layer: 'img',
style: 'default',
tileMatrixSetID: 'w',
format: 'tiles',
maximumLevel: 18,
})
),
})
Tianditu Token

Visit the Tianditu Developer Platform to register and create an application to obtain a free Token.

Step 3: Add Terrain

Loading global terrain gives the earth's surface realistic elevation relief:

Load Global Terrain
const viewer = new Cesium.Viewer(containerRef.current, {
terrain: Cesium.Terrain.fromWorldTerrain(),
// ... other options
})

Or load dynamically after creation:

viewer.scene.setTerrain(Cesium.Terrain.fromWorldTerrain())

Step 4: Add Markers

Add some markers on the globe:

Add Markers
// Add point marker + text label
viewer.entities.add({
name: 'Beijing',
position: Cesium.Cartesian3.fromDegrees(116.4074, 39.9042),
point: {
pixelSize: 10,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
},
label: {
text: 'Beijing',
font: '14px sans-serif',
fillColor: Cesium.Color.WHITE,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
outlineColor: Cesium.Color.BLACK,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, -15),
},
})

// Fly to the marker
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(116.4074, 39.9042, 50000),
duration: 2.0,
})

Step 5: Use DMap3D SDK

Now import DMap3D and use measurement and drawing tools:

Distance Measurement

Add Distance Measurement
import DMap3D from 'dmap3d'

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

// Activate measurement (left-click to add points, right-click to finish)
distanceTool.activate()

// Listen for measurement completion
distanceTool.onMeasureEnd((result) => {
console.log('Total distance:', result.totalDistance, 'meters')
})

Polygon Drawing

Add Drawing Functionality
// Create polygon drawing tool
const polygonTool = new DMap3D.drawing.polygon({
viewer,
style: {
fillColor: '#0000FF',
fillAlpha: 0.3,
outlineColor: '#FFFFFF',
outlineWidth: 2,
},
clampToGround: true,
})

// Start drawing (left-click to add vertices, right-click to finish)
polygonTool.draw((entity, positions) => {
console.log('Drawing complete, vertex count:', positions.length)
})

Viewshed Analysis

Add Viewshed Analysis
// Create viewshed analysis tool
const viewshedTool = new DMap3D.analysis.viewshed(viewer, {
visibleLineColor: '#00ff00',
invisibleLineColor: '#ff0000',
})

// Activate analysis (click to set observation point)
viewshedTool.activate()

Step 6: Complete Example

Integrate all the above steps into a complete React component:

src/App.tsx
import { useEffect, useRef, useState } from 'react'
import * as Cesium from 'cesium'
import DMap3D from 'dmap3d'
import 'cesium/Build/Cesium/Widgets/widgets.css'

function App() {
const containerRef = useRef<HTMLDivElement>(null)
const viewerRef = useRef<Cesium.Viewer | null>(null)
const [activeTool, setActiveTool] = useState<string>('')

useEffect(() => {
if (!containerRef.current || viewerRef.current) return

Cesium.Ion.defaultAccessToken = 'your-cesium-ion-token'

const viewer = new Cesium.Viewer(containerRef.current, {
animation: false,
timeline: false,
fullscreenButton: false,
geocoder: false,
homeButton: false,
sceneModePicker: false,
selectionIndicator: false,
navigationHelpButton: false,
infoBox: false,
baseLayerPicker: false,
baseLayer: Cesium.ImageryLayer.fromProviderAsync(
new Cesium.WebMapTileServiceImageryProvider({
url: 'https://t0.tianditu.gov.cn/img_w/wmts?tk=YOUR_TOKEN',
layer: 'img',
style: 'default',
tileMatrixSetID: 'w',
format: 'tiles',
maximumLevel: 18,
})
),
terrain: Cesium.Terrain.fromWorldTerrain(),
})
viewerRef.current = viewer

// Add marker
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.4074, 39.9042),
point: { pixelSize: 10, color: Cesium.Color.RED },
label: {
text: 'Beijing',
font: '14px sans-serif',
fillColor: Cesium.Color.WHITE,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, -15),
},
})

viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(116.4074, 39.9042, 50000),
})

return () => {
viewer.destroy()
viewerRef.current = null
}
}, [])

// Distance measurement
const handleMeasureDistance = () => {
const viewer = viewerRef.current
if (!viewer) return
const tool = new DMap3D.measurement.spaceDistance(viewer, {
lineColor: '#ffff00',
pointColor: '#ff0000',
})
tool.activate()
setActiveTool('distance')
}

// Polygon drawing
const handleDrawPolygon = () => {
const viewer = viewerRef.current
if (!viewer) return
const tool = new DMap3D.drawing.polygon({
viewer,
style: { fillColor: '#0000FF', fillAlpha: 0.3 },
clampToGround: true,
})
tool.draw()
setActiveTool('polygon')
}

return (
<div style={{ position: 'relative', width: '100%', height: '100vh' }}>
<div ref={containerRef} style={{ width: '100%', height: '100%' }} />
<div style={{
position: 'absolute', top: 20, right: 20,
background: 'rgba(0,0,0,0.7)', padding: 16, borderRadius: 8,
color: '#fff',
}}>
<h3 style={{ margin: '0 0 12px 0' }}>Toolbar</h3>
<button onClick={handleMeasureDistance} style={btnStyle}>
Distance Measurement
</button>
<button onClick={handleDrawPolygon} style={btnStyle}>
Draw Polygon
</button>
{activeTool && <p style={{ marginTop: 8 }}>Active tool: {activeTool}</p>}
</div>
</div>
)
}

const btnStyle: React.CSSProperties = {
display: 'block', width: '100%', padding: '8px 16px',
marginBottom: 8, border: 'none', borderRadius: 4,
background: '#1890ff', color: '#fff', cursor: 'pointer',
}

export default App

Run the Application

Open your browser and you will see:

  1. A 3D globe with Tianditu basemap and global terrain
  2. A red marker at the Beijing location
  3. A toolbar in the upper right corner for distance measurement and polygon drawing

Controls

ActionMouse
Rotate globeHold left button and drag
ZoomScroll wheel
PanHold right button and drag
Tilt viewHold middle button and drag
Measure/DrawLeft-click to add points, right-click to finish

Next Steps

Congratulations on completing your first DMap3D application! Here's what you can do next: