创建服务区图层 (Network Analyst)

摘要

创建服务区网络分析图层并设置其分析属性。服务区分析图层主要用于确定在指定中断成本范围内能从设施点位置访问的区域。

使用情况

  • 通过此工具创建分析图层后,您可以使用添加位置工具向图层中添加网络分析对象;使用求解工具来求解分析;以及使用保存至图层文件工具将结果保存到磁盘中。

  • 在地理处理模型中使用此工具时,如果模型作为工具来运行,则必须将输出网络分析图层创建为模型参数;否则,输出图层将无法添加到地图内容中。

参数

标注说明数据类型
输入分析网络

将在其中执行服务区分析的网络数据集。

Network Dataset Layer
输出图层名称

要创建的服务区网络分析图层的名称。

String
阻抗属性

分析过程中用作阻抗的成本属性。

String
行驶自/至设施点
(可选)

指定行至或离开设施点的方向。

  • TRAVEL_FROM在远离设施点的方向上创建服务区。
  • TRAVEL_TO在接近设施点的方向上创建服务区。

使用此选项的结果是,在基于行驶方向的网络中,单向限制及不同行驶方向的阻抗差异会产生不同的服务区。例如,应该在远离设施点的方向上创建比萨外卖店的服务区,而医院的服务区应该创建在朝向设施点的方向上。

String
默认中断值
(可选)

指示要计算的服务区范围的默认阻抗值。可通过对设施点指定中断值来覆盖默认值。

可以设置多个面中断来创建同心服务区。例如,要为同一设施点查找 2 分钟、3 分钟和 5 分钟服务区,请将“默认中断值”参数指定为“2 3 5”(2、3 和 5 这些数字之间应该以空格分隔)。

String
面类型
(可选)

指定要生成的面的类型。

  • SIMPLE_POLYS创建生成速度快并且相当精确的概化面,边缘除外。这是默认设置。
  • DETAILED_POLYS创建详细面,用于对服务区线进行精确建模并且可包含未到达的岛状区域。这种面比概化面的生成速度慢。
  • NO_POLYS在仅需要服务区线的情况下,将关闭“面生成”选项。

如果是具有类似格网网络的市区数据,则概化多边形和详细多边形之间的差别最小。然而,对于山区道路和农村道路,详细多边形可能会呈现出比概化多边形更精确的结果。

String
合并具有相似范围的面
(可选)

指定用来合并共享相似中断值的面的选项。仅当为多个设施点生成面时,此选项才可用。

  • NO_MERGE为各个设施点创建单独的面。这些面可以相互叠置。
  • NO_OVERLAP为各个设施点创建最接近的单独面。这些面不会相互叠置。
  • MERGE 连接具有相同中断值的多个设施点的面。
String
面嵌套选项
(可选)

指定该选项,将同心服务区面创建为圆或环。仅当为这些设施点指定多个中断值时,此选项才可用。

  • RINGS不包括较小中断的区域。这将在连续的中断之间创建面。如果要查找从一个中断到另一个中断的区域,请使用此选项。
  • DISKS 在设施点与中断之间创建面。例如,如果创建 5 分钟和 10 分钟服务区,则 10 分钟服务区面将包含 5 分钟服务区面内的区域。如果要为各个中断查找从设施点到中断的整个区域,请使用此选项。
String
线类型
(可选)

指定基于服务区分析生成的线的类型。对于大型服务区,选择实际线具有测量值的实际线选项将增加分析所占用的内存量。

  • NO_LINES不生成线。这是默认设置。
  • TRUE_LINES生成没有测量值的线。
  • TRUE_LINES_WITH_MEASURES生成具有测量值的线。基于插入了中间结点的边上每个端点的阻抗值生成测量值。如果对性能要求较高,请勿使用此选项。
String
叠置线
(可选)

确定计算服务区线时是否生成重叠线。

  • 选中 - 当设施点具有重合的服务区线时,将包含各个设施点的单独线要素。
  • 未选中 - 每个服务区线最多被包含一次,并将它与最近(阻抗最小)的设施点相关联。
Boolean
当线跨越服务区中断时对其进行分割
(可选)
  • 选中 - 将两个中断之间的每条线分割为两条线,各自位于其对应中断内。如果要按中断对服务区线进行符号化,此选项很有用。否则,应取消选中此选项以达到最佳性能。
  • 未选中 - 在中断的边界处不对线进行分割。这是默认设置。
Boolean
在面生成过程中排除源
(可选)

指定生成面时要排除的网络源的列表。所有面都将忽略排除的源中遍历元素的几何。

在生成面的过程中,如果需要排除某些会创建低精度的面或者对服务区分析无关紧要的网络源时,此选项十分有用。例如,在街道和铁路的多模式网络上创建行驶时间服务区时,应该在面生成过程中选择排除铁路线,这样才能准确地对车辆可以行驶的区域进行建模。

从服务区多边形中排除网络源并不会阻止这些源受遍历。只会影响该服务区的多边形形状。如果要阻止遍历一个给定的网络源,必须在定义网络数据集时创建适当的限制。

String
累加器
(可选)

分析过程中要累积的成本属性的列表。 这些累积属性仅供参考;求解程序仅使用阻抗属性参数所指定的成本属性来计算路径。

对于每个累积的成本属性,均会向求解程序所输出的路径中添加一个 Total_[阻抗] 属性。

String
U 形转弯策略
(可选)

指定将在交汇点处使用的 U 形转弯策略。 允许 U 形转弯表示求解程序可以在交汇点处转向并沿同一街道往回行驶。 考虑到交汇点表示街道交叉路口和死角,不同的车辆可以在某些交汇点转弯,而在其他交汇点则不行 - 这取决于交汇点是交叉路口还是死角。 为适应此情况,U 形转弯策略参数由连接到交汇点的边数隐性指定,这称为交汇点价。 此参数可接受的值如下所列;每个值的后面是根据交汇点价对其含义的描述。

  • ALLOW_UTURNS无论在交汇点处有几条连接的边,均允许 U 形转弯。 这是默认值。
  • NO_UTURNS在所有交汇点处均禁止 U 形转弯,不管交汇点原子价如何。 不过请注意,即使已选择该设置,在网络位置处仍允许 U 形转弯;但是也可以通过设置个别网络位置的 CurbApproach 属性来禁止 U 形转弯。
  • ALLOW_DEAD_ENDS_ONLY除仅有一条相邻边的交汇点(死角)外,其他交汇点均禁止 U 形转弯。
  • ALLOW_DEAD_ENDS_AND_INTERSECTIONS_ONLY在恰好有两条相邻边相遇的交汇点处禁止 U 形转弯,但是交叉点(三条或三条以上相邻边的交汇点)和死角(仅有一条相邻边的交汇点)处允许。 通常,网络在路段中间有多余的交汇点。 此选项可防止车辆在这些位置掉头。

如果您需要定义更加精确的 U 形转弯策略,可以考虑在网络成本属性中添加一个通用转弯延迟赋值器,或者如果存在的话,调整其设置,并特别注意反向转弯的配置。 还可以设置网络位置的 CurbApproach 属性。

String
约束条件
(可选)

分析过程中要应用的限制属性的列表。

String
修剪面
(可选)
  • 选中 - 对包含服务区外围边的面进行修剪,以使其达到外边界的指定距离内。这在网络非常稀疏且不需要服务区覆盖大片不含要素的区域时十分有用。
  • 未选中 - 不修剪面。
Boolean
面修剪
(可选)

指定对服务区面进行修剪的距离范围。该参数包括距离的值和单位。默认值是 100 米。

Linear Unit
在线中包括网络源字段
(可选)
  • 选中 - 向服务区线添加 SourceID、SourceOID、FromPosition 和 ToPosition 字段,以保存分析过程中已遍历的基础源要素的信息。此选项可用于将服务区线的结果连接到原始源数据。
  • 未选中 - 不向服务区线添加源字段(SourceID、SourceOID、FromPosition 和 ToPosition)。
Boolean
在分析中应用等级
(可选)
  • 选中 - 将使用等级属性进行分析。 使用等级的结果是,求解程序更偏好高等级的边而不是低等级的边。 分等级求解的速度更快,并且可用于模拟驾驶员在可能的情况下选择在高速公路而非地方道路上行驶(即使行程可能更远)的偏好。 只有输入网络数据集具有等级属性时,此选项才处于活动状态。
  • 未选中 - 将不会使用等级属性进行分析。 如果不使用等级,则结果为沿网络数据集的所有边测量的服务区(无论等级级别为何)。

如果未在用于执行分析的网络数据集中定义等级属性,该参数将处于非活动状态。

Boolean
时间
(可选)

离开或到达服务区图层的设施点的时间。将此值理解为离开还是到达时间,取决于行驶方向是离开还是朝向设施点。

  • 如果将行驶自/至设施点设置为 TRAVEL_FROM,此值表示离开时间。
  • 如果将行驶自/至设施点设置为 TRAVEL_TO,此值表示到达时间。

如果您已经选择了基于流量的阻抗属性,将会根据特定的某天某时的动态交通状况来生成解决方案。日期和时间可被指定为 5/14/2012 10:30 AM。

Instead of using a particular date, a day of the week can be specified using the following dates.

  • Today—12/30/1899
  • Sunday—12/31/1899
  • Monday—1/1/1900
  • Tuesday—1/2/1900
  • Wednesday—1/3/1900
  • Thursday—1/4/1900
  • Friday—1/5/1900
  • Saturday—1/6/1900
For example, to specify that travel should begin at 5:00 PM on Tuesday, specify the parameter value as 1/2/1900 5:00 PM.

重复解决相同的分析问题,但使用不同的“时间”参数值,这样您就会看到设施点的到达时间随时间的变化。例如,消防站周围的 5 分钟服务区在大清早时可能变得大一点,而在早高峰期消失,上午晚些时候服务区又扩大,并在一天中都保持这样。

Date

派生输出

标注说明数据类型
网络分析图层

新创建的网络分析图层。

网络分析图层

arcpy.management.MakeServiceAreaLayer(in_network_dataset, out_network_analysis_layer, impedance_attribute, {travel_from_to}, {default_break_values}, {polygon_type}, {merge}, {nesting_type}, {line_type}, {overlap}, {split}, {excluded_source_name}, {accumulate_attribute_name}, {UTurn_policy}, {restriction_attribute_name}, {polygon_trim}, {poly_trim_value}, {lines_source_fields}, {hierarchy}, {time_of_day})
名称说明数据类型
in_network_dataset

将在其中执行服务区分析的网络数据集。

Network Dataset Layer
out_network_analysis_layer

要创建的服务区网络分析图层的名称。

String
impedance_attribute

分析过程中用作阻抗的成本属性。

String
travel_from_to
(可选)

指定行至或离开设施点的方向。

  • TRAVEL_FROM在远离设施点的方向上创建服务区。
  • TRAVEL_TO在接近设施点的方向上创建服务区。

使用此选项的结果是,在基于行驶方向的网络中,单向限制及不同行驶方向的阻抗差异会产生不同的服务区。例如,应该在远离设施点的方向上创建比萨外卖店的服务区,而医院的服务区应该创建在朝向设施点的方向上。

String
default_break_values
(可选)

指示要计算的服务区范围的默认阻抗值。可通过对设施点指定中断值来覆盖默认值。

可以设置多个面中断来创建同心服务区。例如,要为同一设施点查找 2 分钟、3 分钟和 5 分钟服务区,请将“默认中断值”参数指定为“2 3 5”(2、3 和 5 这些数字之间应该以空格分隔)。

String
polygon_type
(可选)

指定要生成的面的类型。

  • SIMPLE_POLYS创建生成速度快并且相当精确的概化面,边缘除外。这是默认设置。
  • DETAILED_POLYS创建详细面,用于对服务区线进行精确建模并且可包含未到达的岛状区域。这种面比概化面的生成速度慢。
  • NO_POLYS在仅需要服务区线的情况下,将关闭“面生成”选项。

如果是具有类似格网网络的市区数据,则概化多边形和详细多边形之间的差别最小。然而,对于山区道路和农村道路,详细多边形可能会呈现出比概化多边形更精确的结果。

String
merge
(可选)

指定用来合并共享相似中断值的面的选项。仅当为多个设施点生成面时,此选项才可用。

  • NO_MERGE为各个设施点创建单独的面。这些面可以相互叠置。
  • NO_OVERLAP为各个设施点创建最接近的单独面。这些面不会相互叠置。
  • MERGE 连接具有相同中断值的多个设施点的面。
String
nesting_type
(可选)

指定该选项,将同心服务区面创建为圆或环。仅当为这些设施点指定多个中断值时,此选项才可用。

  • RINGS不包括较小中断的区域。这将在连续的中断之间创建面。如果要查找从一个中断到另一个中断的区域,请使用此选项。
  • DISKS 在设施点与中断之间创建面。例如,如果创建 5 分钟和 10 分钟服务区,则 10 分钟服务区面将包含 5 分钟服务区面内的区域。如果要为各个中断查找从设施点到中断的整个区域,请使用此选项。
String
line_type
(可选)

指定基于服务区分析生成的线的类型。对于大型服务区,选择 TRUE_LINESTRUE_LINES_WITH_MEASURES 选项将增加分析所占用的内存量。

  • NO_LINES不生成线。这是默认设置。
  • TRUE_LINES生成没有测量值的线。
  • TRUE_LINES_WITH_MEASURES生成具有测量值的线。基于插入了中间结点的边上每个端点的阻抗值生成测量值。如果对性能要求较高,请勿使用此选项。
String
overlap
(可选)

确定计算服务区线时是否生成重叠线。

  • OVERLAP 当设施点具有重合的服务区线时,将包含各个设施点的单独线要素。
  • NON_OVERLAP 每个服务区线最多被包含一次,并将它与最近(阻抗最小)的设施点相关联。
Boolean
split
(可选)
  • SPLIT将两个中断之间的每条线分割为两条线,各自位于其对应中断内。如果要按中断对服务区线进行符号化,此选项很有用。否则,使用 NO_SPLIT 选项以达到最佳性能。
  • NO_SPLIT在中断的边界处不对线进行分割。这是默认设置。
Boolean
excluded_source_name
[excluded_source_name,...]
(可选)

指定生成面时要排除的网络源的列表。所有面都将忽略排除的源中遍历元素的几何。

在生成面的过程中,如果需要排除某些会创建低精度的面或者对服务区分析无关紧要的网络源时,此选项十分有用。例如,在街道和铁路的多模式网络上创建行驶时间服务区时,应该在面生成过程中选择排除铁路线,这样才能准确地对车辆可以行驶的区域进行建模。

从服务区多边形中排除网络源并不会阻止这些源受遍历。只会影响该服务区的多边形形状。如果要阻止遍历一个给定的网络源,必须在定义网络数据集时创建适当的限制。

String
accumulate_attribute_name
[accumulate_attribute_name,...]
(可选)

分析过程中要累积的成本属性的列表。 这些累积属性仅供参考;求解程序仅使用阻抗属性参数所指定的成本属性来计算路径。

对于每个累积的成本属性,均会向求解程序所输出的路径中添加一个 Total_[阻抗] 属性。

String
UTurn_policy
(可选)

指定将在交汇点处使用的 U 形转弯策略。 允许 U 形转弯表示求解程序可以在交汇点处转向并沿同一街道往回行驶。 考虑到交汇点表示街道交叉路口和死角,不同的车辆可以在某些交汇点转弯,而在其他交汇点则不行 - 这取决于交汇点是交叉路口还是死角。 为适应此情况,U 形转弯策略参数由连接到交汇点的边数隐性指定,这称为交汇点价。 此参数可接受的值如下所列;每个值的后面是根据交汇点价对其含义的描述。

  • ALLOW_UTURNS无论在交汇点处有几条连接的边,均允许 U 形转弯。 这是默认值。
  • NO_UTURNS在所有交汇点处均禁止 U 形转弯,不管交汇点原子价如何。 不过请注意,即使已选择该设置,在网络位置处仍允许 U 形转弯;但是也可以通过设置个别网络位置的 CurbApproach 属性来禁止 U 形转弯。
  • ALLOW_DEAD_ENDS_ONLY除仅有一条相邻边的交汇点(死角)外,其他交汇点均禁止 U 形转弯。
  • ALLOW_DEAD_ENDS_AND_INTERSECTIONS_ONLY在恰好有两条相邻边相遇的交汇点处禁止 U 形转弯,但是交叉点(三条或三条以上相邻边的交汇点)和死角(仅有一条相邻边的交汇点)处允许。 通常,网络在路段中间有多余的交汇点。 此选项可防止车辆在这些位置掉头。

如果您需要定义更加精确的 U 形转弯策略,可以考虑在网络成本属性中添加一个通用转弯延迟赋值器,或者如果存在的话,调整其设置,并特别注意反向转弯的配置。 还可以设置网络位置的 CurbApproach 属性。

String
restriction_attribute_name
[restriction_attribute_name,...]
(可选)

分析过程中要应用的限制属性的列表。

String
polygon_trim
(可选)
  • TRIM_POLYS对包含服务区外围边的面进行修剪,以使其达到外边界的指定距离内。这在网络非常稀疏且不需要服务区覆盖大片不含要素的区域时十分有用。
  • NO_TRIM_POLYS不修剪面。
Boolean
poly_trim_value
(可选)

指定对服务区面进行修剪的距离范围。该参数包括距离的值和单位。默认值是 100 米。

Linear Unit
lines_source_fields
(可选)
  • LINES_SOURCE_FIELDS 向服务区线添加 SourceID、SourceOID、FromPosition 和 ToPosition 字段,以保存分析过程中已遍历的基础源要素的信息。此选项可用于将服务区线的结果连接到原始源数据。
  • NO_LINES_SOURCE_FIELDS不向服务区线添加源字段(SourceID、SourceOID、FromPosition 和 ToPosition)。
Boolean
hierarchy
(可选)
  • USE_HIERARCHY将使用等级属性进行分析。 使用等级的结果是,求解程序更偏好高等级的边而不是低等级的边。 分等级求解的速度更快,并且可用于模拟驾驶员在可能的情况下选择在高速公路而非地方道路上行驶(即使行程可能更远)的偏好。 只有输入网络数据集具有等级属性时,此选项才有效。
  • NO_HIERARCHY将不会使用等级属性进行分析。 如果不使用等级,则结果为沿网络数据集的所有边测量的服务区(无论等级级别为何)。

如果未在用于执行分析的网络数据集中定义等级属性,该参数将不可用。

Boolean
time_of_day
(可选)

离开或到达服务区图层的设施点的时间。将此值理解为离开还是到达时间,取决于行驶方向是离开还是朝向设施点。

  • 如果将行驶自/至设施点设置为 TRAVEL_FROM,此值表示离开时间。
  • 如果将行驶自/至设施点设置为 TRAVEL_TO,此值表示到达时间。

如果您已经选择了基于流量的阻抗属性,将会根据特定的某天某时的动态交通状况来生成解决方案。日期和时间可被指定为 5/14/2012 10:30 AM。

Instead of using a particular date, a day of the week can be specified using the following dates.

  • Today—12/30/1899
  • Sunday—12/31/1899
  • Monday—1/1/1900
  • Tuesday—1/2/1900
  • Wednesday—1/3/1900
  • Thursday—1/4/1900
  • Friday—1/5/1900
  • Saturday—1/6/1900
For example, to specify that travel should begin at 5:00 PM on Tuesday, specify the parameter value as 1/2/1900 5:00 PM.

重复解决相同的分析问题,但使用不同的“时间”参数值,这样您就会看到设施点的到达时间随时间的变化。例如,消防站周围的 5 分钟服务区在大清早时可能变得大一点,而在早高峰期消失,上午晚些时候服务区又扩大,并在一天中都保持这样。

Date

派生输出

名称说明数据类型
output_layer

新创建的网络分析图层。

网络分析图层

代码示例

MakeServiceAreaLayer 示例 1(Python 窗口)

仅使用必需参数运行此工具。

network = "C:/Data/SanFrancisco.gdb/Transportation/Streets_ND"
arcpy.na.MakeServiceAreaLayer(network, "FireStationCoverage", "TravelTime")
MakeServiceAreaLayer 示例 2(Python 窗口)

使用所有参数运行此工具

network = "C:/Data/Paris.gdb/Transportation/ParisMultimodal_ND"
arcpy.na.MakeServiceAreaLayer(network, "WarehouseCoverage", "DriveTime",
                                "TRAVEL_FROM", "5 10 15", "SIMPLE_POLYS", 
                                "NO_OVERLAP", "RINGS", "TRUE_LINES",
                                "NON_OVERLAP", "NO_SPLIT",
                                ["Metro_Lines", "Transfer_Stations",
                                "Transfer_Street_Station"],
                                ["Meters", "DriveTime"], "ALLOW_DEAD_ENDS_ONLY",
                                ["Oneway"], "NO_TRIM_POLYS", "",
                                "LINES_SOURCE_FIELDS")
MakeServiceAreaLayer 示例 3(工作流)

以下独立 Python 脚本演示了如何使用 MakeServiceAreaLayer 工具在消防站周围生成 1 分钟、2 分钟和 3 分钟服务区。

# Name: MakeServiceAreaLayer_Workflow.py
# Description: Generate 1-,2-,3- minute service areas around fire stations and
#              save the results to a layer file on disk. The service area
#              polygons can be used to visualize the areas that do not have
#              adequate coverage from the fire stations
# Requirements: Network Analyst Extension

#Import system modules
import arcpy
from arcpy import env
import os

try:
    #Set environment settings
    output_dir = "C:/Data"
    #The NA layer's data will be saved to the workspace specified here
    env.workspace = os.path.join(output_dir, "Output.gdb")
    env.overwriteOutput = True

    #Set local variables
    input_gdb = "C:/Data/SanFrancisco.gdb"
    network = os.path.join(input_gdb, "Transportation", "Streets_ND")
    layer_name = "FireStationCoverage"
    impedance = "TravelTime"
    facilities = os.path.join(input_gdb, "Analysis", "FireStations")
    output_layer_file = os.path.join(output_dir, layer_name + ".lyrx")

    #Create a new service area layer. We wish to generate the service area
    #polygons as rings, so that we can easily visualize the coverage for any
    #given location. We also want overlapping polygons as we can determine the
    #number of fire stations that cover a given location. We use hierarchy to
    #speed up the time taken to create the polygons. We will specify these
    #options while creating the new service area layer.
    result_object = arcpy.na.MakeServiceAreaLayer(network, layer_name,
                                    impedance, "TRAVEL_FROM", "1 2 3",
                                    "DETAILED_POLYS", "NO_MERGE", "RINGS")

    #Get the layer object from the result object. The service layer can now be
    #referenced using the layer object.
    layer_object = result_object.getOutput(0)

    #Get the names of all the sublayers within the service area layer.
    sublayer_names = arcpy.na.GetNAClassNames(layer_object)
    #Stores the layer names that we will use later
    facilities_layer_name = sublayer_names["Facilities"]

    #Load the fire stations as facilities using default field mappings and
    #default search tolerance
    arcpy.na.AddLocations(layer_object, facilities_layer_name, facilities, "",
                                                                            "")

    #Solve the service area layer
    arcpy.na.Solve(layer_object)

    #Save the solved service area layer as a layer file on disk
    layer_object.saveACopy(output_layer_file)

    print("Script completed successfully")

except Exception as e:
    # If an error occurred, print line number and error message
    import traceback, sys
    tb = sys.exc_info()[2]
    print(("An error occurred on line %i" % tb.tb_lineno))
    print((str(e)))
MakeServiceAreaLayer 示例 4(工作流)

本例展示了如何在一天的多个时间点内围绕设施点创建服务区,以及如何将字段从输入要素移到输出要素并将输出面追加到现有要素类中。

# Name: MakeServiceAreaLayer_Workflow2.py
# Description: Generate 3-minute service areas around fire stations at several
#               times of day to compare coverage differences due to varying
#               traffic conditions. Save the results to a feature class on disk.
# Requirements: Network Analyst Extension

#Import system modules
import arcpy
from arcpy import env
import os, datetime

try:
    #Set environment settings
    output_dir = "C:/Data"
    #The NA layer's data will be saved to the workspace specified here
    env.workspace = os.path.join(output_dir, "Output.gdb")
    env.overwriteOutput = True

    #Set local variables
    input_gdb = "C:/Data/SanFrancisco.gdb"
    network = os.path.join(input_gdb, "Transportation", "Streets_ND")
    layer_name = "FireStationCoverage"
    out_featureclass = os.path.join(output_dir, "Output.gdb",
                                                        "FireStationCoverage")
    impedance = "TravelTime"
    facilities = os.path.join(input_gdb, "Analysis", "FireStations")
    times_of_day = [datetime.datetime(2014, 9, 25, 7, 0, 0),
                    datetime.datetime(2014, 9, 25, 12, 30, 0),
                    datetime.datetime(2014, 9, 25, 17, 30, 0),
                    datetime.datetime(2014, 9, 25, 21, 0, 0)]

    #Create a new service area layer.
    result_object = arcpy.na.MakeServiceAreaLayer(network, layer_name,
                                                impedance, "TRAVEL_FROM", "3",
                                                "DETAILED_POLYS", "NO_MERGE",
                                                hierarchy = "NO_HIERARCHY")

    #Get the layer object from the result object. The service area layer can
    #now be referenced using the layer object.
    layer_object = result_object.getOutput(0)

    #Get the names of all the sublayers within the service area layer.
    sublayer_names = arcpy.na.GetNAClassNames(layer_object)
    #Stores the layer names that we will use later
    facilities_layer_name = sublayer_names["Facilities"]
    polygons_layer_name = sublayer_names["SAPolygons"]

    #The input data has a field for FireStationID that we want to transfer to
    #our analysis layer. Add the field, and then use field mapping to transfer
    #the values.
    arcpy.na.AddFieldToAnalysisLayer(layer_object, facilities_layer_name,
                                                    "FireStationID", "TEXT")
    field_mappings = arcpy.na.NAClassFieldMappings(layer_object,
                                                    facilities_layer_name)
    field_mappings["FireStationID"].mappedFieldName = "FireStationID"

    #Load the fire stations as facilities.
    arcpy.na.AddLocations(layer_object, facilities_layer_name, facilities,
                            field_mappings, "",
                            exclude_restricted_elements = "EXCLUDE")

    # Add fields to the output Polygons sublayer for later use.
    arcpy.na.AddFieldToAnalysisLayer(layer_object, polygons_layer_name,
                                        "FireStationID", "TEXT")
    arcpy.na.AddFieldToAnalysisLayer(layer_object, polygons_layer_name,
                                        "TimeOfDay", "TEXT")

    #Get sublayers to work with later
    facilities_sublayer = layer_object.listLayers(facilities_layer_name)[0]
    polygons_sublayer = layer_object.listLayers(polygons_layer_name)[0]

    #Get the Service Area Layer's solver properties. This can be used to
    #set individual properties later without re-creating the layer.
    solver_properties = arcpy.na.GetSolverProperties(layer_object)

    #Solve the Service Area for each time of day in the time list
    for t in times_of_day:

        print("Calculating service area for time of day: ", t)

        #Use the solver properties to set the time of day for the solve
        solver_properties.timeOfDay = t

        #Solve the service area layer
        arcpy.na.Solve(layer_object)

        #Transfer the FireStationID field from the input Facilities to the
        #output Polygons
        arcpy.management.AddJoin(polygons_sublayer, "FacilityID",
                                        facilities_sublayer, "ObjectID")
        #The joined fields are qualified by the feature class name of the joined
        #table, so determine the feature class names
        field_qualifier_pol = os.path.basename(polygons_sublayer.dataSource)
        target_field_name = "%s.FireStationID" % field_qualifier_pol
        field_qualifier_fac = os.path.basename(facilities_sublayer.dataSource)
        expression = "!%s.FireStationID!" % field_qualifier_fac
        arcpy.management.CalculateField(polygons_sublayer, target_field_name,
                                        expression, "PYTHON")
        arcpy.management.RemoveJoin(polygons_sublayer)

        #Populate the TimeOfDay field in the output feature class
        expression = '"' + str(t) + '"'
        arcpy.management.CalculateField(polygons_sublayer, "TimeOfDay",
                                            expression, "PYTHON")

        #Append the polygons to the output feature class. If this was the first
        #solve, create the feature class.
        if not arcpy.Exists(out_featureclass):
            arcpy.management.CopyFeatures(polygons_sublayer, out_featureclass)
        else:
            arcpy.management.Append(polygons_sublayer, out_featureclass)

    print("Script completed successfully")

except Exception as e:
    # If an error occurred, print line number and error message
    import traceback, sys
    tb = sys.exc_info()[2]
    print("An error occurred on line %i" % tb.tb_lineno)
    print(str(e))