教程 22:动态导入

要访问 ArcGIS CityEngine 中的教程工程,请打开 CityEngine,然后在主菜单中单击帮助 > 下载教程和示例。 在选择教程或示例后,系统会自动下载工程并将其添加到 CityEngine 工作空间。

路边的棕榈树两旁是灌木丛

本教程将通过涉及 ESRI.lib Plant_Loader 的示例向您展示如何使用动态导入。 想象一下,您希望在道路两侧插植棕榈树。 您将了解到用户常犯的错误(这会导致树木高度不正确),以及修复这个错误的繁琐方法和使用动态导入修复错误的方法。

用户常犯的错误

用户在使用 Plant_Loader 时,通常会设置植物的名称,而不知道如果未进行设置,则高度和半径可能不正确。 换句话说,在不知道还需要设置从属属性的情况下设置所需属性时,这通常会导致错误。

接下来,您将更加详细地了解这一点。

  1. Navigator 窗口中展开 Tutorial_22_Dynamic_Imports 教程文件夹。
  2. 打开 /scenes/ 文件夹中的 dynamic_imports_01.cej 文件以在没有任何植物的街道的视窗中打开一个场景:

    没有植物的街道

  3. 打开 /rules/ 文件夹中的 dynamic_imports_01.cga 规则文件以在 CGA 编辑器窗口中将其打开。
  4. 通过在现有的 import 语句之后添加以下代码行来从 ESRI.lib 导入 Plant_Loader

    import Plant_Loader:"/ESRI.lib/rules/Plants/Plant_Loader.cga" (Representation="LowPoly")

  5. 使用 Plant_Loader 修改 Tree 规则,向街道两侧添加树木:

    Tree -->
    	Plant_Loader.Generate

  6. 保存 dynamic_imports_01.cga 文件。
  7. 选择人行道形状并单击生成 生成 (Ctrl+G):

    街道两侧具有默认“Orange Tree”。

    由于您未指定植物名称,因此街道两侧具有默认“Orange Tree”。 对于本教程,您希望树木为“Coconut Palm”。

    要查看此时场景和规则的外观,请打开 dynamic_imports_02.cej 场景和 dynamic_imports_02.cga 规则文件。

  8. Tree 规则中,将植物属性名称设置为“Coconut Palm”:

    Tree -->
    	set(Plant_Loader.Name, "Coconut Palm")
    	Plant_Loader.Generate

  9. 保存规则并生成:

    街道两侧具有正确的“Coconut Palm”树木,但高度错误。

    街道两侧具有棕榈树,但其高度和半径不正确,因为这些值来自默认“Orange Tree”名称。

    这是因为,在导入 Plant_Loader 时,Name 属性设置为“Orange Tree”,并且将根据“Orange Tree”的标准大小来计算 HeightRadius 属性。 在 Plant_Loader 中,这些属性相互依赖。 将根据 Name 属性计算 Height 值;并根据 NameHeight 属性计算 Radius 值。

    因此,当您使用 set() 操作将 Plant_Loader.Name 设置为“Coconut Palm”时,此操作仅设置了 Name 属性。 而并未更改或重新计算高度和半径的值,并且这些属性仍然具有来自“Orange Tree”的原始值。

以繁琐的方式修复错误

通过仅设置植物的 Name 属性,您创建了具有橘子树高度的棕榈树。 要修复棕榈树的错误高度,可以在设置植物的 Name 后,重新计算并设置 HeightRadius 的值。

接下来您将探索此解决方案,但请记住,这是一种乏味的方法,因为它需要您了解 Plant_Loader 的属性依赖关系以及如何重新计算所需属性。 这种方法比较复杂,容易出错。

  1. 打开 dynamic_imports_03.cej 场景和 dynamic_imports_03.cga 规则文件。
  2. dynamic_imports_03.cga 中,设置植物的 Name 后,请修改 Tree 规则以设置 HeightRadius

    Tree -->
    	set(Plant_Loader.Name, "Coconut Palm")
    	set(Plant_Loader.Height, Plant_Loader.getStandardHeight)
    	set(Plant_Loader.Radius, Plant_Loader.getRadius)
    	Plant_Loader.Generate

  3. 保存并生成。

    路边棕榈树的大小已正确设置

    现在棕榈树的高度和半径均正确,但此方式不简单。 此方法十分复杂,因为首先您必须知道需要重新计算的属性以及重新计算的顺序,其次,您必须知道重新计算这些属性的方法。

使用动态导入修复错误

修复此错误的建议方法是使用动态导入。 您可以在动态导入中设置所需属性,而非使用 set() 操作设置属性,并且将自动重新计算任何依赖属性和常量。 以下是使用 Plant_Loader 示例的工作原理。

  1. 打开 dynamic_imports_04.cej 场景和 dynamic_imports_04.cga 规则文件。
  2. 修改 Tree 规则以使用可将 Name 属性设置为“Coconut Palm”的动态导入:

    Tree -->
    	Plant_Loader(Name="Coconut Palm").Generate

    将自动更新 HeightRadius 属性,无需考虑这一点。

  3. 保存并生成。

    棕榈树大小已使用动态导入正确设置

    该场景和之前一模一样。 椰子树排列在街道两侧,并且具有正确的高度和半径。 区别在于代码。 借助动态导入,您仅需设置所需属性,而无需考虑属性依赖关系。

  4. 修改 Bush 规则以使用 Plant_Loader 的动态导入沿人行道插入杜鹃花:

    Bush -->
    	Plant_Loader(Name="Rhododendron Azaleas").Generate

  5. 保存并生成。

    沿道路一侧的棕榈树和灌木丛

    通过在形状树木中不同点处的动态导入中将 Name 属性设置为不同的值,可以使用相同的已导入 Plant_Loader 来插入棕榈树和杜鹃花丛。

    可以打开 dynamic_imports_05.cej 场景和 dynamic_imports_05.cga 文件以查看最终的场景和规则文件。

在本教程中,您学习了以下内容:

  • 一个常见错误是仅设置植物名称,导致插入的植物高度不正确。
  • 如何以繁琐的方式修复错误,即设置所有依赖属性。
  • 如何以推荐的方式修复错误,即使用动态导入来设置所需的属性。 使用这种方法,将自动重新计算依赖属性。

要继续学习 CityEngine,请参阅完整的 CityEngine 教程目录