原文链接及内容

示例介绍:结合 Bentley iTwin Platform 的数据类型,展示地理空间要素(GeoJSON格式的点、线、面)、现实网格(Reality Mesh)和点云数据(Point Cloud),并提供交互功能,如切换图层显示和相机视角控制。

示例运行效果如下图所示:

地图采用的是:Bing Maps Roads,则选取了选择器中的第3种类型地图,具体如下图所示:

代码如下:

1
2
viewer.baseLayerPicker.viewModel.selectedImagery =
viewer.baseLayerPicker.viewModel.imageryProviderViewModels[2];

示例代码如下:

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
/**
* 生成一个共享密钥,用于在没有 OAuth 的情况下访问 iTwin
* https://developer.bentley.com/apis/access-control-v2/operations/create-itwin-share/
*/
Cesium.ITwinPlatform.defaultShareKey =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpVHdpbklkIjoiMDRiYTcyNWYtZjNjMC00ZjMwLTgwMTQtYTQ0ODhjYmQ2MTJkIiwiaWQiOiJkNzNhODQzMC1iZWNiLTQxMTQtYThjYy04NmIxZGMzNGYzMjUiLCJleHAiOjE3NzcwNTU3Njl9.ySsHT7VcVZDTPBhrnzqRIQMaLwjD6p3mPyGCHUI0awA";

/**
* 如需使用其他身份验证方式,请访问 https://developer.bentley.com/apis/overview/authorization/。
* 然后按如下方式设置您的访问令牌:Cesium.ITwinPlatform.defaultAccessToken = 'your token'
*/
const iTwinId = "04ba725f-f3c0-4f30-8014-a4488cbd612d";

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: true,
terrain: Cesium.Terrain.fromWorldTerrain(),
});

/**
* selectedImagery:选中的影像图层
* imageryProviderViewModels:可用于影像选择的 ProviderViewModel 实例数组
*
* 这里默认选择选择器中第3个数据源:Bing Maps Roads。
* 具体参考:https://cesium.com/learn/cesiumjs/ref-doc/BaseLayerPicker.html
*/
viewer.baseLayerPicker.viewModel.selectedImagery =
viewer.baseLayerPicker.viewModel.imageryProviderViewModels[2];

// 鸟瞰视图
const birdsEyeView = {
destination: new Cesium.Cartesian3(
-1525359.4318772827,
6191643.528984093,
148851.5321709012
),
orientation: new Cesium.HeadingPitchRoll(
0.16657338935967037,
-0.7943050121851765,
6.283180723449992
),
duration: 0,
easingFunction: Cesium.EasingFunction.LINEAR_NONE,
};
viewer.scene.camera.flyTo(birdsEyeView);

// 加载要素服务 geojson 文件:分别为点、线、面类型的数据
const points = await Cesium.ITwinData.loadGeospatialFeatures(
iTwinId,
"2380dc1b-1dac-4709-aa5c-f6cb38c4e9f5"
);
const lines = await Cesium.ITwinData.loadGeospatialFeatures(
iTwinId,
"613d2310-4d01-43b7-bc92-873a2ca4a4a0"
);
const areas = await Cesium.ITwinData.loadGeospatialFeatures(
iTwinId,
"93e7ef51-5210-49f2-92a3-c7f6685e102f"
);

// 样式化点和线要素
// 使用 Cesium.PinBuilder 创建图标(Maki 图标集),设置图标大小为 48 像素,底端对齐
const pinBuilder = new Cesium.PinBuilder();
points.entities.values.forEach(async (entity) => {
const styleByType = {
Tree: { color: Cesium.Color.GREEN, icon: "park2" },//树
Lamp_post: { color: Cesium.Color.WHITE, icon: "lighthouse" },//路灯
Traffic_light: { color: Cesium.Color.CRIMSON, icon: "circle-stroked" },//交通灯
Arrow_Marking: { color: Cesium.Color.YELLOW, icon: "car" },//箭头标记
Road_Sign: { color: Cesium.Color.ORANGE, icon: "triangle" },//路标
};
const type = entity.properties.type?.getValue();
if (Cesium.defined(type) && Cesium.defined(styleByType[type])) {
const { color, icon } = styleByType[type];
const canvas = await pinBuilder.fromMakiIconId(icon, color, 48);
entity.billboard.image = canvas.toDataURL();
entity.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
}
});
lines.entities.values.forEach((entity) => {
const lineColorsByType = {
Contours: Cesium.Color.CRIMSON,//等高线
Lane_Marking: Cesium.Color.CYAN,//车道标记
Kerb: Cesium.Color.BLUEVIOLET,//路缘
Chevron_marking: Cesium.Color.DARKORANGE,//人字形标记
Turning_pocket: Cesium.Color.DEEPPINK,//转弯区
Yellow_Box: Cesium.Color.GOLD,//黄框
};
const type = entity.properties.type?.getValue();
if (Cesium.defined(type) && Cesium.defined(lineColorsByType[type])) {
entity.polyline.material = lineColorsByType[type];
}
});

viewer.dataSources.add(points);
viewer.dataSources.add(lines);
viewer.dataSources.add(areas);

// 加载现实网格(reality data mesh)和点云(pointcloud)
const realityMeshId = "62e4432d-621d-489a-87ff-1fc56a2b5369";
const realityMesh = await Cesium.ITwinData.createTilesetForRealityDataId(
iTwinId,
realityMeshId
);
viewer.scene.primitives.add(realityMesh);
const pointcloudId = "ebf2ee74-f0de-4cd6-a311-19a169c55fdc";
const pointcloud = await Cesium.ITwinData.createTilesetForRealityDataId(
iTwinId,
pointcloudId
);

// 增大点云中点的尺寸并开启衰减(attenuation)效果,使它们在Viewer中更清晰可见
pointcloud.maximumScreenSpaceError = 1;//提高渲染精度
pointcloud.pointCloudShading.attenuation = true;//启用距离衰减,使远处的点更小,提升视觉效果
pointcloud.style = new Cesium.Cesium3DTileStyle({
pointSize: 5.0,
});
pointcloud.show = false;
viewer.scene.primitives.add(pointcloud);

Sandcastle.addToolbarButton(
"切换显示点",
() => (points.show = !points.show),
"layers"
);
Sandcastle.addToolbarButton(
"切换显示线",
() => (lines.show = !lines.show),
"layers"
);
Sandcastle.addToolbarButton(
"切换显示区域",
() => (areas.show = !areas.show),
"layers"
);
Sandcastle.addToolbarButton(
"切换显示现实(实景)网格",
() => (realityMesh.show = !realityMesh.show),
"layers"
);
Sandcastle.addToolbarButton(
"切换显示点云",
() => (pointcloud.show = !pointcloud.show),
"layers"
);

Sandcastle.addToolbarButton("鸟瞰视角", () => {
viewer.scene.camera.flyTo(birdsEyeView);
});
Sandcastle.addToolbarButton("缩放至点云", () => {
pointcloud.show = true;
viewer.zoomTo(pointcloud);
});