使用 CesiumJS 对 3D Tiles 进行样式化和过滤

660 阅读3分钟

原文地址:Styling and Filtering 3D Tiles – Cesium

本指南将详细阐述如何借助 CesiumJS 对 3D Tiles 予以样式化和过滤,从而突显数据集中的关键特征。

墨尔本的热力图,使用3D Tiles样式化创建。左侧:OSM建筑3D Tiles。右侧:点云3D Tiles。 墨尔本的热力图,使用 3D Tiles 样式化创建。左侧:OSM Buildings 3D Tiles。右侧:点云 3D Tiles。

前提条件

  • 一个带有属性或分类的 3D Tileset:您可以使用 Cesium ion 资源库内的现有数据集,例如 OSM 建筑或蒙特利尔点云,也可以上传您自己的数据。倘若要将非 3D Tiles 格式的数据转换为 3D Tiles,可以参考 Cesium 的数据导入快速指南,以了解详尽的转换步骤。
  • Cesi umJS基础:需要对 CesiumJS 的基本操作具备一定的了解。倘若您是 Cesium 的新手,建议首先从CesiumJS 快速入门 - 掘金 (juejin.cn)展开学习,这会助力您迅速掌握 CesiumJS 的核心概念。
  • Cesium ion账户:拥有一个 Cesium ion 账户是必要的,因为如此一来您便能访问 Cesium ion 资源库中的丰富数据集。倘若您尚未注册,请依照CesiumJS 快速入门 - 掘金 (juejin.cn)里的指引完成注册流程。

3D Tiles 的样式化语言

3D Tiles 样式化语言允许您对数据集中特征的显示规则进行设定,像建筑物的颜色、所展示的建筑类型等。这对于识别城市中的模式或者创建更具信息性的可视化效果非常有用。

样式是通过 JSON 和 JavaScript 表达式来进行定义的。此外,样式化语言提供了一系列的内置函数,支持常见的数学运算,比如 mindistancelog

本指南涵盖了这些 3D Tiles 样式化语言常用部分的示例:

  • showcolor 等样式选项
  • 包含特征属性测试、空值检查以及点云中点的 Classification 检查在内的 conditions 条件测试
  • 使用 defines 创建新变量
  • distance 函数的使用
  • 创建新的颜色定义

有关详细的 3D Tiles 样式化和过滤的文档,请参阅3D Tiles样式化规范。另外,在Sandcastle中还能找到更多相关示例(搜索“styling”)。

什么是 3D Tiles 特征?

特征可以是单个建筑物、门、窗、阀门或者点云中的点等等。

应用基本样式

我们能够通过两种常见的方式为 3D Tileset 应用样式:借助 showcolor 这两个视觉属性。一旦明确了样式规则,我们可以通过将 3D Tileset 的 style 设置为新的 Cesium3DTileStyle,从而将其应用于特征。

在下面的代码片段中,我们使用了 Cesium OSM Buildings 3D Tiles 以及澳大利亚墨尔本的 Crown 娱乐中心。规则是将名为“Crown 娱乐中心”的建筑物着色为红色,将其他所有建筑物着色为白色。CesiumJS 会将此规则应用于每一个特征,替换特征上的任何现有样式。我们所选择的特征属性是 name,它已经存在于数据集中。

osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({
  color: {
    conditions: [
      ["${name} === 'Crown Entertainment Complex'", "color('red')"],
      ["true", "color('white')"],
    ],
  },
});

在Sandcastle中打开

我们可以通过点击查看器中的特征来查看特征属性列表:

3D Tiles样式化 nameAttribute

基于属性展现特征

3D Tiles 样式语言除了用于着色外,还能够依据元数据属性来显示和隐藏特征。

这里呈现的是来自 Cesium OSM Buildings tileset 的墨尔本所有建筑。

3D Tiles样式化 showAllBuildings 显示所有建筑的墨尔本。

假定我们想要找出墨尔本的所有住宅建筑。在 OSM Buildings 中,这些建筑是通过使用 building 属性被分类为“residential”或者“apartment”来筛选。

osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({
  show: "${feature['building']} === 'residential' || ${feature['building']} === 'apartments'",
});

在Sandcastle中打开

3D Tiles样式化 showAllResidential 仅显示住宅建筑的墨尔本。

使用条件为特征着色

您同样可以运用条件来为特征赋予不同的颜色。

例如,您想要为墨尔本 Crown 娱乐中心周边区域的游客规划一条巴士路线。那么,哪些建筑在该中心的特定距离范围内呢?

以下的代码片段会依据建筑物到 Crown 娱乐中心的距离为每个建筑分配颜色:

osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({
  defines: {
    distanceFromComplex:
      "distance(vec2(${feature['cesium#longitude']}, ${feature['cesium#latitude']}), vec2(144.96007, -37.82249))",
  },
  color: {
    conditions: [
      ["${distanceFromComplex} > 0.010", "color('#d65c5c')"],
      ["${distanceFromComplex} > 0.006", "color('#f58971')"],
      ["${distanceFromComplex} > 0.002", "color('#f5af71')"],
      ["${distanceFromComplex} > 0.0001", "color('#f5ec71')"],
      ["true", "color('#ffffff')"],
    ],
  },
});

在Sandcastle中打开

下面对代码中的核心内容进行一些解释:

  • defines 表达式能够创建新的变量。
  • distance 是 3D Tiles 样式语言的一个 内置函数
  • 3D Tiles 样式中的 conditions 允许您在数组定义类似颜色(color)这样的特征。
  • 条件的表现类似于 if 语句。
  • 支持 CSS 风格的 颜色定义

上述的代码片段将会产生如下样式效果:

为点云设置样式

点云 是一组点,这些点遵循与上述相同的样式规则,但存在一些额外的选项。

点云样式选项和属性

除了 colorshow 这两个视觉属性外,点云 Tiles 还支持 pointSize。默认的 pointSize 为 1.0 。

Cesium ion 上 LAS 文件中的点云,每个点都具有 ClassificationIntensity 这两个属性。

  • Classification 是一个整数,它映射到点的数据类型,比如地面、低植被或建筑物。
  • Intensity 是点表面的反射率,是一个处于 0 到 255 之间的整数。

点云样式还能够应用于其他点属性 ,如位置、颜色和法线。例如,您可以使用 POSITION_ABSOLUTE 元数据属性创建基于点云到中心点距离的热力图,这类似于我们依据到 Crown 娱乐中心距离对 OSM 建筑物进行着色。

点云样式示例

假设您想要将加拿大蒙特利尔 Biosphere 博物馆周围的环境进行可视化。样式规则是如果点的 Classification 属性是植被,则将点着色为绿色

pointCloudTileset.style = new Cesium.Cesium3DTileStyle({
  color: {
    conditions: [
      ["${Classification} === 2", "color('brown')"],       // 地面
      ["${Classification} === 3", "color('greenyellow')"], // 低植被
      ["${Classification} === 4", "color('green')"],       // 中等植被
      ["${Classification} === 5", "color('darkgreen')"],   // 高植被
      ["true", "color('white')"]
    ]
  }
});

在Sandcastle中打开

应用样式规则后,我们能够将博物馆周围的植被情况进行可视化:

3D Tiles 样式 bioMuseumMontrealPointCloudClassified

处理未定义的属性

有时,建筑物可能会缺失某些属性。在此种情况下,我们能够添加一个 null 检查条件:

osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({
    color: {
      conditions: [
        ["${material} === null", "color('white')"],
        ["${material} === 'glass'", "color('skyblue', 0.5)"],
        ["${material} === 'concrete'", "color('grey')"],
        ["${material} === 'brick'", "color('indianred')"],
        ["true", "color('white')"],
      ],
    },
  });
}

在这个示例当中,如果任何建筑物没有 material 元数据属性,那么它的颜色将会是白色。

在 Cesium Stories 中使用样式编辑器

您还能够使用 Cesium Stories 当中的样式编辑器来对 3D Tiles 进行样式设置。我们上面所介绍的样式都能够在编辑器中予以应用,而无需编写代码。请参阅 在 Cesium Stories 中为 3D Tiles 设置样式教程

3D Tiles 样式 ionStyleEditor

其他资源

请查看 Sandcastle 中的样式示例,包括:

有关 3D Tiles 样式和过滤的详细文档,请参阅 3D Tiles 样式规范