Set analysis inputs

One of the most important parts of performing network analysis with the arcpy.nax module's solver objects is loading inputs. This topic will describe how to properly set your analysis inputs.

Inputs can be loaded using the following:

  • The solver object's load method can load an existing feature class, table or layer.
  • The solver object's insertCursor method can insert data.

Note:

This topic uses Service Area analysis as an example; however, the information provided here can be applied to any type of network analysis.

Load inputs with the load method

If your inputs are already in a feature class, table, layer, feature set, or record set, the quickest way to use them in an analysis is with the load method. The load method adds the contents of your existing input to the network analysis class.

The following code snippet shows how to load facilities from a feature class using the load method when performing a service area analysis.

input_facilities = "C:/data/io.gdb/FireStations"
service_area.load(arcpy.nax.ServiceAreaInputDataType.Facilities, input_facilities)

Learn more about the load method for Service Area analysis in the Methods section of the ServiceArea solver object's documentation.

Use field mappings to preserve fields from your input data

Each network analysis class has a particular schema, and the values of each input field may be important for your analysis. However, the names of the fields supported by the network analysis input class might not match the names of the fields in your input dataset. Use the fieldMappings method to handle the difference. Use fieldMappings to associate a field in your input data to the supported property in the network analysis input class.

For example, consider a Service Area analysis used to determine the area reachable within a 10-minute response time from a set of fire stations. Although most of the 10 minutes represents the time spent driving from the fire station to the site of the emergency, the fire crew must spend time putting on protective equipment and preparing their truck before they can leave the station and start driving. The Service Area solver's input Facilities class has a field named AdditionalTime that can be used to model this necessary extra preparation time.

Your input data may also have a field that represents additional time, but the field might have a different name, such as TurnoutTime. You can use field mapping to map your TurnoutTime field to the AdditionalTime field. When you run the load method with this data, the AdditionalTime field in the Facilities input class will be populated with the values from your TurnoutTime field.

The fieldMappings method generates an NAClassFieldMappings dictionary in which the keys are the supported property names for the network analysis class (such as AdditionalTime) and the values are NAClassFieldMap objects that can be used to set the desired mapping behavior. You can map your TurnoutTime field to the AdditionalTime property by retrieving the AdditionalTime property from the dictionary and setting the associated NAClassFieldMap object's mappedFieldName property to the TurnoutTime field.

You can also set a default value using the defaultValue property. This value will be used for any facility (fire station, in this example) where the TurnoutTime field is null. Note that you can set the defaultValue property for any field even if you are not setting the mappedFieldName to match a field in your data.

The following code snippet shows how to load Service Area facilities using field mapping to map values from a field in your data into a supported property of the Service Area Facilities class.

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
)

Learn more about the fieldMappings method for Service Area analysis in the Methods section of the ServiceArea solver object's documentation.

See a complete list of fields supported by each input class for a Service Area analysis

Insert inputs using the insertCursor method

If your inputs are something other than a feature class or layer, such as a .csv file with latitude and longitude or the results of some other analysis, you can directly insert these records into your network analysis using the insertCursor method. This method isn't the same as arcpy.da.InsertCursor, but it behaves in a very similar way.

When you create the cursor, specify which supported input fields you want to set values for using the field_names parameter. Once you have created the cursor, insert rows one at a time with the cursor object's insertRow method. For most network analysis input classes, you will need to specify the geometry of the inputs by using one of the supported shape tokens. For example, using the SHAPE@ token allows you to pass inputs using a geometry object. You can use the SHAPE@XY token to pass a tuple of X and Y coordinates in the spatial reference of the network data source used for the analysis.

The following code snippet shows how to insert Service Area facilities using the insertCursor method. This example uses the SHAPE@XY token to insert the locations of the facilities using their latitude and longitude.

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

The following code snippet shows how to insert Service Area facilities using the insertCursor method. This example constructs point geometries from latitude and longitude values and inserts them using the SHAPE@ token.

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

Learn more about the insertCursor method for Service Area analysis in the Methods section of the ServiceArea solver object's documentation.

Learn more about the SolverInsertCursor object

See a complete list of fields supported by each input class for a Service Area analysis

Locate inputs on the network

The input data for your network analysis rarely coincides exactly with the geometry of the streets in the network. When you perform a network analysis, the solver must determine the exact position on the network used for the analysis that should be used to represent each input location.

Learn more about network location fields and how inputs are located on the network

The arcpy.nax solver objects contain some properties that control locating behavior. For example, you can set the search tolerance distance using the searchTolerance and searchToleranceUnits properties or set a search query using the searchQuery property to restrict network source features matching certain characteristics. Additionally, the analysis object's travel mode and barriers are considered when locating inputs. Inputs are not located on edges and junctions that are restricted by the travel mode or by any barriers you included in the analysis. Learn more about the searchTolerance, searchToleranceUnits, and searchQuery parameters for a Service Area analysis in the Properties section of the ServiceArea solver object's documentation.

Use precalculated network location fields

Although inputs are added to the analysis using the load and insertCursor methods, the network locations are not calculated until the analysis is solved using the solve method. However, it is possible to use precalculated network locations by specifying network location fields in either load or insertCursor. This saves time during the solve process, and it can speed up your overall analysis if you are going to use the same input locations more than once.

Learn how to precalculate network locations

Use precalculated network location fields with the load method

To use precalculated network location fields when loading data, set the load method's use_location_fields parameter to True. This will include the network location fields in the NAClassFieldMappings dictionary returned by the load method. The network location fields can then be mapped like any other input fields.

As long as the precalculated network location fields in your input data have the standard field names, you do not need to explicitly map your fields. They will be automatically mapped to the input class's location fields when the NAClassFieldMappings dictionary is created, and they will be used by the analysis if you use these field mappings when you call the load method.

Use precalculated network location fields with the insertCursor method

To use precalculated network location fields when inserting data with the insertCursor method, include these fields in the field_names parameter when calling the insertCursor method. You can set values for these fields just like any other field when inserting rows.

Tip:

If you insert rows using network location fields, you do not need to specify geometry for the inputs using any of the special shape tokens. The solver uses the geometry to calculate the network locations, but this is not needed if the network locations have already been determined.

Include custom fields in analysis inputs

In some cases, you may want to include additional fields in your network analysis that do not correspond to any of the supported network analysis properties. For example, if you are modeling fire station coverage, you may want to include the number of trucks based out of each station. This information will not be used for the network analysis itself, but it will be used for reporting purposes later. It is possible to include additional fields like this in your network analysis inputs, and these fields are typically passed to the analysis outputs. For example, extra fields in the Service Area Facilities input class will be included in the ServiceAreaResult object's Facilities output class as well.

Tip:

Use the fieldNames method to verify that your custom fields have been successfully added to an analysis input class. Learn more about the fieldNames method for Service Area analysis in the Methods section of the ServiceArea solver object's documentation.

Include custom fields when using the load method

If you are loading a feature class or layer into your analysis using the load method, use the list_candidate_fields parameter fieldMappings method to include nondefault fields from your input data. This parameter accepts a list of field objects that can be obtained from the feature class or layer you plan to load. All fields included in this list will be included in the field mapping dictionary, and when you use these field mappings with the load method, all fields will be included in your analysis inputs.

The following code snippet shows how to use the fieldMappings method's list_candidate_fields parameter to include all fields from your input data in the Service Area analysis's Facilities input class.

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
)

The following code snippet is similar to the previous one, but rather than including all fields from your input data, it shows how to include only a specific one.

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
)

Include custom fields when using the insertCursor method

If you are inserting data directly into the analysis inputs using the insertCursor method, you must first add your desired nondefault fields to the input class using the addFields method. Once the desired fields have been added, you can include them in the field_names parameter when calling the insertCursor method and insert values as normal.

Learn more about the addFields method for Service Area analysis in the Methods section of the ServiceArea solver object's documentation.

The following code snippet shows how to add a nondefault field using the addFields method and insert rows with values for this field using the insertCursor method.

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