使用 arcpy.nax 模块的求解程序对象执行网络分析的最重要部分之一就是加载输入。 本主题介绍如何正确设置分析输入。
可以使用以下步骤加载输入:
- 求解程序对象的 load 方法可以加载现有要素类、表或图层。
- 求解程序对象的 insertCursor 方法可以插入数据。
注:
本主题以服务区分析为例;但是,此处提供的信息可以应用于任何类型的网络分析。
使用 load 方法加载输入
如果您的输入已经位于要素类、表、图层、要素集或记录集中,则在分析中使用它们的最快捷方式是使用 load 方法。 load 方法可将现有输入的内容添加到网络分析类中。
以下代码片段显示了执行服务区分析时如何使用 load 方法从要素类加载设施点。
input_facilities = "C:/data/io.gdb/FireStations"
service_area.load(arcpy.nax.ServiceAreaInputDataType.Facilities, input_facilities)
有关服务区分析的 load 方法的详细信息,请参阅 ServiceArea 求解程序对象文档的“方法”部分。
使用字段映射保留输入数据中的字段
每个网络分析类都具有一个特定方案,每个输入字段的值可能对于您的分析非常重要。 但是,网络分析输入类支持的字段名称可能与输入数据集中的字段名称不匹配。 可以使用 fieldMappings 方法来处理差异。 可以使用 fieldMappings 将输入数据中的字段与网络分析输入类中受支持的属性相关联。
例如,考虑使用服务区分析来确定可在 10 分钟响应时间内从一组消防站到达的区域。 尽管这 10 分钟中的大部分时间代表从消防站行驶到紧急情况现场所花费的时间,但消防员必须先花时间佩戴防护装备并准备好他们的消防车,然后才能离开消防站并开始驾驶。 服务区求解程序的输入 Facilities 类具有一个名为 AdditionalTime 的字段,可用于对此必要的额外准备时间进行建模。
您的输入数据可能还包含一个表示其他时间的字段,但是该字段可能具有不同的名称,例如 TurnoutTime。可以使用字段映射将 TurnoutTime 字段映射到 AdditionalTime 字段。 当使用此数据运行 load 方法时,将使用 TurnoutTime 字段中的值来填充 Facilities 输入类中的 AdditionalTime 字段。
fieldMappings 方法将生成一个 NAClassFieldMappings 字典,其中的关键字是网络分析类受支持的属性名称(例如 AdditionalTime),而值是可用于设置所需映射行为的 NAClassFieldMap 对象。 通过从字典中检索 AdditionalTime 属性并将相关联 NAClassFieldMap 对象的 mappedFieldName 属性设置为 TurnoutTime 字段,即可将 TurnoutTime 字段映射到 AdditionalTime 属性。
您也可以使用 defaultValue 属性来设置默认值。 该值将用于 TurnoutTime 字段为空的任何设施点(在本示例中为消防站)。 请注意,即使您未将 defaultValue 设置为与数据中的字段相匹配,也可以为任何字段设置 mappedFieldName 属性。
以下代码片段显示了如何使用字段映射将数据字段中的值映射到服务区 Facilities 类的受支持属性中,从而加载服务区设施点。
input_facilities = "C:/data/io.gdb/FireStations"
# Construct a field mapping object
field_mappings = service_area.fieldMappings(arcpy.nax.ServiceAreaInputDataType.Facilities)
# Map the TurnoutTime field from your input data to the Service Area Facilities
# class's AdditionalTime property
field_mappings["AdditionalTime"].mappedFieldName = "TurnoutTime"
# Set a default of one minute of additional time in case the TurnoutTime field
# has a null value
field_mappings["AdditionalTime"].defaultValue = 1
# Load your input data using the field mappings
service_area.load(
arcpy.nax.ServiceAreaInputDataType.Facilities,
input_facilities,
field_mappings
)
有关服务区分析的 fieldMappings 方法的详细信息,请参阅 ServiceArea 求解程序对象文档的“方法”部分。
使用 insertCursor 方法插入输入
如果您的输入不是要素类或图层,例如具有经度和纬度的 .csv 文件或某些其他分析的结果,则可以使用 insertCursor 方法将这些记录直接插入到网络分析中。 此方法与 arcpy.da.InsertCursor 不同,但是其行为方式非常相似。
在创建游标时,请指定您要使用 field_names 参数为其设置值的受支持输入字段。 创建游标后,可以使用游标对象的 insertRow 方法一次插入一行。 对于大多数网络分析输入类,您将需要使用受支持的形状令牌之一来指定输入的几何。 例如,借助 SHAPE@ 令牌,可以使用几何对象来传递输入。 可以使用 SHAPE@XY 令牌在用于分析的网络数据源的空间参考中传递一组 X 和 Y 坐标。
以下代码片段显示了如何使用 insertCursor 方法来插入服务区设施点。 本示例将使用 SHAPE@XY 令牌,通过设施点的纬度和经度来插入设施点的位置。
# Define fields to use with the insertCursor
fields = ["Name", "AdditionalTime", "SHAPE@XY"]
# Construct the insertCursor for the desired input type using the fields
# specified
with service_area.insertCursor(arcpy.nax.ServiceAreaInputDataType.Facilities, fields) as cur:
# Insert rows. The lists of values inserted match the designated fields.
cur.insertRow(["Fire Station 1", 1, (-117.10191118199998, 32.634351493000054)])
cur.insertRow(["Fire Station 2", 1, (-116.97970607599996, 32.56210221400005)])
cur.insertRow(["Fire Station 3", 2.5, (-116.97141447099995, 32.654230331000065)])
cur.insertRow(["Fire Station 4", 1.5, (-117.00762504, 32.70097640100005)])
以下代码片段显示了如何使用 insertCursor 方法来插入服务区设施点。 本示例将根据纬度和经度值构造点几何,然后使用 SHAPE@ 令牌将其插入。
sr_wgs84 = arcpy.SpatialReference(4326)
# Input data with latitude and longitude values specified in WGS84 coordinates
input_data = [
["Fire Station 1", 1, -117.10191118199998, 32.634351493000054],
["Fire Station 2", 1, -116.97970607599996, 32.56210221400005],
["Fire Station 3", 2.5, -116.97141447099995, 32.654230331000065],
["Fire Station 4", 1.5, -117.00762504, 32.70097640100005]
]
# Define fields to use with the insertCursor
fields = ["Name", "AdditionalTime", "SHAPE@"]
# Construct the insertCursor for the desired input type using the fields
# specified
with service_area.insertCursor(arcpy.nax.ServiceAreaInputDataType.Facilities, fields) as cur:
for input_pt in input_data:
# Construct a PointGeometry object for the point using the
# correct spatial reference
pt_geom = arcpy.PointGeometry(
arcpy.Point(input_pt[2], input_pt[3]), sr_wgs84)
# Insert the data using its shape
cur.insertRow([input_pt[0], input_pt[1], pt_geom])
以下代码片段显示了如何使用 insertCursor 方法来插入服务区设施点。 此示例将插入 .csv 文件中的行。
代码假设 .csv 文件中存储的数据包含设施点名称、附加时间、经度和纬度,类似于先前示例中的列表。
# Define fields to use with the insertCursor
fields = ["Name", "AdditionalTime", "SHAPE@XY"]
# Open the .csv file and construct a reader using the csv module
with open(in_csv, "r") as f:
reader = csv.reader(f)
# Read the headers and don't try to insert this row
headers = next(reader)
# Construct the insertCursor for the desired input type using the fields
# specified
with service_area.insertCursor(
arcpy.nax.ServiceAreaInputDataType.Facilities,
fields
) as cur:
# Iterate through the CSV file's rows and insert them as facilities
for row in reader:
cur.insertRow(
[row[0], float(row[1]), (float(row[2]), float(row[3]),)]
)
有关服务区分析的 insertCursor 方法的详细信息,请参阅 ServiceArea 求解程序对象文档的“方法”部分。
在网络上定位输入
用于网络分析的输入数据很少与网络中街道的几何完全一致。 在执行网络分析时,求解程序必须确定用于分析的网络上的确切位置,该位置应用于表示每个输入位置。
arcpy.nax 求解程序对象包含一些用于控制所有分析输入的定位行为的属性。
searchSources 属性控制可用于定位的网络源,并可选择允许您指定 SQL 表达式以将定位限制为与特定特征匹配的网络源要素。 例如,您可以将分析配置为在街道上而不是在公共交通线路上定位输入,并且您可以防止输入定位在具有特定道路类值的街道要素上。
在网络上定位输入要素时,searchTolerance 和 searchToleranceUnits 属性控制所需的最大搜索距离。 如果在此距离内未发现有效的网络位置,则输入要素将被视为未定位且无法用于分析。
有关这些服务区分析参数的详细信息,请参阅 ServiceArea 求解程序对象文档的“属性”部分。
分别控制每个输入类的定位行为
在某些情况下,您可能希望分别控制分析中每个输入类的定位行为。 例如,在 OD 成本矩阵分析中,如果搜索查询不需要应用于输入目标和障碍,则可以使用搜索查询仅用于输入源。
使用 setLocateSettingsOverrides 方法为单个输入类配置定位行为,覆盖分析的默认设置。
以下代码片段显示了如何为分析设置默认搜索容差和搜索源,以及仅为输入设施点设置搜索查询。
# Set default search tolerance and search sources for all analysis inputs
service_area.searchTolerance = 200
service_area.searchToleranceUnits = arcpy.nax.DistanceUnits.Feet
service_area.searchSources = [["Streets", ""], ["Streets_ND_Junctions", ""]]
# Set a search query for the input facilities only to prevent locating
# on highway ramps (designated, in this example, as ROAD_CLASS 3). This query
# will not apply to other inputs, such as barriers.
sources = [["Streets", "ROAD_CLASS <> 3"], ["Streets_ND_Junctions", ""]]
service_area.setLocateSettingsOverrides(
arcpy.nax.ServiceAreaInputDataType.Facilities,
search_sources=sources
)
有关该服务区分析方法的详细信息,请参阅 ServiceArea 求解程序对象文档的“方法”部分。
使用预先计算的网络位置字段
虽然使用 load 和 insertCursor 方法将输入添加到分析,但是在使用 solve 方法求解分析前,将不会计算网络位置。 但是,通过在 load 或 insertCursor 中指定网络位置字段,可以使用预先计算的网络位置。 由此可在求解过程中节省时间,并且当您需要多次使用相同的输入位置时,可加快整体分析的速度。
使用预先计算的网络位置字段时,在某些情况下,您可能希望将 allowAutoRelocate 属性设置为 False。 当此属性设置为 True 时,位于受到所选出行模式限制或被障碍物阻挡的网络部分上的输入将在求解时自动重新定位,以确保所有位置都可到达。 在许多情况下,这是期望的行为;但是,如果您想完全按照输入数据中显示的方式使用预先计算的网络位置字段,您可以将 allowAutoRelocate 属性设置为 False。
将预先计算的网络位置字段与 load 方法配合使用
要在加载数据时使用预先计算的网络位置字段,首先使用 fieldMappings 方法构建字段映射。 将 fieldMappings 方法的 use_location_fields 参数设置为 True。 由此将在方法返回的 NAClassFieldMappings 字典中包括网络位置字段。
如果输入数据中预先计算的网络位置字段具有标准名称,则无需显式映射字段。 在创建 NAClassFieldMappings 字典时,可将其自动映射到输入类的位置字段,如果在调用 load 方法时使用这些字段映射,则其将由分析使用。 如果位置字段具有非标准名称,您可以像任何其他输入字段一样将其映射。
以下代码片段显示了如何使用预先计算的网络位置字段来加载服务区设施点。
# Network locations have been precalculated for these inputs
# using the Calculate Locations tool. The feature class
# includes the network location fields:
# SourceID, SourceOID, PosAlong, SideOfEdge
input_facilities = "C:/data/io.gdb/FireStations"
# Construct a field mapping object with network location fields
field_mappings = service_area.fieldMappings(
arcpy.nax.ServiceAreaInputDataType.Facilities,
use_location_fields=True
)
# Load your input data using the field mappings
# Location fields are included automatically because
# of the field mappings.
service_area.load(
arcpy.nax.ServiceAreaInputDataType.Facilities,
input_facilities,
field_mappings
)
将预先计算的网络位置字段与 insertCursor 方法配合使用
在使用 insertCursor 方法插入数据时,要使用预先计算的网络位置字段,请在调用 insertCursor 方法时将这些字段包含在 field_names 参数中。 在插入行时,可以像任何其他字段一样为这些字段设置值。
提示:
如果使用网络位置字段插入行,则无需使用任何特殊形状令牌为输入指定几何。 求解程序将使用几何来计算网络位置,但是如果已确定网络位置,则无需执行此操作。
以下代码片段显示了如何使用 insertCursor 方法通过预先计算的网络位置字段来插入服务区设施点。
# Define fields to use with the insertCursor
fields = ["Name", "SHAPE@XY", "SourceID", "SourceOID", "PosAlong", "SideOfEdge"]
# Define input data with network location fields
# The latitude and longitude are not strictly necessary because the inputs
# have already been located on the network.
input_data = [
["Fire Station 1", (-117.10191118199998, 32.634351493000054), 1, 9533, 0.5, 2],
["Fire Station 2", (-116.97970607599996, 32.56210221400005), 1, 7629, 0.33, 1],
["Fire Station 3", (-116.97141447099995, 32.654230331000065), 1, 2309, 1.0, 1],
["Fire Station 4", (-117.00762504, 32.70097640100005), 1, 9016, 0.62, 1]
]
# Insert the facilities
with service_area.insertCursor(arcpy.nax.ServiceAreaInputDataType.Facilities, fields) as cur:
for input_pt in input_data:
cur.insertRow(input_pt)
在分析输入中包含自定义字段
在某些情况下,您可能需要在网络分析中包含与任何受支持网络分析属性都不对应的其他字段。 例如,如果要对消防站覆盖范围进行建模,则可能需要包括每个消防站的卡车数量。 此信息将不会用于网络分析本身,但稍后将用于报告目的。 可以在网络分析输入中包含与其类似的其他字段,并且通常会将这些字段传递到分析输出。 例如,服务区 Facilities 输入类中的其他字段也将包含在 ServiceAreaResult 对象的 Facilities 输出类中。
提示:
可以使用 fieldNames 方法来验证自定义字段是否已成功添加到分析输入类中。 有关服务区分析的 fieldNames 方法的详细信息,请参阅 ServiceArea 求解程序对象文档的“方法”部分。
使用 load 方法时包含自定义字段
如果要使用 load 方法将要素类或图层加载到分析中,请使用 list_candidate_fields 参数 fieldMappings 方法以包含输入数据中的非默认字段。 该参数将接受可从您计划加载的要素类或图层获得的字段对象列表。 此列表中包含的所有字段都将包含在字段映射字典中,在将这些字段映射与 load 方法配合使用时,所有字段都将包含在分析输入中。
以下代码片段显示了如何使用 fieldMappings 方法的 list_candidate_fields 参数以在服务区分析的 Facilities 输入类中包含输入数据中的所有字段。
input_facilities = "C:/data/io.gdb/FireStations"
# Construct a field mapping object
# Use the list_candidate_fields parameter to include non-default custom fields
# from the input
field_mappings = service_area.fieldMappings(
arcpy.nax.ServiceAreaInputDataType.Facilities,
list_candidate_fields=arcpy.ListFields(input_facilities)
)
# Load your input data using the field mappings
service_area.load(
arcpy.nax.ServiceAreaInputDataType.Facilities,
input_facilities,
field_mappings
)
以下代码片段类似于上一个代码片段,但是不包含输入数据中的所有字段,而是显示了如何仅包含一个特定字段。
input_facilities = "C:/data/io.gdb/FireStations"
extra_fields = [f for f in arcpy.ListFields(input_facilities) if f.name == "NumTrucks"]
# Construct a field mapping object
# Use the list_candidate_fields parameter to include non-default custom fields
# from the input
field_mappings = service_area.fieldMappings(
arcpy.nax.ServiceAreaInputDataType.Facilities,
list_candidate_fields=extra_fields
)
# Load your input data using the field mappings
service_area.load(
arcpy.nax.ServiceAreaInputDataType.Facilities,
input_facilities,
field_mappings
)
使用 insertCursor 方法时包含自定义字段
如果要使用 insertCursor 方法将数据直接插入到分析输入中,则必须首先使用 addFields 方法将所需非默认字段添加到输入类中。 添加了所需字段后,即可在调用 insertCursor 方法时将其包含在 field_names 参数中,并正常插入值。
有关服务区分析的 addFields 方法的详细信息,请参阅 ServiceArea 求解程序对象文档的“方法”部分。
以下代码片段显示了如何使用 addFields 方法添加非默认字段,以及如何使用 insertCursor 方法插入具有该字段值的行。
# Add a custom field called NumTrucks to the Service Area Facilities input class
field_definitions = [["NumTrucks", "SHORT"]]
service_area.addFields(arcpy.nax.ServiceAreaInputDataType.Facilities, field_definitions)
# Define fields to use with the insertCursor
fields = ["Name", "NumTrucks", "AdditionalTime", "SHAPE@XY"]
# Construct the insertCursor for the desired input type using the fields specified
with service_area.insertCursor(arcpy.nax.ServiceAreaInputDataType.Facilities, fields) as cur:
# Insert rows. The lists of values inserted match the designated fields.
cur.insertRow(["Fire Station 1", 1, 1, (-117.10191118199998, 32.634351493000054)])
cur.insertRow(["Fire Station 2", 2, 1, (-116.97970607599996, 32.56210221400005)])
cur.insertRow(["Fire Station 3", 4, 2.5, (-116.97141447099995, 32.654230331000065)])
cur.insertRow(["Fire Station 4", 2, 1.5, (-117.00762504, 32.70097640100005)])