综述
Cesium从1.99版本开始支持I3S服务的加载,到目前位置,已经支持I3S的倾斜模型、3D Object模型以及属性查询的支持。Cesium1.115又对I3S标准的Building数据实现了加载支持。而ArcGIS之前一直没有跨越对3DTiles数据的支持,所以在一些开发过程中不能完全的满足一些客户的需求。随着ArcGIS 4.29版本的发布,ArcGIS提供了IntegratedMesh3DTilesLayer的对象去支持3D Tiles数据格式的加载,从而丰富了ArcGIS数据类型,也实现了ArcGIS和Cesium两大Web GIS平台间的数据互通。
Cesium中I3S的支持
从Cesium官网的示例中我们可以看到,目前Cesium支持的I3S标准的数据,主要为倾斜、3d object、BIM、以及数据查看的功能。
从代码可以看到,Cesium提供了Cesium.I3SDataProvider.fromUrl的方法去加载I3S标准数据:
javascript
// Create I3S data provider
const i3sProvider = await Cesium.I3SDataProvider.fromUrl(
tours["San Francisco"],
i3sOptions
);
并且可是通过点击事件绑定,获取3d Object数据对象的属性信息:
javascript
// Pick a new feature
const pickedFeature = viewer.scene.pick(movement.position);
if (!Cesium.defined(pickedFeature)) {
return;
}
const pickedPosition = viewer.scene.pickPosition(movement.position);
if (
Cesium.defined(pickedFeature.content) &&
Cesium.defined(pickedFeature.content.tile.i3sNode)
) {
const i3sNode = pickedFeature.content.tile.i3sNode;
if (pickedPosition) {
i3sNode.loadFields().then(function () {
let description = "No attributes";
let name;
const fields = i3sNode.getFieldsForPickedPosition(
pickedPosition
);
if (Object.keys(fields).length > 0) {
description =
'<table class="cesium-infoBox-defaultTable"><tbody>';
for (const fieldName in fields) {
if (i3sNode.fields.hasOwnProperty(fieldName)) {
description += `<tr><th>${fieldName}</th><td>`;
description += `${fields[fieldName]}</td></tr>`;
if (!Cesium.defined(name) && isNameProperty(fieldName)) {
name = fields[fieldName];
}
}
}
description += `</tbody></table>`;
}
if (!Cesium.defined(name)) {
name = "unknown";
}
selectedEntity.name = name;
selectedEntity.description = description;
viewer.selectedEntity = selectedEntity;
});
}
}
},
Cesium.ScreenSpaceEventType.LEFT_CLICK);
ArcGIS对3DTiles的支持
访问ArcGIS Maps SDK For JavaScript官网,会找到IntegratedMesh3DTilesLayer的对象,这个是4.29版本新提供的图层类,用于支持3dtiles规范的数据加载。
从描述中看,目前ArcGIS对于3dTiles的加载支持,还是需要符合ArcGIS REST格式的url。这块我们可以将数据放到tomcat下去提供。
代码实现,其实和ArcGIS的其他图层加载方式类似,代码采用官网上的示例代码:
javascript
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>IntegratedMesh3DTilesLayer | Sample | ArcGIS Maps SDK for JavaScript 4.29</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.29/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.29/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
require([
"esri/WebScene",
"esri/views/SceneView",
"esri/layers/IntegratedMesh3DTilesLayer",
"esri/widgets/Expand",
"esri/widgets/LayerList",
"esri/widgets/Legend"
], (WebScene, SceneView, IntegratedMesh3DTilesLayer, Expand, LayerList, Legend) => {
/*************************************
* Load webscene with layer showing
* building energy ratings
*************************************/
const webscene = new WebScene({
portalItem: {
id: "5b177c2579bf45159bb91e2a13b4218b"
}
});
/*************************************
* Create IntegratedMesh3DTilesLayer layer
* and add it to the webscene
***********************************/
const layer = new IntegratedMesh3DTilesLayer({
url: "https://tiles.arcgis.com/tiles/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Utrecht_3D_Tiles_Integrated_Mesh/3DTilesServer/tileset.json",
title: "Utrecht Integrated Mesh 3D Tiles"
});
webscene.add(layer);
/*************************************
* Create the View and add expandable
* LayerList and Legend widgets to the UI
***********************************/
const view = new SceneView({
container: "viewDiv",
map: webscene,
lighting: {
directShadowsEnabled: true
}
});
const expandLegend = new Expand({
content: new Legend({
view: view
}),
expanded: true,
expandTooltip: "Expand Legend",
group: "top-right",
view: view
});
const expandLayerList = new Expand({
content: new LayerList({
view: view
}),
expandTooltip: "Expand Layer List",
group: "top-right",
view: view
});
view.ui.add([expandLegend, expandLayerList], "top-right");
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
从图层类的命名IntegratedMesh3DTilesLayer可以看出,这个3dtiles的数据加载其实和倾斜模型(IntegratedMeshLayer)的加载有相似性,示例中其实加载了一个要素图层,叠加在模型表面,这个功能和倾斜一样。
结语
3dTiles数据一般开发常用的生成工具为CesiumLab,ArcGIS对于3dtiles数据的支持,可以让原先使用cesium的开发者也可以借用arcgis的一些优势功能去开发自己的业务。