原文链接及内容

效果如下视频所示:

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<style>
@import url(../templates/bucket.css);
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>加载中...</h1></div>
<div id="toolbar">
<table class="infoPanel">
<tbody>
<tr>
<td>左键单击添加顶点。</td>
</tr>
<tr>
<td>右键点击以开始绘制新形状。</td>
</tr>
</tbody>
</table>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
const viewer = new Cesium.Viewer("cesiumContainer", {
geocoder: false,
sceneModePicker: false,
homeButton: false,
navigationHelpButton: false,
baseLayerPicker: false,
navigationInstructionsInitiallyVisible: false,
fullscreenButton: false,
selectionIndicator: false,
skyBox: false,
timeline: false,
animation: false,
shouldAnimate: true,
infoBox: false,
terrain: Cesium.Terrain.fromWorldTerrain(),
});

//移除默认的双击行为
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
);

//创建一个白色的贴地的点
function createPoint(worldPosition) {
const point = viewer.entities.add({
position: worldPosition,
point: {
color: Cesium.Color.WHITE,
pixelSize: 5,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
});
return point;
}

let drawingMode = "line";
function drawShape(positionData) {
let shape;
if (drawingMode === "line") {
shape = viewer.entities.add({
polyline: {
positions: positionData,
clampToGround: true,
width: 3,
},
});
} else if (drawingMode === "polygon") {
shape = viewer.entities.add({
polygon: {
hierarchy: positionData,
material: new Cesium.ColorMaterialProperty(
Cesium.Color.WHITE.withAlpha(0.7)
),
},
});
}
return shape;
}

let activeShapePoints = [];
let activeShape;
let floatingPoint;
const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
//注册左键单击事件
handler.setInputAction(function (event) {
// 我们使用`viewer.scene.globe.pick`而非`viewer.camera.pickEllipsoid`,以确保在鼠标滑过地形时能获取正确的坐标点。
const ray = viewer.camera.getPickRay(event.position);
const earthPosition = viewer.scene.globe.pick(ray, viewer.scene);
// 如果我们的鼠标不在地球上,则 'earthPosition' 将未定义。
if (Cesium.defined(earthPosition)) {
if (activeShapePoints.length === 0) {
floatingPoint = createPoint(earthPosition);
activeShapePoints.push(earthPosition);
const dynamicPositions = new Cesium.CallbackProperty(function () {
if (drawingMode === "polygon") {
return new Cesium.PolygonHierarchy(activeShapePoints);
}
return activeShapePoints;
}, false);
activeShape = drawShape(dynamicPositions);
}
activeShapePoints.push(earthPosition);
createPoint(earthPosition);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

//注册鼠标移动事件
handler.setInputAction(function (event) {
if (Cesium.defined(floatingPoint)) {
const ray = viewer.camera.getPickRay(event.endPosition);
const newPosition = viewer.scene.globe.pick(ray, viewer.scene);
if (Cesium.defined(newPosition)) {
floatingPoint.position.setValue(newPosition);
activeShapePoints.pop();
activeShapePoints.push(newPosition);
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

// 重新绘制形状,使其不再动态,并删除动态形状。
function terminateShape() {
activeShapePoints.pop();
drawShape(activeShapePoints);
viewer.entities.remove(floatingPoint);
viewer.entities.remove(activeShape);
floatingPoint = undefined;
activeShape = undefined;
activeShapePoints = [];
}

//注册右击事件
handler.setInputAction(function (event) {
terminateShape();
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

const options = [
{
text: "绘制线",
onselect: function () {
if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) {
window.alert("此浏览器不支持在地形上(渲染)折线。");
}

terminateShape();
drawingMode = "line";
},
},
{
text: "绘制多边形",
onselect: function () {
terminateShape();
drawingMode = "polygon";
},
},
];

Sandcastle.addToolbarMenu(options);
// 放大到有山脉的区域
viewer.camera.lookAt(
Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0),
new Cesium.Cartesian3(5000.0, 5000.0, 5000.0)
);

viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);