教程 22:动态导入

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

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

本教程将通过涉及 ESRI.lib Plant_Loader 的示例向您展示如何使用动态导入。 您将学习如何使用两种方法沿道路两侧插入棕榈树:一种更加耗时的方法需要在 CGA 中进行更多编码,另一种更加有效的方法使用动态导入。

用户常犯的错误

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

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

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

    没有植物的街道

  3. 打开 /rules/ 文件夹中的 dynamic_imports_01.cga 规则文件以在 CGA 编辑器窗口中将其打开。
  4. 要从 ESRI.lib 导入 Plant_Loader,请将 /ESRI.lib/rules/Plants/Plant_Loader.cga 文件从 Navigator 窗口拖放到规则文件中的 import Street_Modern_Simple:"/ESRI.lib/rules/Streets/Street_Modern_Simple.cga" 语句下方:

    Plant_Loader dropped into dynamic_imports_01.cga 文件

    由此可添加第二个 import 语句:

    import Plant_Loader:"/ESRI.lib/rules/Plants/Plant_Loader.cga"

  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 教程目录