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

相关推荐
GISer_Jing1 小时前
Monorepo+Pnpm+Turborepo
前端·javascript·ecmascript
天涯学馆1 小时前
前端开发也能用 WebAssembly?这些场景超实用!
前端·javascript·面试
我在北京coding2 小时前
TypeError: Cannot read properties of undefined (reading ‘queryComponents‘)
前端·javascript·vue.js
海天胜景3 小时前
vue3 获取选中的el-table行数据
javascript·vue.js·elementui
翻滚吧键盘4 小时前
vue绑定一个返回对象的计算属性
前端·javascript·vue.js
苦夏木禾4 小时前
js请求避免缓存的三种方式
开发语言·javascript·缓存
超级土豆粉4 小时前
Turndown.js: 优雅地将 HTML 转换为 Markdown
开发语言·javascript·html
乆夨(jiuze)4 小时前
记录H5内嵌到flutter App的一个问题,引发后面使用fastClick,引发后面input输入框单击无效问题。。。
前端·javascript·vue.js
小彭努力中5 小时前
141.在 Vue 3 中使用 OpenLayers Link 交互:把地图中心点 / 缩放级别 / 旋转角度实时写进 URL,并同步解析显示
前端·javascript·vue.js·交互