创建服务区分析图层 (Network Analyst)

摘要

创建服务区网络分析图层并设置其分析属性。 服务区分析图层主要用于确定在指定中断成本范围内能从设施点位置访问的区域。 该图层可通过本地网络数据集进行创建,也可通过在线托管路径服务或门户托管路径服务进行创建。

使用情况

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

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

  • ArcGIS AllSource 中,网络分析图层数据存储在文件地理数据库要素类中的磁盘上。 在工程中创建网络分析图层时,将在当前工作空间环境的新要素数据集中创建图层数据。 在 Python 脚本中创建网络分析图层时,您必须首先使用 arcpy.env.workspace = "<path to file gdb>" 将工作空间环境显式地设置到想要存储图层数据的文件地理数据库。 创建图层后,将向该文件地理数据库添加一个包含相应子图层要素类的新要素数据集。

参数

标注说明数据类型
网络数据源

将对其执行网络分析的网络数据集或服务。 将门户 URL 用于服务。

Network Dataset Layer;String
图层名称
(可选)

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

String
出行模式
(可选)

分析中使用的出行模式名称。 出行模式为一组网络设置(例如行驶限制和 U 形转弯),用于确定行人、车辆、卡车或其他交通媒介在网络中的移动方式。 出行模式在网络数据源中进行定义。

arcpy.na.TravelMode 对象和包含出行模式有效 JSON 表示的字符串也可用作参数的输入。

String
行驶方向
(可选)

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

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

  • 远离设施点出行方向为离开设施点。 这是默认设置。
  • 朝向设施点出行方向为行至设施点。
String
中断
(可选)

将使用所选出行模式使用的抗阻属性单位计算服务区范围。 例如,分析行驶时间时,中断值 10 表示生成的服务区将代表 10 分钟行驶区域内可送达的区域。

可设置多个中断值以便创建同心服务区。 例如,要针对同一设施点查找 2 分钟、3 分钟和 5 分钟内的服务区,可将该参数值指定为 2、3 和 5。

在设施点子图层中指定单独的中断值可按设施点覆盖默认中断值。

Double
时间
(可选)

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

  • 如果将行驶方向设置为远离设施点,则此值表示离开时间。
  • 如果将行驶方向设置为朝向设施点,则此值表示到达时间。

根据使用抗阻值的出行模式查找可到达的道路,而抗阻值根据时间的不同而不同(例如取决于动态交通状况)时,时间参数最为有用。 使用不同的时间值求解同一分析可查看设施点可到达的道路如何随时间的变化而变化。 例如,消防站周围的 5 分钟服务区在大清早时可能变得大一点,而在早高峰期消失,上午晚些时候服务区又扩大,并在一天中都保持这样。

可将时间和日期指定为 10/21/2015 10:30 AM。

将您的分析配置为使用以下特殊日期之一来模拟一周中的某天或当前日期,而不是特定的静态日期:

  • 今天 - 12/30/1899
  • 星期日 - 12/31/1899
  • 星期一 - 1/1/1900
  • 星期二 - 1/2/1900
  • 星期三 - 1/3/1900
  • 星期四 - 1/4/1900
  • 星期五 - 1/5/1900
  • 星期六 - 1/6/1900

了解如何在网络分析中使用和解释日期和时间的详细细腻

Date
时区
(可选)

指定时间参数的时区。

  • 各位置的本地时间时间参数将使用设施点所处的一个或多个时区。 服务区开始时间或结束时间的时区交错。 这是默认设置。例如,如果将时间设为 9:00 a.m.,则会为处于东部时区的设施点生成东部时间 9:00 a.m. 的服务区、为处于中部时区的设施点生成中部时间 9:00 a.m. 的服务区、为处于山区时区的设施点生成山区时间 9:00 a.m. 的服务区等等。 如果商店处于覆盖美国、在当地时间 9:00 a.m. 开业的商店链中,请在一次求解中选择此参数值来查找处于所有商店开业时间的市场地区。 首先,东部时区的商店将开业,并生成面。 一个小时后,商店将在中部时区开业,依此类推。 当地时间始终为 9 点,但却因不同时区而实时交错。
  • UTC时间参数将使用协调世界时间 (UTC)。 无论各设施点处于哪些时区或区域都会同时到达或出发。如果将时间设为 2:00 p.m.,则会为处于东部时区的设施点生成东部标准时间 9:00 a.m. 的服务区、为处于中部时区的设施点生成中部标准时间 8:00 a.m. 的服务区、为处于山区时区的设施点生成山区标准时间 7:00 a.m. 的服务区等等。
    注:

    以上情况均假定为标准时间。 在夏令时期间,东部、中部、和山地时间应各提前 1 小时(即分别为 10:00 a.m.、9:00 a.m. 和 8:00 a.m.)。

    UTC 选项可用于为跨两个时区的管辖区显示紧急响应范围。 将急救车辆加载为设施点。 将时间设置为 UTC 的当前时间。 (您需要确定当前 UTC 时间和日期,以便正确使用此选项。)设置其他属性,并对分析进行求解。 尽管时区边界会分割车辆,但结果仍将显示当前交通状况下可以到达的区域。 也可对其他时间使用相同的过程,而不仅是当前时间。
String
输出类型
(可选)

指定要生成的输出类型。 服务区输出可以是超过中断值前表示可到达道路的线要素,也可以是包括这些线的面要素(表示可达到的区域)。

如果网络数据源是不支持线生成的 Portal for ArcGIS 版本上的服务,则线以及面和线输出类型将不可用。

  • 服务区输出将仅包含面。 这是默认设置。
  • 线服务区输出将仅包含线。
  • 面和线服务区输出将既包含面又包含线。
String
面细节
(可选)

指定输出面的细节层次。

如果分析包括的市区具有类似格网的街道网络,则概化面和标准面之间的差异十分细微。 但是,如果涉及山区和农村道路,则标准面表示的结果可能要比概化面更加详细。

  • 标准将以标准细节层次创建面。 这是默认设置。
  • 概化将使用网络的等级属性创建概化面,以快速生成结果。 如果网络没有等级属性,则此选项不可用。
  • 将创建细节层次较高的面,以便用于需要精细结果的情况。
String
重叠几何
(可选)

指定多个设施点中服务区输出间的相互行为。

  • 重叠将为各个设施点创建单独的面或线集。 这些面或线可以相互叠置。 这是默认设置。
  • 融合将中断值相同的多个设施点面合并为一个单独的面。 该选项不适用于线输出。
  • 分割区域将分配至最近设施点,因此面或线不会相互重叠。
String
中断几何
(可选)

指定在指定了多个中断值的情况下单个设施点服务区输出的行为。 该参数不适用于线输出。

  • 圆环各个面将仅包括连续中断值之间的区域。 其将不会包括设施点和任何较小中断值之间的区域。 例如,如果创建 5 分钟和 10 分钟服务区,5 分钟服务区面将包含 0 到 5 分钟内可到达的区域,而 10 分钟服务区面则包括 5 到 10 分钟内可到达的区域。 这是默认设置。
  • 圆盘各个面将包含从设施点到中断值内可到达的区域,其中包括较小中断值内可到达的区域。 例如,如果创建 5 分钟和 10 分钟服务区,则 10 分钟服务区面将包含 5 分钟服务区面内的区域。
String
面修剪距离
(可选)

服务区面修剪距离。 面修剪距离是附近没有其他可到达道路时,服务区面将从道路延伸的距离,类似于线缓冲大小。 这在网络稀疏且不需要服务区覆盖大片不含要素的区域时十分有用。

该参数包括距离的值和单位。 默认值是 100 米。

Linear Unit
在面生成过程中排除源
(可选)

生成服务区面时将要排除的网络数据集边源。 不会在已排除源周围生成面,即使它们在分析中遍历。

从服务区面中排除网络源时,不会阻止遍历这些源。 从服务区面中排除网络源仅影响服务区的面形状。 要阻止遍历给定网络源,必须在定义网络数据集时创建适当的限制。

在生成面的过程中,如果需要排除某些会创建低精度的面或者对服务区分析无关紧要的网络源时,此选项十分有用。 例如,在包含街道和地铁线路的多模式网络中创建步行时间服务区时,应面生成过程中排除地铁线路。 尽管旅客可以乘坐地铁线路,但是他们却无法在地铁线路中途下车或进入到附近建筑。 相反,他们必须全程乘坐地铁线路,在地铁站离开地铁系统,然后通过街道步行至建筑物内。 沿地铁线路生成的面要素不会十分准确。

此参数在以下情况中不可用:输出几何类型不包括面,网络中的边源少于两个,网络数据源是 ArcGIS Online 服务,或者网络数据源服务所在 Portal for ArcGIS 的版本不支持排除源功能。

String
累积属性
(可选)

分析过程中要累积的成本属性的列表。 这些累积属性仅供参考;求解程序仅使用求解分析时指定的出行模式所使用的成本属性。

对于每个累积的成本属性,会在网络分析输出要素中填充 Total_[阻抗] 属性。

如果分析图层未配置为输出线、网络数据源为 ArcGIS Online 服务,或如果网络数据源是不支持累积的 Portal for ArcGIS 版本上的服务,则此参数不可用。

String
忽略求解时无效的位置
(可选)

指定是否忽略无效的输入位置。 通常,如果无法在网络上定位,则位置无效。 当无效位置被忽略时,求解器将跳过它们并尝试使用剩余位置执行分析。

  • 选中 - 将忽略无效的输入位置,并且仅使用有效的位置。 这是默认设置。
  • 未选中 - 将使用所有输入位置。 无效的位置将导致分析失败。
Boolean

派生输出

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

新创建的网络分析图层。

Network Analyst Layer

arcpy.management.MakeServiceAreaAnalysisLayer(network_data_source, {layer_name}, {travel_mode}, {travel_direction}, {cutoffs}, {time_of_day}, {time_zone}, {output_type}, {polygon_detail}, {geometry_at_overlaps}, {geometry_at_cutoffs}, {polygon_trim_distance}, {exclude_sources_from_polygon_generation}, {accumulate_attributes}, {ignore_invalid_locations})
名称说明数据类型
network_data_source

将对其执行网络分析的网络数据集或服务。 将门户 URL 用于服务。

Network Dataset Layer;String
layer_name
(可选)

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

String
travel_mode
(可选)

分析中使用的出行模式名称。 出行模式为一组网络设置(例如行驶限制和 U 形转弯),用于确定行人、车辆、卡车或其他交通媒介在网络中的移动方式。 出行模式在网络数据源中进行定义。

arcpy.na.TravelMode 对象和包含出行模式有效 JSON 表示的字符串也可用作参数的输入。

String
travel_direction
(可选)

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

  • FROM_FACILITIES出行方向为离开设施点。 这是默认设置。
  • TO_FACILITIES出行方向为行至设施点。

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

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

将使用所选出行模式使用的抗阻属性单位计算服务区范围。 例如,分析行驶时间时,中断值 10 表示生成的服务区将代表 10 分钟行驶区域内可送达的区域。

可设置多个中断值以便创建同心服务区。 例如,要针对同一设施点查找 2 分钟、3 分钟和 5 分钟内的服务区,可将该参数值指定为 2、3 和 5。

在设施点子图层中指定单独的中断值可按设施点覆盖默认中断值。

Double
time_of_day
(可选)

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

  • 如果 travel_direction='FROM_FACILITIES',则此值表示离开时间。
  • 如果 travel_direction='TO_FACILITIES',则此值表示到达时间。

根据使用抗阻值的出行模式查找可到达的道路,而抗阻值根据时间的不同而不同(例如取决于动态交通状况)时,time_of_day 参数最为有用。 使用不同的 time_of_day 值求解同一分析可查看设施点可到达的道路如何随时间的变化而变化。 例如,消防站周围的 5 分钟服务区在大清早时可能变得大一点,而在早高峰期消失,上午晚些时候服务区又扩大,并在一天中都保持这样。

可将时间和日期指定为 10/21/2015 10:30 AM。

将您的分析配置为使用以下特殊日期之一来模拟一周中的某天或当前日期,而不是特定的静态日期:

  • 今天 - 12/30/1899
  • 星期日 - 12/31/1899
  • 星期一 - 1/1/1900
  • 星期二 - 1/2/1900
  • 星期三 - 1/3/1900
  • 星期四 - 1/4/1900
  • 星期五 - 1/5/1900
  • 星期六 - 1/6/1900

了解如何在网络分析中使用和解释日期和时间的详细细腻

Date
time_zone
(可选)

指定时间参数的时区。

  • LOCAL_TIME_AT_LOCATIONS时间参数将使用设施点所处的一个或多个时区。 服务区开始时间或结束时间的时区交错。 这是默认设置。例如,如果将时间设为 9:00 a.m.,则会为处于东部时区的设施点生成东部时间 9:00 a.m. 的服务区、为处于中部时区的设施点生成中部时间 9:00 a.m. 的服务区、为处于山区时区的设施点生成山区时间 9:00 a.m. 的服务区等等。 如果商店处于覆盖美国、在当地时间 9:00 a.m. 开业的商店链中,请在一次求解中选择此参数值来查找处于所有商店开业时间的市场地区。 首先,东部时区的商店将开业,并生成面。 一个小时后,商店将在中部时区开业,依此类推。 当地时间始终为 9 点,但却因不同时区而实时交错。
  • UTC时间参数将使用协调世界时间 (UTC)。 无论各设施点处于哪些时区或区域都会同时到达或出发。如果将时间设为 2:00 p.m.,则会为处于东部时区的设施点生成东部标准时间 9:00 a.m. 的服务区、为处于中部时区的设施点生成中部标准时间 8:00 a.m. 的服务区、为处于山区时区的设施点生成山区标准时间 7:00 a.m. 的服务区等等。
    注:

    以上情况均假定为标准时间。 在夏令时期间,东部、中部、和山地时间应各提前 1 小时(即分别为 10:00 a.m.、9:00 a.m. 和 8:00 a.m.)。

    UTC 选项可用于为跨两个时区的管辖区显示紧急响应范围。 将急救车辆加载为设施点。 将时间设置为 UTC 的当前时间。 (您需要确定当前 UTC 时间和日期,以便正确使用此选项。)设置其他属性,并对分析进行求解。 尽管时区边界会分割车辆,但结果仍将显示当前交通状况下可以到达的区域。 也可对其他时间使用相同的过程,而不仅是当前时间。
String
output_type
(可选)

指定要生成的输出类型。 服务区输出可以是超过中断值前表示可到达道路的线要素,也可以是包括这些线的面要素(表示可达到的区域)。

  • POLYGONS服务区输出将仅包含面。 这是默认设置。
  • LINES服务区输出将仅包含线。
  • POLYGONS_AND_LINES服务区输出将既包含面又包含线。

如果网络数据源是不支持线生成的 Portal for ArcGIS 版本上的服务,则线以及面和线输出类型将不可用。

String
polygon_detail
(可选)

指定输出面的细节层次。

  • STANDARD将以标准细节层次创建面。 这是默认设置。
  • GENERALIZED将使用网络的等级属性创建概化面,以快速生成结果。 如果网络没有等级属性,则此选项不可用。
  • HIGH将创建细节层次较高的面,以便用于需要精细结果的情况。

如果分析包括的市区具有类似格网的街道网络,则概化面和标准面之间的差异十分细微。 但是,如果涉及山区和农村道路,则标准面表示的结果可能要比概化面更加详细。

String
geometry_at_overlaps
(可选)

指定多个设施点中服务区输出间的相互行为。

  • OVERLAP将为各个设施点创建单独的面或线集。 这些面或线可以相互叠置。 这是默认设置。
  • DISSOLVE将中断值相同的多个设施点面合并为一个单独的面。 该选项不适用于线输出。
  • SPLIT区域将分配至最近设施点,因此面或线不会相互重叠。
String
geometry_at_cutoffs
(可选)

指定在指定了多个中断值的情况下单个设施点服务区输出的行为。 该参数不适用于线输出。

  • RINGS各个面将仅包括连续中断值之间的区域。 其将不会包括设施点和任何较小中断值之间的区域。 例如,如果创建 5 分钟和 10 分钟服务区,5 分钟服务区面将包含 0 到 5 分钟内可到达的区域,而 10 分钟服务区面则包括 5 到 10 分钟内可到达的区域。 这是默认设置。
  • DISKS各个面将包含从设施点到中断值内可到达的区域,其中包括较小中断值内可到达的区域。 例如,如果创建 5 分钟和 10 分钟服务区,则 10 分钟服务区面将包含 5 分钟服务区面内的区域。
String
polygon_trim_distance
(可选)

服务区面修剪距离。 面修剪距离是附近没有其他可到达道路时,服务区面将从道路延伸的距离,类似于线缓冲大小。 这在网络稀疏且不需要服务区覆盖大片不含要素的区域时十分有用。

该参数包括距离的值和单位。 默认值是 100 米。

Linear Unit
exclude_sources_from_polygon_generation
[exclude_sources_from_polygon_generation,...]
(可选)

生成服务区面时将要排除的网络数据集边源。 不会在已排除源周围生成面,即使它们在分析中遍历。

从服务区面中排除网络源时,不会阻止遍历这些源。 从服务区面中排除网络源仅影响服务区的面形状。 要阻止遍历给定网络源,必须在定义网络数据集时创建适当的限制。

在生成面的过程中,如果需要排除某些会创建低精度的面或者对服务区分析无关紧要的网络源时,此选项十分有用。 例如,在包含街道和地铁线路的多模式网络中创建步行时间服务区时,应面生成过程中排除地铁线路。 尽管旅客可以乘坐地铁线路,但是他们却无法在地铁线路中途下车或进入到附近建筑。 相反,他们必须全程乘坐地铁线路,在地铁站离开地铁系统,然后通过街道步行至建筑物内。 沿地铁线路生成的面要素不会十分准确。

此参数在以下情况中不可用:输出几何类型不包括面,网络中的边源少于两个,网络数据源是 ArcGIS Online 服务,或者网络数据源服务所在 Portal for ArcGIS 的版本不支持排除源功能。

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

分析过程中要累积的成本属性的列表。 这些累积属性仅供参考;求解程序仅使用求解分析时指定的出行模式所使用的成本属性。

对于每个累积的成本属性,会在网络分析输出要素中填充 Total_[阻抗] 属性。

如果分析图层未配置为输出线、网络数据源为 ArcGIS Online 服务,或如果网络数据源是不支持累积的 Portal for ArcGIS 版本上的服务,则此参数不可用。

String
ignore_invalid_locations
(可选)

指定是否忽略无效的输入位置。 通常,如果无法在网络上定位,则位置无效。 当无效位置被忽略时,求解器将跳过它们并尝试使用剩余位置执行分析。

  • SKIP无效的输入位置将被忽略,只使用有效的位置。 这是默认设置。
  • HALT将使用所有输入位置。 无效的位置将导致分析失败。
Boolean

派生输出

名称说明数据类型
out_network_analysis_layer

新创建的网络分析图层。

Network Analyst Layer

代码示例

MakeServiceAreaAnalysisLayer 示例 1(Python 窗口)

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

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

使用所有参数运行此工具

network = "C:/Data/Paris.gdb/Transportation/ParisMultimodal_ND"
arcpy.na.MakeServiceAreaAnalysisLayer(network, "WarehouseCoverage",
                                "Driving Time", "FROM_FACILITIES", [5, 10, 15],
                                "1/1/1900 9:00 AM", "UTC", "POLYGONS",
                                "STANDARD", "DISSOLVE", "RINGS", "100 meters",
                                ["Metro_Lines", "Transfer_Stations",
                                "Transfer_Street_Station"], ["Meters", 
                                "DriveTime"])
MakeServiceAreaAnalysisLayer 示例 3(工作流)

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

# Name: MakeServiceAreaAnalysisLayer_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:
    #Check out Network Analyst license if available. Fail if the Network Analyst license is not available.
    if arcpy.CheckExtension("network") == "Available":
        arcpy.CheckOutExtension("network")
    else:
        raise arcpy.ExecuteError("Network Analyst Extension license is not available.")
    
    #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"
    travel_mode = "Driving Time"
    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 so we can determine the
    #number of fire stations that cover a given location. We will specify these
    #options while creating the new service area layer.
    result_object = arcpy.na.MakeServiceAreaAnalysisLayer(network, layer_name,
                                    travel_mode, "FROM_FACILITIES", [1, 2, 3],
                                    polygon_detail="HIGH",
                                    geometry_at_overlaps="OVERLAP",
                                    geometry_at_cutoffs="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))
MakeServiceAreaAnalysisLayer 示例 4(工作流)

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

旧版本:

GetNASublayer 功能可用于检索网络分析图层的子图层。 它是在 ArcGIS Pro 2.7 中引入的。 在以前的软件版本中,用于检索网络分析图层的子图层对象的最佳方法是使用网络分析 Layer 对象的 listLayers 方法,该方法将子图层名称用作通配符。

# Name: MakeServiceAreaAnalysisLayer_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:
    # Check out Network Analyst license if available. Fail if the Network Analyst license is not available.
    if arcpy.CheckExtension("network") == "Available":
        arcpy.CheckOutExtension("network")
    else:
        raise arcpy.ExecuteError("Network Analyst Extension license is not available.")
    
    # 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")
    travel_mode = "Driving Time"
    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.MakeServiceAreaAnalysisLayer(network, layer_name,
                                                travel_mode, "FROM_FACILITIES",
                                                [3], polygon_detail="HIGH",
                                                geometry_at_overlaps="OVERLAP")

    # 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, "")

    # 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 = arcpy.na.GetNASublayer(layer_object, "Facilities")
    polygons_sublayer = arcpy.na.GetNASublayer(layer_object, "SAPolygons")

    # 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))