创建 OD 成本矩阵图层 (Network Analyst)

摘要

创建起始-目的地 (OD) 成本矩阵网络分析图层并设置其分析属性。OD 成本矩阵分析图层对于描述从一组起始位置到一组目的地位置的成本矩阵十分有用。

使用情况

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

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

参数

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

要执行 OD 成本矩阵分析的网络数据集。

Network Dataset Layer
输出图层名称

要创建的 OD 成本矩阵网络分析图层的名称。

String
阻抗属性

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

String
默认中断
(可选)

中断为指定起始点搜索目的地时对应的默认阻抗值。如果累积的阻抗大于中断值,则停止遍历。可通过指定起始点的中断值来覆盖此默认值。

Double
要查找的默认目的地数
(可选)

要为每个起始点查找的默认目的地数。可通过为起始点的 TargetDestinationCount 属性指定一个值来覆盖默认值。

Long
累加器
(可选)

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

对于每个累积的成本属性,均会向求解程序所输出的路径中添加一个 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
等级设置
(可选)

旧版本:

在版本 10 之前,可使用此参数将网络数据集中建立的默认等级范围更改为其他范围以用于分析。 而版本 10 中不再支持此参数。 要更改等级范围以进行分析,请更新网络数据集中的默认等级范围。

Network Analyst Hierarchy Settings
输出路径形状
(可选)
  • NO_LINES将不会为输出路径生成任何形状。这在存在大量的起始点和目的地,但您只对 OD 成本矩阵表(而不是输出线的形状)感兴趣时很有用。
  • STRAIGHT_LINES输出路径形状是介于各个起始点-目的地对之间的直线(单线)。

无论选择何种输出 shape 类型,最佳路径始终由网络阻抗(而非欧氏距离)决定。 这表示只是路径形状不同,而对网络进行的基础遍历则相同。

String
开始时间
(可选)

指示从起始点出发的时间。

如果您已经选择了基于流量的阻抗属性,将会根据特定的某天某时的动态交通状况来生成解决方案。日期和时间可被指定为 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.

Date

派生输出

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

新创建的网络分析图层。

网络分析图层

arcpy.management.MakeODCostMatrixLayer(in_network_dataset, out_network_analysis_layer, impedance_attribute, {default_cutoff}, {default_number_destinations_to_find}, {accumulate_attribute_name}, {UTurn_policy}, {restriction_attribute_name}, {hierarchy}, {hierarchy_settings}, {output_path_shape}, {time_of_day})
名称说明数据类型
in_network_dataset

要执行 OD 成本矩阵分析的网络数据集。

Network Dataset Layer
out_network_analysis_layer

要创建的 OD 成本矩阵网络分析图层的名称。

String
impedance_attribute

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

String
default_cutoff
(可选)

中断为指定起始点搜索目的地时对应的默认阻抗值。如果累积的阻抗大于中断值,则停止遍历。可通过指定起始点的中断值来覆盖此默认值。

Double
default_number_destinations_to_find
(可选)

要为每个起始点查找的默认目的地数。可通过为起始点的 TargetDestinationCount 属性指定一个值来覆盖默认值。

Long
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
hierarchy
(可选)
  • USE_HIERARCHY将使用等级属性进行分析。 使用等级的结果是,求解程序更偏好高等级的边而不是低等级的边。 分等级求解的速度更快,并且可用于模拟驾驶员在可能的情况下选择在高速公路而非地方道路上行驶(即使行程可能更远)的偏好。 只有输入网络数据集具有等级属性时,此选项才有效。
  • NO_HIERARCHY将不会使用等级属性进行分析。 如果未使用等级,则结果是网络数据集的精确路径。

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

Boolean
hierarchy_settings
(可选)

旧版本:

在版本 10 之前,可使用此参数将网络数据集中建立的默认等级范围更改为其他范围以用于分析。 而版本 10 中不再支持此参数,并且应将其指定为空字符串。 要更改等级范围以进行分析,请更新网络数据集中的默认等级范围。

Network Analyst Hierarchy Settings
output_path_shape
(可选)
  • NO_LINES将不会为输出路径生成任何形状。这在存在大量的起始点和目的地,但您只对 OD 成本矩阵表(而不是输出线的形状)感兴趣时很有用。
  • STRAIGHT_LINES输出路径形状是介于各个起始点-目的地对之间的直线(单线)。

无论选择何种输出 shape 类型,最佳路径始终由网络阻抗(而非欧氏距离)决定。 这表示只是路径形状不同,而对网络进行的基础遍历则相同。

String
time_of_day
(可选)

指示从起始点出发的时间。

如果您已经选择了基于流量的阻抗属性,将会根据特定的某天某时的动态交通状况来生成解决方案。日期和时间可被指定为 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.

Date

派生输出

名称说明数据类型
output_layer

新创建的网络分析图层。

网络分析图层

代码示例

MakeODCostMatrixLayer 示例 1(Python 窗口)

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

network = "C:/Data/Paris.gdb/Transportation/ParisMultimodal_ND"
arcpy.na.MakeODCostMatrixLayer(network, "DrivetimeCosts", "DriveTime")
MakeODCostMatrixLayer 示例 2(Python 窗口)

使用所有参数运行此工具

network = "C:/Data/Paris.gdb/Transportation/ParisMultimodal_ND"
arcpy.na.MakeODCostMatrixLayer(network, "DrivetimeCosts", "DriveTime", 10, 20,
                                ["Meters", "DriveTime"], "NO_UTURNS",
                                ["Oneway"], "USE_HIERARCHY", "", "NO_LINES")
MakeODCostMatrixLayer 示例 3(工作流)

以下独立 Python 脚本演示了如何使用 MakeODCostMatrixLayer 工具创建起始-目的地成本矩阵,用于将货物从仓库交付给距离仓库十分钟行程范围内的所有商店。

# Name: MakeODCostMatrixLayer_Workflow.py
# Description: Create an origin-destination cost matrix for delivery of goods
#              from the warehouses to all stores within a 10-minute drive time
#              and save the results to a layer file on disk. Such a matrix can
#              be used as an input for logistics, delivery and routing analyses.
# 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/Paris.gdb"
    network = os.path.join(input_gdb, "Transportation", "ParisMultimodal_ND")
    layer_name = "WarehouseToStoreDrivetimeMatrix"
    impedance = "DriveTime"
    search_tolerance = "1000 Meters"
    accumulate_attributes = ["Meters"]
    origins = os.path.join(input_gdb, "Analysis", "Warehouses")
    destinations = os.path.join(input_gdb, "Analysis", "Stores")
    output_layer_file = os.path.join(output_dir, layer_name + ".lyrx")

    #Create a new OD Cost matrix layer. We wish to find all stores within a 10
    #minute cutoff. Apart from finding the drive time to the stores, we also
    #want to find the total distance, so we will accumulate the "Meters"
    #impedance attribute.
    result_object = arcpy.na.MakeODCostMatrixLayer(network, layer_name,
                                                impedance, 10, "",
                                                accumulate_attributes)

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

    #Get the names of all the sublayers within the OD cost matrix layer.
    sublayer_names = arcpy.na.GetNAClassNames(layer_object)
    #Stores the layer names that we will use later
    origins_layer_name = sublayer_names["Origins"]
    destinations_layer_name = sublayer_names["Destinations"]

    #Load the warehouse locations as origins using a default field mappings and
    #a search tolerance of 1000 Meters.
    arcpy.na.AddLocations(layer_object, origins_layer_name, origins, "",
                          search_tolerance)

    #Load the store locations as destinations and map the NOM field from stores
    #features as Name property using field mappings
    field_mappings = arcpy.na.NAClassFieldMappings(layer_object,
                                                        destinations_layer_name)
    field_mappings["Name"].mappedFieldName = "NOM"
    arcpy.na.AddLocations(layer_object, destinations_layer_name, destinations,
                          field_mappings, search_tolerance)

    #Solve the OD cost matrix layer
    arcpy.na.Solve(layer_object)

    #Save the solved OD cost matrix 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))
MakeODCostMatrixLayer 示例 4(工作流)

下面的独立 Python 脚本演示了如何访问子图层、如何连接输入和输出图层以及如何将输入源和目的地的字段值传输至输出线图层。

# Name: MakeODCostMatrixLayer_Workflow2.py
# Description: Find the travel time to the closest hospital from each census
#               tract and join the travel time and hospital name to the input
#               tracts.
# Requirements: Network Analyst Extension

#Import system modules
import arcpy
from arcpy import env
import datetime
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 inputs and outputs
    input_gdb = "C:/Data/SanFrancisco.gdb"
    network = os.path.join(input_gdb, "Transportation", "Streets_ND")
    origins = os.path.join(input_gdb, "Analysis", "TractCentroids")
    destinations = os.path.join(input_gdb, "Analysis", "Hospitals")
    output_features = "TractCentroids_withOD"

    #Define some OD cost matrix analysis settings
    layer_name = "HospitalsOD"
    #Optimize based on travel time
    impedance = "TravelTime"
    #Calculate the total distance, even though the analysis is optimizing time
    accumulate_attributes = ["Meters"]
    #Find only the closest hospital
    num_hospitals_to_find = 1
    #Set the time of day for the analysis to 6PM on a generic Monday.
    start_time = datetime.datetime(1900, 1, 1, 18, 0, 0)
    #Don't output line shapes (output Lines will still list travel times)
    out_lines = "NO_LINES"

    #Create a new OD cost matrix layer.
    result_object = arcpy.na.MakeODCostMatrixLayer(network, layer_name,
                    impedance,
                    default_number_destinations_to_find=num_hospitals_to_find,
                    accumulate_attribute_name=accumulate_attributes,
                    output_path_shape=out_lines, time_of_day=start_time)

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

    #Get the names of all the sublayers within the OD layer.
    sublayer_names = arcpy.na.GetNAClassNames(layer_object)
    #Store the layer names for later use
    origins_layer_name = sublayer_names["Origins"]
    destinations_layer_name = sublayer_names["Destinations"]

    #The input census tract data has a unique ID field that can be transferred
    #to the analysis layer. Add the field, and then use field mapping to
    #transfer the values.
    arcpy.na.AddFieldToAnalysisLayer(layer_object, origins_layer_name,
                                                        "Tract_ID", "TEXT")
    field_mappings = arcpy.na.NAClassFieldMappings(layer_object,
                                                            origins_layer_name)
    field_mappings["Tract_ID"].mappedFieldName = "ID"

    #Load the census tracts as origins.
    arcpy.na.AddLocations(layer_object, origins_layer_name, origins,
                            field_mappings, "",
                            exclude_restricted_elements = "EXCLUDE")

    #Map the input hospital NAME field to a new Hospital_Name field in
    #Destinations
    arcpy.na.AddFieldToAnalysisLayer(layer_object, destinations_layer_name,
                                                        "Hospital_Name", "TEXT")
    field_mappings = arcpy.na.NAClassFieldMappings(layer_object,
                                                        destinations_layer_name)
    field_mappings["Hospital_Name"].mappedFieldName = "NAME"

    #Load the hospitals as desinations.
    arcpy.na.AddLocations(layer_object, destinations_layer_name, destinations,
                            field_mappings, "",
                            exclude_restricted_elements = "EXCLUDE")

    #Solve the OD layer
    arcpy.na.Solve(layer_object)

    #Get sublayers
    #listLayers returns a list of sublayer layer objects contained in the NA
    #group layer, filtered by layer name used as a wildcard. Use the sublayer
    #name from GetNAClassNames as the wildcard string in case the sublayers
    #have non-default names.
    origins_sublayer = layer_object.listLayers(origins_layer_name)[0]
    destinations_sublayer = layer_object.listLayers(destinations_layer_name)[0]
    lines_sublayer = layer_object.listLayers(sublayer_names["ODLines"])[0]

    #Use the JoinField tool to transfer OD Cost Matrix information to the
    #output feature class
    #Transfer the tract ID from the input Origins to the output Lines
    arcpy.management.JoinField(lines_sublayer, "OriginID",
                                    origins_sublayer, "ObjectID", "Tract_ID")
    #Transfer the hospital name from the input Destinations to the output Lines
    arcpy.management.JoinField(lines_sublayer, "DestinationID",
                            destinations_sublayer, "ObjectID", "Hospital_Name")
    #Transfer fields of interest (hospital name, TravelTime cost, and other
    #accumulated costs) from the output Lines to a copy of the input census
    #tracts feature class using the Tract_ID field
    output_impedance_fieldname = "Total_" + impedance
    fields_to_transfer = ["Hospital_Name", output_impedance_fieldname]
    for field in accumulate_attributes:
        fields_to_transfer.append("Total_" + field)
    arcpy.management.CopyFeatures(origins, output_features)
    arcpy.management.JoinField(output_features, "ID",
                                lines_sublayer, "Tract_ID", fields_to_transfer)

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