Make Service Area Layer (Network Analyst)

Summary

Makes a service area network analysis layer and sets its analysis properties. A service area analysis layer is useful in determining the area of accessibility within a given cutoff cost from a facility location.

Usage

  • After creating the analysis layer with this tool, you can add network analysis objects to it using the Add Locations tool, solve the analysis using the Solve tool, and save the results on disk using the Save To Layer File tool.

  • When using this tool in geoprocessing models, if the model is run as a tool, the output network analysis layer must be made a model parameter; otherwise, the output layer is not added to the contents of the map.

Parameters

LabelExplanationData Type
Input Analysis Network

The network dataset on which the service area analysis will be performed.

Network Dataset Layer
Output Layer Name

Name of the service area network analysis layer to create.

String
Impedance Attribute

The cost attribute that will be used as impedance in the analysis.

String
Travel From or To Facility
(Optional)

Specifies the direction of travel to or from the facilities.

  • TRAVEL_FROMThe service area is created in the direction away from the facilities.
  • TRAVEL_TOThe service area is created in the direction towards the facilities.

Using this option can result in different service areas on a network with one-way restrictions and having different impedances based on direction of travel. The service area for a pizza delivery store, for example, should be created away from the facility, whereas the service area of a hospital should be created toward the facility.

String
Default Break Values
(Optional)

Default impedance values indicating the extent of the service area to be calculated. The default can be overridden by specifying the break value on the facilities.

Multiple polygon breaks can be set to create concentric service areas. For instance, to find 2-, 3-, and 5-minute service areas for the same facility, specify "2 3 5" as the value for the Default break values parameter (the numbers 2, 3, and 5 should be separated by a space).

String
Polygon Type
(Optional)

Specifies the type of polygons to be generated.

  • SIMPLE_POLYSCreates generalized polygons, which are generated quickly and are fairly accurate, except on the fringes. This is the default.
  • DETAILED_POLYSCreates detailed polygons, which accurately model the service area lines and may contain islands of unreached areas. This option is slower than generating generalized polygons.
  • NO_POLYSTurns off polygon generation for the case in which only service area lines are desired.

If your data is of an urban area with a gridlike network, the difference between generalized and detailed polygons would be minimal. However, for mountain and rural roads, the detailed polygons may present significantly more accurate results than generalized polygons.

String
Merge Polygons with Similar Ranges
(Optional)

Specifies the options to merge polygons that share similar break values. This option is applicable only when generating polygons for multiple facilities.

  • NO_MERGECreates individual polygons for each facility. The polygons can overlap each other.
  • NO_OVERLAPCreates individual polygons that are closest for each facility. The polygons do not overlap each other.
  • MERGE Joins the polygons of multiple facilities that have the same break value.
String
Polygon Nest Option
(Optional)

Specifies the option to create concentric service area polygons as disks or rings. This option is applicable only when multiple break values are specified for the facilities.

  • RINGSDo not include the area of the smaller breaks. This creates polygons going between consecutive breaks. Use this option if you want to find the area from one break to another.
  • DISKS Creates the polygons going from the facility to the break. For instance, If you create 5- and 10-minute service areas, then the 10-minute service area polygon will include the area under the 5-minute service area polygon. Use this option if you want to find the entire area from the facility to the break for each break.
String
Line Type
(Optional)

Specifies the type of lines to be generated based on the service area analysis. Selecting the True Lines or True lines with measures option for large service areas will increase the amount of memory consumed by the analysis.

  • NO_LINESDo not generate lines. This is the default.
  • TRUE_LINESLines are generated without measures.
  • TRUE_LINES_WITH_MEASURESLines are generated with measures. The measure values are generated based on the impedance value on each end of the edge with the intermediate vertices interpolated. Do not use this option if faster performance is desired.
String
Overlap Lines
(Optional)

Determines whether overlapping lines are generated when the service area lines are computed.

  • Checked—Include a separate line feature for each facility when the facilities have service area lines that are coincident.
  • Unchecked—Include each service area line at most once and associate it with its closest (least impedance) facility.
Boolean
Split Lines when They Cross a Service Area Break
(Optional)
  • Checked—Split every line between two breaks into two lines, each lying within its break. This is useful if you want to symbolize the service area lines by break. Otherwise, leave this option unchecked for optimal performance.
  • Unchecked—The lines are not split at the boundaries of the breaks. This is the default.
Boolean
Exclude Sources from Polygon Generation
(Optional)

Specifies the list of network sources to be excluded when generating the polygons. The geometry of traversed elements from the excluded sources will be omitted from all polygons.

This is useful if you have some network sources that you don't want to be included in the polygon generation because they create less accurate polygons or are inconsequential for the service area analysis. For example, while creating a drive time service area in a multimodal network of streets and rails, you should choose to exclude the rail lines from polygon generation so as to correctly model where a vehicle could travel.

Excluding a network source from service area polygons does not prevent those sources from being traversed. Excluding sources from service area polygons only influences the polygon shape of the service areas. If you want to prevent traversal of a given network source, you must create an appropriate restriction when defining your network dataset.

String
Accumulators
(Optional)

A list of cost attributes to be accumulated during analysis. These accumulation attributes are for reference only; the solver only uses the cost attribute specified by the Impedance Attribute parameter to calculate the route.

For each cost attribute that is accumulated, a Total_[Impedance] property is added to the routes that are output by the solver.

String
U-Turn Policy
(Optional)

Specifies the U-turn policy that will be used at junctions. Allowing U-turns implies that the solver can turn around at a junction and double back on the same street. Given that junctions represent street intersections and dead ends, different vehicles may be able to turn around at some junctions but not at others—it depends on whether the junction represents an intersection or a dead end. To accommodate this, the U-turn policy parameter is implicitly specified by the number of edges that connect to the junction, which is known as junction valency. The acceptable values for this parameter are listed below; each is followed by a description of its meaning in terms of junction valency.

  • ALLOW_UTURNSU-turns are permitted at junctions with any number of connected edges. This is the default value.
  • NO_UTURNSU-turns are prohibited at all junctions, regardless of junction valency. However, U-turns are still permitted at network locations even when this option is specified, but you can set the individual network location's CurbApproach property to prohibit U-turns there as well.
  • ALLOW_DEAD_ENDS_ONLYU-turns are prohibited at all junctions, except those that have only one adjacent edge (a dead end).
  • ALLOW_DEAD_ENDS_AND_INTERSECTIONS_ONLYU-turns are prohibited at junctions where exactly two adjacent edges meet but are permitted at intersections (junctions with three or more adjacent edges) and dead ends (junctions with exactly one adjacent edge). Often, networks have extraneous junctions in the middle of road segments. This option prevents vehicles from making U-turns at these locations.

If you need a more precisely defined U-turn policy, consider adding a global turn delay evaluator to a network cost attribute or adjusting its settings if one exists, and pay particular attention to the configuration of reverse turns. You can also set the CurbApproach property of your network locations.

String
Restrictions
(Optional)

A list of restriction attributes that will be applied during the analysis.

String
Trim Polygons
(Optional)
  • Checked—Trims the polygons containing the edges at the periphery of the service area to be within the specified distance of these outer edges. This is useful if the network is very sparse and you don't want the service area to cover large areas where there are no features.
  • Unchecked—Do not trim polygons.
Boolean
Polygon Trim
(Optional)

Specifies the distance within which the service area polygons are trimmed. The parameter includes a value and units for the distance. The default value is 100 meters.

Linear Unit
Include Network Source Fields in Lines
(Optional)
  • Checked—Add the SourceID, SourceOID, FromPosition, and ToPosition fields to the service area lines to hold information about the underlying source features traversed during the analysis. This can be useful to join the results of the service area lines to the original source data.
  • Unchecked—Do not add the source fields (SourceID, SourceOID, FromPosition, and ToPosition) to the service area lines.
Boolean
Use Hierarchy in Analysis
(Optional)
  • Checked—The hierarchy attribute will be used for the analysis. Using a hierarchy results in the solver preferring higher-order edges to lower-order edges. Hierarchical solves are faster, and they can be used to simulate the preference of a driver who chooses to travel on freeways rather than local roads when possible—even if that means a longer trip. This option is active only if the input network dataset has a hierarchy attribute.
  • Unchecked—The hierarchy attribute will not be used for the analysis, and the result will be a service area measured along all edges of the network dataset regardless of hierarchy level.

The parameter is inactive if no hierarchy attribute is defined on the network dataset used to perform the analysis.

Boolean
Time of Day
(Optional)

The time to depart from or arrive at the facilities of the service area layer. The interpretation of this value as a depart or arrive time depends on whether travel is away from or toward the facilities.

  • It represents the departure time if Travel From or To Facility is set to TRAVEL_FROM.
  • It represents the arrival time if Travel From or To Facility is set to TRAVEL_TO.

If you have chosen a traffic-based impedance attribute, the solution will be generated given dynamic traffic conditions at the time of day specified here. A date and time can be specified as 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.

Repeatedly solving the same analysis, but using different Time of Day values, allows you to see how a facility's reach changes over time. For instance, the five-minute service area around a fire station may start out large in the early morning, diminish during the morning rush hour, grow in the late morning, and so on throughout the day.

Date

Derived Output

LabelExplanationData Type
Network Analyst Layer

The newly created network analysis layer.

Network Analyst Layer

arcpy.management.MakeServiceAreaLayer(in_network_dataset, out_network_analysis_layer, impedance_attribute, {travel_from_to}, {default_break_values}, {polygon_type}, {merge}, {nesting_type}, {line_type}, {overlap}, {split}, {excluded_source_name}, {accumulate_attribute_name}, {UTurn_policy}, {restriction_attribute_name}, {polygon_trim}, {poly_trim_value}, {lines_source_fields}, {hierarchy}, {time_of_day})
NameExplanationData Type
in_network_dataset

The network dataset on which the service area analysis will be performed.

Network Dataset Layer
out_network_analysis_layer

Name of the service area network analysis layer to create.

String
impedance_attribute

The cost attribute that will be used as impedance in the analysis.

String
travel_from_to
(Optional)

Specifies the direction of travel to or from the facilities.

  • TRAVEL_FROMThe service area is created in the direction away from the facilities.
  • TRAVEL_TOThe service area is created in the direction towards the facilities.

Using this option can result in different service areas on a network with one-way restrictions and having different impedances based on direction of travel. The service area for a pizza delivery store, for example, should be created away from the facility, whereas the service area of a hospital should be created toward the facility.

String
default_break_values
(Optional)

Default impedance values indicating the extent of the service area to be calculated. The default can be overridden by specifying the break value on the facilities.

Multiple polygon breaks can be set to create concentric service areas. For instance, to find 2-, 3-, and 5-minute service areas for the same facility, specify "2 3 5" as the value for the Default break values parameter (the numbers 2, 3, and 5 should be separated by a space).

String
polygon_type
(Optional)

Specifies the type of polygons to be generated.

  • SIMPLE_POLYSCreates generalized polygons, which are generated quickly and are fairly accurate, except on the fringes. This is the default.
  • DETAILED_POLYSCreates detailed polygons, which accurately model the service area lines and may contain islands of unreached areas. This option is slower than generating generalized polygons.
  • NO_POLYSTurns off polygon generation for the case in which only service area lines are desired.

If your data is of an urban area with a gridlike network, the difference between generalized and detailed polygons would be minimal. However, for mountain and rural roads, the detailed polygons may present significantly more accurate results than generalized polygons.

String
merge
(Optional)

Specifies the options to merge polygons that share similar break values. This option is applicable only when generating polygons for multiple facilities.

  • NO_MERGECreates individual polygons for each facility. The polygons can overlap each other.
  • NO_OVERLAPCreates individual polygons that are closest for each facility. The polygons do not overlap each other.
  • MERGE Joins the polygons of multiple facilities that have the same break value.
String
nesting_type
(Optional)

Specifies the option to create concentric service area polygons as disks or rings. This option is applicable only when multiple break values are specified for the facilities.

  • RINGSDo not include the area of the smaller breaks. This creates polygons going between consecutive breaks. Use this option if you want to find the area from one break to another.
  • DISKS Creates the polygons going from the facility to the break. For instance, If you create 5- and 10-minute service areas, then the 10-minute service area polygon will include the area under the 5-minute service area polygon. Use this option if you want to find the entire area from the facility to the break for each break.
String
line_type
(Optional)

Specifies the type of lines to be generated based on the service area analysis. Selecting the TRUE_LINES or TRUE_LINES_WITH_MEASURES option for large service areas will increase the amount of memory consumed by the analysis.

  • NO_LINESDo not generate lines. This is the default.
  • TRUE_LINESLines are generated without measures.
  • TRUE_LINES_WITH_MEASURESLines are generated with measures. The measure values are generated based on the impedance value on each end of the edge with the intermediate vertices interpolated. Do not use this option if faster performance is desired.
String
overlap
(Optional)

Determines whether overlapping lines are generated when the service area lines are computed.

  • OVERLAP Include a separate line feature for each facility when the facilities have service area lines that are coincident.
  • NON_OVERLAP Include each service area line at most once and associate it with its closest (least impedance) facility.
Boolean
split
(Optional)
  • SPLITSplit every line between two breaks into two lines, each lying within its break. This is useful if you want to symbolize the service area lines by break. Otherwise, use the NO_SPLIT option for optimal performance.
  • NO_SPLITThe lines are not split at the boundaries of the breaks. This is the default.
Boolean
excluded_source_name
[excluded_source_name,...]
(Optional)

Specifies the list of network sources to be excluded when generating the polygons. The geometry of traversed elements from the excluded sources will be omitted from all polygons.

This is useful if you have some network sources that you don't want to be included in the polygon generation because they create less accurate polygons or are inconsequential for the service area analysis. For example, while creating a drive time service area in a multimodal network of streets and rails, you should choose to exclude the rail lines from polygon generation so as to correctly model where a vehicle could travel.

Excluding a network source from service area polygons does not prevent those sources from being traversed. Excluding sources from service area polygons only influences the polygon shape of the service areas. If you want to prevent traversal of a given network source, you must create an appropriate restriction when defining your network dataset.

String
accumulate_attribute_name
[accumulate_attribute_name,...]
(Optional)

A list of cost attributes to be accumulated during analysis. These accumulation attributes are for reference only; the solver only uses the cost attribute specified by the Impedance Attribute parameter to calculate the route.

For each cost attribute that is accumulated, a Total_[Impedance] property is added to the routes that are output by the solver.

String
UTurn_policy
(Optional)

Specifies the U-turn policy that will be used at junctions. Allowing U-turns implies that the solver can turn around at a junction and double back on the same street. Given that junctions represent street intersections and dead ends, different vehicles may be able to turn around at some junctions but not at others—it depends on whether the junction represents an intersection or a dead end. To accommodate this, the U-turn policy parameter is implicitly specified by the number of edges that connect to the junction, which is known as junction valency. The acceptable values for this parameter are listed below; each is followed by a description of its meaning in terms of junction valency.

  • ALLOW_UTURNSU-turns are permitted at junctions with any number of connected edges. This is the default value.
  • NO_UTURNSU-turns are prohibited at all junctions, regardless of junction valency. However, U-turns are still permitted at network locations even when this option is specified, but you can set the individual network location's CurbApproach property to prohibit U-turns there as well.
  • ALLOW_DEAD_ENDS_ONLYU-turns are prohibited at all junctions, except those that have only one adjacent edge (a dead end).
  • ALLOW_DEAD_ENDS_AND_INTERSECTIONS_ONLYU-turns are prohibited at junctions where exactly two adjacent edges meet but are permitted at intersections (junctions with three or more adjacent edges) and dead ends (junctions with exactly one adjacent edge). Often, networks have extraneous junctions in the middle of road segments. This option prevents vehicles from making U-turns at these locations.

If you need a more precisely defined U-turn policy, consider adding a global turn delay evaluator to a network cost attribute or adjusting its settings if one exists, and pay particular attention to the configuration of reverse turns. You can also set the CurbApproach property of your network locations.

String
restriction_attribute_name
[restriction_attribute_name,...]
(Optional)

A list of restriction attributes that will be applied during the analysis.

String
polygon_trim
(Optional)
  • TRIM_POLYSTrims the polygons containing the edges at the periphery of the service area to be within the specified distance of these outer edges. This is useful if the network is very sparse and you don't want the service area to cover large areas where there are no features.
  • NO_TRIM_POLYSDo not trim polygons.
Boolean
poly_trim_value
(Optional)

Specifies the distance within which the service area polygons are trimmed. The parameter includes a value and units for the distance. The default value is 100 meters.

Linear Unit
lines_source_fields
(Optional)
  • LINES_SOURCE_FIELDS Add the SourceID, SourceOID, FromPosition, and ToPosition fields to the service area lines to hold information about the underlying source features traversed during the analysis. This can be useful to join the results of the service area lines to the original source data.
  • NO_LINES_SOURCE_FIELDSDo not add the source fields (SourceID, SourceOID, FromPosition, and ToPosition) to the service area lines.
Boolean
hierarchy
(Optional)
  • USE_HIERARCHYThe hierarchy attribute will be used for the analysis. Using a hierarchy results in the solver preferring higher-order edges to lower-order edges. Hierarchical solves are faster, and they can be used to simulate the preference of a driver who chooses to travel on freeways rather than local roads when possible—even if that means a longer trip. This option is valid only if the input network dataset has a hierarchy attribute.
  • NO_HIERARCHYThe hierarchy attribute will not be used for the analysis, and the result will be a service area measured along all edges of the network dataset regardless of hierarchy level.

The parameter is not used if no hierarchy attribute is defined on the network dataset used to perform the analysis.

Boolean
time_of_day
(Optional)

The time to depart from or arrive at the facilities of the service area layer. The interpretation of this value as a depart or arrive time depends on whether travel is away from or toward the facilities.

  • It represents the departure time if Travel From or To Facility is set to TRAVEL_FROM.
  • It represents the arrival time if Travel From or To Facility is set to TRAVEL_TO.

If you have chosen a traffic-based impedance attribute, the solution will be generated given dynamic traffic conditions at the time of day specified here. A date and time can be specified as 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.

Repeatedly solving the same analysis, but using different Time of Day values, allows you to see how a facility's reach changes over time. For instance, the five-minute service area around a fire station may start out large in the early morning, diminish during the morning rush hour, grow in the late morning, and so on throughout the day.

Date

Derived Output

NameExplanationData Type
output_layer

The newly created network analysis layer.

Network Analyst Layer

Code sample

MakeServiceAreaLayer example 1 (Python window)

Run the tool using only the required parameters.

network = "C:/Data/SanFrancisco.gdb/Transportation/Streets_ND"
arcpy.na.MakeServiceAreaLayer(network, "FireStationCoverage", "TravelTime")
MakeServiceAreaLayer example 2 (Python window)

Run the tool using all parameters.

network = "C:/Data/Paris.gdb/Transportation/ParisMultimodal_ND"
arcpy.na.MakeServiceAreaLayer(network, "WarehouseCoverage", "DriveTime",
                                "TRAVEL_FROM", "5 10 15", "SIMPLE_POLYS", 
                                "NO_OVERLAP", "RINGS", "TRUE_LINES",
                                "NON_OVERLAP", "NO_SPLIT",
                                ["Metro_Lines", "Transfer_Stations",
                                "Transfer_Street_Station"],
                                ["Meters", "DriveTime"], "ALLOW_DEAD_ENDS_ONLY",
                                ["Oneway"], "NO_TRIM_POLYS", "",
                                "LINES_SOURCE_FIELDS")
MakeServiceAreaLayer example 3 (workflow)

The following stand-alone Python script demonstrates how the MakeServiceAreaLayer tool can be used to generate a 1-, 2-, and 3-minute service area around fire stations.

# Name: MakeServiceAreaLayer_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:
    #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"
    impedance = "TravelTime"
    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 as we can determine the
    #number of fire stations that cover a given location. We use hierarchy to
    #speed up the time taken to create the polygons. We will specify these
    #options while creating the new service area layer.
    result_object = arcpy.na.MakeServiceAreaLayer(network, layer_name,
                                    impedance, "TRAVEL_FROM", "1 2 3",
                                    "DETAILED_POLYS", "NO_MERGE", "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)))
MakeServiceAreaLayer example 4 (workflow)

This example shows how to create service areas around facilities for multiple times of the day, as well as how to port fields from the input features to the output features and append output polygons to an existing feature class.

# Name: MakeServiceAreaLayer_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:
    #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")
    impedance = "TravelTime"
    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.MakeServiceAreaLayer(network, layer_name,
                                                impedance, "TRAVEL_FROM", "3",
                                                "DETAILED_POLYS", "NO_MERGE",
                                                hierarchy = "NO_HIERARCHY")

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

    # 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 = layer_object.listLayers(facilities_layer_name)[0]
    polygons_sublayer = layer_object.listLayers(polygons_layer_name)[0]

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

Environments