原文链接及内容

: 由于个人的Cesium Ion中没有官方示例中的数据,因此仅在官方提供的在线编辑器中进行了学习、修改。

实现效果如下视频所示:

示例代码如下:

1
2
3
4
5
6
7
8
9
<style>
@import url(../templates/bucket.css);
.cesium-performanceDisplay-defaultContainer {
top: 10px;
}
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>拼命加载数据中</h1></div>
<div id="toolbar"></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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/**
* 发电厂设计模型由 Bentley 软件公司提供
*/
const viewer = new Cesium.Viewer("cesiumContainer", {
geocoder: false,
homeButton: false,
sceneModePicker: false,
baseLayerPicker: false,
navigationHelpButton: false,
navigationInstructionsInitiallyVisible: false,
animation: false,
timeline: false,
fullscreenButton: false,
selectionIndicator: false,
skyBox: false,
shouldAnimate: true,
});

const scene = viewer.scene;

viewer.cesiumWidget.creditContainer.style.display = "none"; //隐藏版权信息
scene.debugShowFramesPerSecond = true; //添加帧速显示

viewer.clock.currentTime = Cesium.JulianDate.fromIso8601("2022-08-01T00:00:00Z");

let selectedFeature;
let picking = false;

Sandcastle.addToggleButton("按单个要素选择", false, function (checked) {
picking = checked;
if (!picking) {
unselectFeature(selectedFeature);
}
});

function selectFeature(feature) {
const element = feature.getProperty("element");
setElementColor(element, Cesium.Color.YELLOW);
selectedFeature = feature;
}

function unselectFeature(feature) {
if (!Cesium.defined(feature)) {
return;
}
const element = feature.getProperty("element");
setElementColor(element, Cesium.Color.WHITE);
if (feature === selectedFeature) {
selectedFeature = undefined;
}
}

const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(function (movement) {
if (!picking) {
return;
}

const feature = scene.pick(movement.endPosition);

unselectFeature(selectedFeature);

if (feature instanceof Cesium.Cesium3DTileFeature) {
selectFeature(feature);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

/**
* 在该数据集中,每个要素都有一个“element”属性,它是一个全局ID,
* 该属性用于在不同瓦片和LOD(Levels of Detail,多细节层次)之间关联要素。
* 这是在 3D Tiles 支持全局批次 ID 概念之前的一种临时解决方案:https://github.com/CesiumGS/3d-tiles/issues/265
*
* 多细节层次 —— 在显示网格时,根据摄像机距离物体的距离,来使用更多或者更少的几何体来对其进行显示。
* 详见:https://threejs.org/docs/#api/zh/objects/LOD
*/
const elementMap = {}; // 构建一个element属性到要素的映射。
const hiddenElements = [
112001, 113180, 131136, 113167, 71309, 109652, 111178, 113156, 113170, 124846,
114076, 131122, 113179, 114325, 131134, 113164, 113153, 113179, 109656, 114095,
114093, 39225, 39267, 113149, 113071, 112003, 39229, 113160, 39227, 39234,
113985, 39230, 112004, 39223,
];

function getElement(feature) {
return parseInt(feature.getProperty("element"), 10);
}

function setElementColor(element, color) {
const featuresToColor = elementMap[element];
const length = featuresToColor.length;
for (let i = 0; i < length; ++i) {
const feature = featuresToColor[i];
feature.color = Cesium.Color.clone(color, feature.color);
}
}

function unloadFeature(feature) {
unselectFeature(feature);
const element = getElement(feature);
const features = elementMap[element];
const index = features.indexOf(feature);
if (index > -1) {
features.splice(index, 1);
}
}

function loadFeature(feature) {
const element = getElement(feature);
let features = elementMap[element];
if (!Cesium.defined(features)) {
features = [];
elementMap[element] = features;
}
features.push(feature);

if (hiddenElements.indexOf(element) > -1) {
feature.show = false;
}
}

function processContentFeatures(content, callback) {
const featuresLength = content.featuresLength;
for (let i = 0; i < featuresLength; ++i) {
const feature = content.getFeature(i);
callback(feature);
}
}

function processTileFeatures(tile, callback) {
const content = tile.content;
const innerContents = content.innerContents;
if (Cesium.defined(innerContents)) {
const length = innerContents.length;
for (let i = 0; i < length; ++i) {
processContentFeatures(innerContents[i], callback);
}
} else {
processContentFeatures(content, callback);
}
}

try {
const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(2464651);
scene.primitives.add(tileset);

viewer.zoomTo(
tileset,
new Cesium.HeadingPitchRange(0.5, -0.2, tileset.boundingSphere.radius * 4.0),
);

tileset.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.REPLACE;
tileset.tileLoad.addEventListener(function (tile) {
processTileFeatures(tile, loadFeature);
});

tileset.tileUnload.addEventListener(function (tile) {
processTileFeatures(tile, unloadFeature);
});
} catch (err) {
ElMessage.error(`tileset数据加载出错: ${err}`);
}