Script evaluator examples

Available with Network Analyst license.

Evaluators in a network dataset calculate and assign an attribute value for each network element. Field Script and Element Script are two types of evaluators. They each use expressions to calculate the value that gets assigned to each element. Field Script evaluators use fields from network sources; Element Script evaluators use parameters on the same attribute or values from other network attributes.

Each of these evaluators, Field Script and Element Script, use Python expressions, similar to the Calculate Field tool.

This topic presents examples of Field Script and Element Script evaluators configured using Python.

Learn more about types of evaluators used by the network

Field Script evaluator examples

Field Script evaluators calculate the attribute's value by referencing fields from the network dataset's source feature classes.

Field Script Evaluator dialog box

When constructing Field Script evaluators with Python, fields should be referenced using their names (not aliases) and coded using ! to bracket the name. For example, when using a field called RoadClass, code the field as !RoadClass! in Python.

The geometry of a feature can be used for calculations involving shape length. The shape geometry object is calculated based on the proportionate geodesic length of the source segment in the units of the source feature class's coordinate system. For example, if the feature class's shape field is called Shape, code it as !Shape! in Python. When !Shape! is used as part of a distance-based cost attribute, the proportionate length of the source segment will be used and the units of the coordinate system will be converted into the units of the cost attribute. Properties and methods of the geometry object, such as  !Shape!.length or !Shape!.getLength() are not supported. Only the base  !Shape! is supported in the Field Script evaluators.

The !Shape_Length! field, which contains the planar length of the feature, may be also used for calculating length, but it will be treated as a number with no consideration for coordinate system or proportionate length of a feature. Inside the evaluator, its units will be interpreted as the same unit as the unit of the attribute, not the unit of the coordinate system. For this reason, it is recommended that you use the !Shape! field instead

Null values are handled differently depending on the context of the value. For Boolean operations, null either matches the desired criteria or it does not. However, when a null value is used in a mathematical operation, the evaluator may be unable to compute the desired value, and it will cause a build error when building the network dataset. When using a Field Script evaluator, it is important to handle null values to avoid errors when building or solving against the network dataset.

This code sample demonstrates the configuration of a cost attribute with units of minutes calculated from two fields in the source feature class. The RoadClass field represents the road class, and the script uses the road class to determine the speed limit of the road. The Miles field represents the length of the road in miles. The values of these two fields are combined to return the travel time along the road in minutes. Null and unexpected RoadClass field values are handled by assigning a default speed limit value for these roads. Null Miles field values are not handled and will generate errors when the network dataset is built. This is desirable since these errors must be fixed for the network to function correctly, and it is not possible to set a reasonable default for the length of a road segment.

Value:
calc_time(!RoadClass!, !Miles!)

Code Block:
def calc_time(rc, d):
    # This example assumes that the speed limit is in miles per hour
    # and that the distance field is in miles
    if rc == 1:  # Local roads
        speed_limit = 30
    elif rc == 6:  # Major roads
        speed_limit = 55
    elif rc == 2:  # Highways
        speed_limit = 70
    else:  # Set a default speed limit if RoadClass does not match any other option
        speed_limit = 45   
    return 60 * d / speed_limit

Element Script evaluator examples

Element Script evaluator dialog box

Element Script evaluators calculate the attribute's value by referencing the values of other attributes, parameters, and properties of the network dataset. Because the Element Script evaluator calculates its values at the time of analysis rather than when the network dataset is built, this type of evaluator tends to negatively affect analysis performance. Use another evaluator type if possible.

The following sections describe how to construct Element Script evaluators with Python using network attributes and parameters and other properties of the network elements.

Use network attributes and parameters

The AttributeValueByName() method can use the values from other network attributes, while the ParameterValueByName() method uses parameter values from the context attribute, the same attribute for which the evaluator is being written.

MethodDescription

AttributeValueByName

Use the value of another attribute of the context network element.

This method takes a network attribute name as input string.

Examples:

Edge.AttributeValueByName("OtherCost")

Junction.AttributeValueByName("OtherRestriction")

Turn.AttributeValueByName("OtherRestriction")

ParameterValueByName

Use the value of the specified network attribute parameter of the context network attribute.

This method takes a context network attribute parameter name as input string.

Example:

ParameterValueByName("OtherParamName")

Learn more about network attributes

Learn more about network parameters

The following example determines the impedance to traverse a road segment for a cost attribute called  CostAdjustedforSlope, where the time cost for cycling across the road is modified depending on the slope of the road segment. The network has a descriptor attribute called  AverageSlope, which calculates the average slope of the road segment. The network also has a cost attribute called Minutes, which calculates how long in minutes it takes to traverse the road segment. Two parameters have been set up on  CostAdjustedforSlope, one called  SteepUpFactor and one called  SteepDownFactor. These represent the modification factor for going up or down, respectively, a steep slope. If AverageSlope is below -0.05, indicating a steep downhill road segment, it decreases the time to travel over the road. An AverageSlope value above 0.075 increases the time cost.

Value:
cost_adjusted_for_slope("Minutes", "AverageSlope", "SteepUpFactor", "SteepDownFactor")

Code Block:
def cost_adjusted_for_slope(
    time_cost_attr_name, slope_attr_name,
    up_factor_param_name, down_factor_param_name
):
    # Retrieve the values of other attributes for this road
    time_cost = Edge.AttributeValueByName(time_cost_attr_name)
    slope = Edge.AttributeValueByName(slope_attr_name)

    # Retrieve the value of parameters for this attribute
    up_factor = ParameterValueByName(up_factor_param_name)
    down_factor = ParameterValueByName(down_factor_param_name)

    # Set default values in case the parameter values are null
    if up_factor is None: 
        up_factor = 1.25
    if down_factor is None: 
        down_factor = 0.80

    # Calculate the modified travel time cost based on slope
    factor = 1
    if slope < -0.05:  # Steep downhill
        factor = down_factor
    elif slope > 0.075: # Steep uphill
        factor = up_factor
    modified_cost = factor * time_cost

    return modified_cost

In the next example, the Element Script evaluator is for a restriction called  ClosedForEvent, which restricts junctions based on a Boolean parameter named  MarketEvent. A descriptor attribute called  MarketIntersection contains a Boolean value determining whether the given junction will be impacted by the event. If both  MarketEvent  and  MarketIntersection are true, the junction will be restricted; otherwise, it will be traversable.

Value:
is_closed_for_event("MarketIntersection", "MarketEvent")

Code Block:
def is_closed_for_event(is_conditionally_open_attr_name, event_closure_bool_param_name):
    is_affected_by_event = Junction.AttributeValueByName(is_conditionally_open_attr_name)
    is_closed_for_event_param = ParameterValueByName(event_closure_bool_param_name)
    return is_affected_by_event and is_closed_for_event_param

Use network element properties

Element Script evaluators can also use properties of the context network element. To use network element properties in the Element Script evaluator code, invoke the property after the name of the element type.

This example demonstrates how to configure a turn restriction attribute with an Element Script evaluator using the Angle property of the turn element. Sharp turns, for which the turn angle falls in a certain range of values, are restricted.

Value:
no_backwards_turn(Turn.Angle)

Code Block:
def no_backwards_turn(angle):
    if angle >= 135 and angle <= 225:
        # Restrict turns with sharp angles
        return True
    return False