原文链接及内容

效果如下图所示:可以单击下拉框选项,到指定地点查看。

示例代码如下:

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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
// 在创建Viewer实例对象前,将椭球体设置为月球。
Cesium.Ellipsoid.default = Cesium.Ellipsoid.MOON;

/**
* 这里将地形provider和baseLayer(基础图层)都设置为false
*/
const viewer = new Cesium.Viewer("cesiumContainer", {
geocoder: false,
homeButton: false,
sceneModePicker: false,
navigationHelpButton: false,
navigationInstructionsInitiallyVisible: false,
animation: false,
timeline: false,
fullscreenButton: false,
skyBox: false,
shouldAnimate: true,
baseLayerPicker: false,
terrainProvider: false,
baseLayer: false,
shadows: true,
});
viewer.cesiumWidget.creditContainer.style.display = "none";

const scene = viewer.scene;

// 添加月球地形3D Tiles
try {
const tileset1 = await Cesium.Cesium3DTileset.fromIonAssetId(2684829, {
// Allow clamp to 3D Tiles,允许贴合到3DTiles上
/**
* enableCollision:当设置为 true 时,启用相机或 CPU 拾取的碰撞检测。
* 若此选项为 true 且 ScreenSpaceCameraController#enableCollisionDetection 为真,
* 相机将被阻止穿透瓦片集表面下方。
*/
enableCollision: true,
});
viewer.scene.primitives.add(tileset1);
} catch (error) {
console.log(`加载瓦片集出错: ${error}`);
}

// 边界数据来自 https://wms.lroc.asu.edu/lroc/view_rdr/SHAPEFILE_LROC_GLOBAL_MARE
const boundariesResource = await Cesium.IonResource.fromAssetId(2683530);
const boundarySource = await Cesium.GeoJsonDataSource.load(boundariesResource, {
clampToGround: true,
fill: Cesium.Color.fromBytes(26, 106, 113).withAlpha(0.6),
});
boundarySource.show = false;
viewer.dataSources.add(boundarySource);

/**
* 可能的 Artemis 3 着陆地点。
* 数据来自 https://files.actgate.com/lunar/A3_Named_regions.geojson
*/
const artemis3resource = await Cesium.IonResource.fromAssetId(2683531);
const artemis3Source = await Cesium.GeoJsonDataSource.load(artemis3resource, {
clampToGround: true,
fill: Cesium.Color.fromBytes(243, 242, 99).withAlpha(0.6),
});
artemis3Source.show = false;
viewer.dataSources.add(artemis3Source);

// 位置信息由 https://www.sciencedirect.com/science/article/abs/pii/S0019103516301518?via%3Dihub 提供
const pointsOfInterest = [
{
text: "阿波罗11号",
latitude: 0.67416,
longitude: 23.47315,
},
{
text: "阿波罗14号",
latitude: -3.64417,
longitude: 342.52135,
},
{
text: "阿波罗15号",
latitude: 26.13341,
longitude: 3.6285,
},
{
text: "月球车1号",
latitude: 38.2378,
longitude: -35.0017,
},
{
text: "月球车2号",
latitude: 25.83232,
longitude: 30.92215,
},
];

for (const poi of pointsOfInterest) {
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(poi.longitude, poi.latitude),
label: {
text: poi.text,
font: "14pt Verdana",
outlineColor: Cesium.Color.DARKSLATEGREY,
outlineWidth: 2,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
pixelOffset: new Cesium.Cartesian2(0, -22),
scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e7, 0.5),
translucencyByDistance: new Cesium.NearFarScalar(2.5e7, 1.0, 4.0e7, 0.0),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: new Cesium.CallbackProperty(() => {
return Cesium.Cartesian3.magnitude(scene.camera.positionWC);
}, false),
},
point: {
pixelSize: 10,
color: Cesium.Color.fromBytes(243, 242, 99),
outlineColor: Cesium.Color.fromBytes(219, 218, 111),
outlineWidth: 2,
scaleByDistance: new Cesium.NearFarScalar(1.5e3, 1.0, 4.0e7, 0.1),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: new Cesium.CallbackProperty(() => {
return Cesium.Cartesian3.magnitude(scene.camera.positionWC);
}, false),
},
});
}

const seaOfTranquility = {
destination: new Cesium.Cartesian3(
2134594.9298812235,
1256488.0678322134,
379606.9284823841
),
orientation: {
direction: new Cesium.Cartesian3(
-0.8518395698371783,
-0.5014189063342804,
-0.1514873843927112
),
up: new Cesium.Cartesian3(
-0.13054959630640847,
-0.07684549781463353,
0.9884591910493093
),
},
easingFunction: Cesium.EasingFunction.LINEAR_NONE,
};

const apollo11 = {
destination: new Cesium.Cartesian3(
1609100.311044896,
733266.0643925276,
53608.976740262646
),
orientation: {
direction: new Cesium.Cartesian3(
-0.41704286323660256,
-0.7222280712427744,
-0.5517806297183315
),
up: new Cesium.Cartesian3(
0.8621189850799429,
-0.12210806245903304,
-0.49177278965720556
),
},
easingFunction: Cesium.EasingFunction.LINEAR_NONE,
};

const copernicus = {
destination: new Cesium.Cartesian3(
1613572.8201475781,
-677039.3827805589,
339559.7958496013
),
orientation: {
direction: new Cesium.Cartesian3(
-0.10007925201262617,
0.8771366500325052,
-0.4696971795597116
),
up: new Cesium.Cartesian3(
0.9948921707513932,
0.08196514973381885,
-0.058917593354560566
),
},
easingFunction: Cesium.EasingFunction.LINEAR_NONE,
};

const tycho = {
destination: new Cesium.Cartesian3(
1368413.3560818078,
-166198.00035620513,
-1203576.7397013502
),
orientation: {
direction: new Cesium.Cartesian3(
-0.8601315724135887,
-0.5073902275496569,
0.05223825345888711
),
up: new Cesium.Cartesian3(
0.2639103814694499,
-0.5303301783281616,
-0.8056681776681204
),
},
easingFunction: Cesium.EasingFunction.LINEAR_NONE,
};

const shackleton = {
destination: Cesium.Rectangle.fromBoundingSphere(
new Cesium.BoundingSphere(
new Cesium.Cartesian3(
-17505.087036391753,
38147.40236305639,
-1769721.5748224584
),
40000.0
)
),
orientation: {
direction: new Cesium.Cartesian3(
0.2568703591904826,
-0.6405212914728244,
0.7237058060699372
),
up: new Cesium.Cartesian3(
0.26770932874967773,
-0.6723714327527822,
-0.6901075073627064
),
},
easingFunction: Cesium.EasingFunction.LINEAR_NONE,
};

const camera = viewer.scene.camera;
const rotationSpeed = Cesium.Math.toRadians(0.1);
const removeRotation = viewer.scene.postRender.addEventListener(function (
scene,
time
) {
viewer.scene.camera.rotateRight(rotationSpeed);
});

const options1 = [
{
text: "飞往...",
onselect: () => {},
},
{
text: "月球上的静海(Mare Tranquillitatis)",
onselect: function () {
removeRotation();
scene.camera.flyTo(seaOfTranquility);
artemis3Source.show = false;
},
},
{
text: "阿波罗11号登陆点",
onselect: () => {
removeRotation();
scene.camera.flyTo(apollo11);
artemis3Source.show = false;
},
},
{
text: "哥白尼环形山",
onselect: () => {
removeRotation();
scene.camera.flyTo(copernicus);
artemis3Source.show = false;
},
},
{
text: "第谷环形山",
onselect: () => {
removeRotation();
scene.camera.flyTo(tycho);
artemis3Source.show = false;
},
},
{
text: "沙克尔顿环形山(南极)及阿耳忒弥斯3号登陆选项",
onselect: () => {
removeRotation();
scene.camera.flyTo(shackleton);
artemis3Source.show = true;
},
},
];
Sandcastle.addToolbarMenu(options1);

Sandcastle.addToggleButton("Show Mare Boundaries", false, function (checked) {
boundarySource.show = checked;
});

/**
* 首次加载时旋转月球,但在输入(左键单击、右键单击,中键单击、鼠标滚轮滚动)时禁止月球旋转
*/
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(
() => removeRotation(),
Cesium.ScreenSpaceEventType.LEFT_DOWN
);
handler.setInputAction(
() => removeRotation(),
Cesium.ScreenSpaceEventType.RIGHT_DOWN
);
handler.setInputAction(
() => removeRotation(),
Cesium.ScreenSpaceEventType.MIDDLE_DOWN
);
handler.setInputAction(
() => removeRotation(),
Cesium.ScreenSpaceEventType.WHEEL
);