01、ArcGIS For JavaScript 4.29对3DTiles数据的支持

综述

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的一些优势功能去开发自己的业务。

相关推荐
kyriewen27 分钟前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
许彰午3 小时前
政务督办的分合模式:主办协办的并发审批
前端·javascript·政务
易筋紫容3 小时前
创建型模式:对象的诞生艺术
开发语言·前端·javascript
0_Error_5 小时前
猫国建设者 修改资源 自动采集
javascript
贩卖黄昏的熊5 小时前
NestJS简明教程——安全
开发语言·javascript·安全·typescript·nest.js
贩卖黄昏的熊5 小时前
NestJS简明教程——异常处理和日志
javascript·node.js·nest.js
海带紫菜菠萝汤9 小时前
FFmpeg.wasm 实践:在浏览器中运行 FFmpeg 的能力边界与性能瓶颈
前端·javascript·ffmpeg·音视频·wasm
名字还没想好☜9 小时前
React 受控输入框光标跳到末尾:格式化输入时的 selection 丢失 bug 与修复
前端·javascript·react.js·bug·react·next.js
upgrador9 小时前
桌面应用开发:Electron 与 NSIS 的关系、打包流程及 Windows 本地构建实战
javascript·windows·electron
我要两颗404西柚9 小时前
Stage three:VUE工程化与实战工具
前端·javascript·vue.js