Crear capa de ruta (Network Analyst)

Resumen

Crea una capa de análisis de red de ruta y establece sus propiedades de análisis. Una capa de análisis de ruta es útil para determinar la mejor ruta entre un conjunto de ubicaciones de red en función de un costo de red específico.

Uso

  • Después de crear la capa de análisis con esta herramienta, puede agregarle objetos de análisis de red usando la herramienta Agregar ubicaciones, resolver el análisis usando la herramienta Resolver y guardar los resultados en el disco usando la herramienta Guardar en archivo de capa.

  • Al utilizar esta herramienta en modelos de geoprocesamiento, si el modelo se ejecuta como herramienta, la capa de análisis de red de salida debe convertirse en parámetro de modelo; de lo contrario, la capa de salida no se agrega al contenido del mapa.

Parámetros

EtiquetaExplicaciónTipo de datos
Red de análisis de entrada

El dataset de red en el que se realizará el análisis de ruta.

Network Dataset Layer
Nombre de Capa de salida

Nombre de la capa de análisis de red de ruta que se creará.

String
Atributo de impedancia

El atributo de coste que se usará como impedancia en el análisis.

String
Reordenar las paradas para encontrar la ruta óptima
(Opcional)
  • Activada: se reordenarán las paradas para encontrar la ruta óptima. Esta opción cambia el análisis de ruta de un problema de ruta más corta a un problema del vendedor viajero (TSP).
  • Desactivada: se visitarán las paradas en el orden de entrada. Esta es la opción predeterminada.
Boolean
Preservar el orden de paradas
(Opcional)

Especifica el orden de las paradas cuando se activa el parámetro Reordenar las paradas para encontrar la ruta óptima.

  • PRESERVE_BOTHSe mantendrán la primera y la última parada por orden de entrada como la primera y la última parada de la ruta.
  • PRESERVE_FIRSTSe mantendrá la primera parada por orden de entrada como la primera parada de la ruta, pero la última parada se puede reordenar.
  • PRESERVE_LASTSe mantendrá la última parada por orden de entrada como la última parada de la ruta, pero la primera parada se puede reordenar.
  • PRESERVE_NONELa primera y la última paradas no se conservarán y se podrán reordenar.
String
Utilizar ventanas de tiempo
(Opcional)

Especifica si se utilizarán ventanas de tiempo en las paradas.

  • Activada: la ruta tomará en cuenta las ventanas de tiempo en las paradas. Si se llega a una parada antes de su ventana de tiempo, habrá un tiempo de espera hasta que se inicie la ventana de tiempo. Si se llega a una parada después de su ventana de tiempo, se producirá una violación de ventana de tiempo. La violación de ventana de tiempo total se equilibra al agregar la impedancia al calcular la ruta. Esta opción se habilita sólo cuando la impedancia está expresada en unidades de tiempo.
  • Desactivada: la ruta ignorará las ventanas de tiempo en las paradas. Esta es la opción predeterminada.
Boolean
Acumuladores
(Opcional)

Lista de los atributos de coste que se acumularán durante el análisis. Estos atributos de acumulación solo se utilizan como referencia; el solucionador solo utiliza los atributos de coste especificados por el parámetro Atributo de impedancia para calcular la ruta.

Para cada atributo de coste acumulado, se agrega una propiedad Total_ [Impedancia] a las rutas generadas por el solucionador.

String
Política de cambio de sentido
(Opcional)

Especifica la política de cambio de sentido que se usará en los cruces. Permitir cambios de sentido implica que el solucionador puede dar la vuelta en un cruce y regresar por la misma calle. Debido a que los cruces representan intersecciones de calles y callejones sin salida, distintos vehículos pueden dar la vuelta en algunos cruces, pero no en otros; depende de si el cruce representa una intersección o un callejón sin salida. Para dar cabida a esta situación, el parámetro de la política de cambios de sentido se especifica implícitamente por la cantidad de ejes que se conectan en el cruce, lo que se conoce como valencia de cruce. Los valores aceptables para este parámetro se enumeran a continuación; cada uno seguido de una descripción de su significado en términos de valencia de cruce.

  • ALLOW_UTURNSSe permiten los cambios de sentido en los cruces con cualquier cantidad de bordes adyacentes. Este es el valor predeterminado.
  • NO_UTURNSLos cambios de sentido están prohibidos en todos los cruces, independientemente de la valencia de cruce. No obstante, los cambios de sentido siguen estando permitidos en las ubicaciones de red, aunque se elija esta configuración; pero también puede establecer la propiedad CurbApproach de cada ubicación de red individual para prohibir los cambios de sentido.
  • ALLOW_DEAD_ENDS_ONLYLos cambios de sentido están prohibidos en todos los cruces, excepto los que tienen solo un borde adyacente (una calle sin salida).
  • ALLOW_DEAD_ENDS_AND_INTERSECTIONS_ONLYLos cambios de sentido están prohibidos en los cruces donde se encuentran dos bordes adyacentes, pero están permitidos en las intersecciones (cruces con tres o más bordes adyacentes) o calles sin salida (cruces con exactamente un borde adyacente). A menudo, las redes tienen cruces extraños en medio de segmentos de carretera. Esta opción evita que los vehículos hagan cambios de sentido en estas ubicaciones.

Si necesita una política de cambios de sentido definida de forma más precisa, plantéese agregar un evaluador de retraso de giro global a un atributo de coste de red, o bien ajuste su configuración si existe, y preste especial atención a la configuración de los giros inversos. También puede definir la propiedad CurbApproach de sus ubicaciones de red.

String
Restricciones
(Opcional)

Lista de atributos de restricción que se aplicarán durante el análisis.

String
Utilizar jerarquía en el análisis
(Opcional)
  • Activado: el atributo de jerarquía se usará para el análisis. Utilizar una jerarquía hace que el solucionador prefiera bordes de orden superior en lugar de bordes de orden inferior. Las soluciones jerárquicas son más rápidas y se pueden utilizar para simular la preferencia de un conductor que opta por viajar por autopistas en lugar de por carreteras locales cuando sea posible, aunque signifique un viaje más largo. Esta opción está activa solo si el dataset de red de entrada tiene atributos de jerarquía.
  • Desactivado: el atributo de jerarquía no se usará para el análisis. Si no se utiliza la jerarquía, el resultado es una ruta exacta para el dataset de red.

El parámetro está inactivo si no se define ningún atributo de jerarquía en el dataset de red utilizado para realizar el análisis.

Boolean
Configuración de clasificación de jerarquía
(Opcional)

Heredado:

Antes de la versión 10, este parámetro le permitía cambiar los rangos de jerarquía para el análisis de los rangos de jerarquía predeterminados establecidos en el dataset de red. En la versión 10, este parámetro ya no es compatible. Para cambiar los rangos de jerarquía del análisis, actualice los rangos de jerarquía predeterminados en el dataset de red.

Network Analyst Hierarchy Settings
Forma de ruta de salida
(Opcional)

Especifica el tipo de forma que se utilizará para las entidades de ruta que genere el análisis.

  • TRUE_LINES_WITH_MEASURESLas rutas de salida tendrán la misma forma que las fuentes de red subyacentes. La salida incluye mediciones de ruta para la referenciación lineal. Las mediciones aumentan desde la primera parada y registran la impedancia acumulada para llegar a una posición determinada.
  • TRUE_LINES_WITHOUT_MEASURESLas rutas de salida tendrán la misma forma que las fuentes de red subyacentes.
  • STRAIGHT_LINESLa forma de la ruta de salida será una línea recta simple entre las paradas.
  • NO_LINESNo se generará ninguna forma para las rutas de salida.

Independientemente del tipo de forma de salida que especificado, la mejor ruta siempre se determina por la impedancia de la red y no por la distancia euclidiana. Esto significa que solo las formas de la ruta son diferentes, no los elementos transitables subyacentes de la red.

String
Hora de inicio
(Opcional)

La fecha y hora de inicio para la ruta. La hora de inicio de una ruta se utiliza típicamente para encontrar rutas en función del atributo de impedancia que varía según el momento del día. Por ejemplo, se puede utilizar la hora de inicio de las 7:00 a.m. para encontrar una ruta en la que se tenga en cuenta el tráfico en hora punta. El valor predeterminado de este parámetro es 8:00 a.m. Una fecha y hora se puede especificar como 21/10/2005 10:30 a.m. Si la ruta abarca varios días, y solamente se especifica la hora de inicio, se utilizará la fecha actual.

Configure el análisis para utilizar una de las fechas especiales siguientes para modelar un día de la semana o la fecha actual en lugar de una fecha estática específica:

  • Hoy, 30/12/1899
  • Domingo, 31/12/1899
  • Lunes, 1/1/1900
  • Martes, 2/1/1900
  • Miércoles, 3/1/1900
  • Jueves, 4/1/1900
  • Viernes, 5/1/1900
  • Sábado, 6/1/1900

Por ejemplo, para especificar que el viaje debería empezar a las 5:00 p.m. el martes, especifique el valor de parámetro como 2/1/1900 5:00 PM.

Después de la resolución, se completan las horas de inicio y fin de la ruta en las rutas de salida. Estas horas de inicio y fin también se usan cuando se generan indicaciones.

Más información sobre cómo se utilizan e interpretan las fechas y horas en un análisis de red

Date

Salida derivada

EtiquetaExplicaciónTipo de datos
Capa de Network Analyst

La capa de análisis de red recién creada.

Capa de Network Analyst

arcpy.management.MakeRouteLayer(in_network_dataset, out_network_analysis_layer, impedance_attribute, {find_best_order}, {ordering_type}, {time_windows}, {accumulate_attribute_name}, {UTurn_policy}, {restriction_attribute_name}, {hierarchy}, {hierarchy_settings}, {output_path_shape}, {start_date_time})
NombreExplicaciónTipo de datos
in_network_dataset

El dataset de red en el que se realizará el análisis de ruta.

Network Dataset Layer
out_network_analysis_layer

Nombre de la capa de análisis de red de ruta que se creará.

String
impedance_attribute

El atributo de coste que se usará como impedancia en el análisis.

String
find_best_order
(Opcional)
  • FIND_BEST_ORDERSe reordenarán las paradas para encontrar la ruta óptima. Esta opción cambia el análisis de ruta de un problema de ruta más corta a un problema del vendedor viajero (TSP).
  • USE_INPUT_ORDERSe visitarán las paradas en el orden de entrada. Esta es la opción predeterminada.
Boolean
ordering_type
(Opcional)

Especifica el orden de las paradas cuando se usa FIND_BEST_ORDER.

  • PRESERVE_BOTHSe mantendrán la primera y la última parada por orden de entrada como la primera y la última parada de la ruta.
  • PRESERVE_FIRSTSe mantendrá la primera parada por orden de entrada como la primera parada de la ruta, pero la última parada se puede reordenar.
  • PRESERVE_LASTSe mantendrá la última parada por orden de entrada como la última parada de la ruta, pero la primera parada se puede reordenar.
  • PRESERVE_NONELa primera y la última paradas no se conservarán y se podrán reordenar.
String
time_windows
(Opcional)

Especifica si se utilizarán ventanas de tiempo en las paradas.

  • USE_TIMEWINDOWSLa ruta tomará en cuenta las ventanas de tiempo en las paradas. Si se llega a una parada antes de su ventana de tiempo, habrá un tiempo de espera hasta que se inicie la ventana de tiempo. Si se llega a una parada después de su ventana de tiempo, se producirá una violación de ventana de tiempo. La violación de la ventana de tiempo total se equilibra con la impedancia mínima al calcular la ruta. Esta opción es válida sólo cuando la impedancia está expresada en unidades de tiempo.
  • NO_TIMEWINDOWSLa ruta ignorará las ventanas de tiempo en las paradas. Esta es la opción predeterminada.
Boolean
accumulate_attribute_name
[accumulate_attribute_name,...]
(Opcional)

Lista de los atributos de coste que se acumularán durante el análisis. Estos atributos de acumulación solo se utilizan como referencia; el solucionador solo utiliza los atributos de coste especificados por el parámetro Atributo de impedancia para calcular la ruta.

Para cada atributo de coste acumulado, se agrega una propiedad Total_ [Impedancia] a las rutas generadas por el solucionador.

String
UTurn_policy
(Opcional)

Especifica la política de cambio de sentido que se usará en los cruces. Permitir cambios de sentido implica que el solucionador puede dar la vuelta en un cruce y regresar por la misma calle. Debido a que los cruces representan intersecciones de calles y callejones sin salida, distintos vehículos pueden dar la vuelta en algunos cruces, pero no en otros; depende de si el cruce representa una intersección o un callejón sin salida. Para dar cabida a esta situación, el parámetro de la política de cambios de sentido se especifica implícitamente por la cantidad de ejes que se conectan en el cruce, lo que se conoce como valencia de cruce. Los valores aceptables para este parámetro se enumeran a continuación; cada uno seguido de una descripción de su significado en términos de valencia de cruce.

  • ALLOW_UTURNSSe permiten los cambios de sentido en los cruces con cualquier cantidad de bordes adyacentes. Este es el valor predeterminado.
  • NO_UTURNSLos cambios de sentido están prohibidos en todos los cruces, independientemente de la valencia de cruce. No obstante, los cambios de sentido siguen estando permitidos en las ubicaciones de red, aunque se elija esta configuración; pero también puede establecer la propiedad CurbApproach de cada ubicación de red individual para prohibir los cambios de sentido.
  • ALLOW_DEAD_ENDS_ONLYLos cambios de sentido están prohibidos en todos los cruces, excepto los que tienen solo un borde adyacente (una calle sin salida).
  • ALLOW_DEAD_ENDS_AND_INTERSECTIONS_ONLYLos cambios de sentido están prohibidos en los cruces donde se encuentran dos bordes adyacentes, pero están permitidos en las intersecciones (cruces con tres o más bordes adyacentes) o calles sin salida (cruces con exactamente un borde adyacente). A menudo, las redes tienen cruces extraños en medio de segmentos de carretera. Esta opción evita que los vehículos hagan cambios de sentido en estas ubicaciones.

Si necesita una política de cambios de sentido definida de forma más precisa, plantéese agregar un evaluador de retraso de giro global a un atributo de coste de red, o bien ajuste su configuración si existe, y preste especial atención a la configuración de los giros inversos. También puede definir la propiedad CurbApproach de sus ubicaciones de red.

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

Lista de atributos de restricción que se aplicarán durante el análisis.

String
hierarchy
(Opcional)
  • USE_HIERARCHYEl atributo de jerarquía se usará para el análisis. Utilizar una jerarquía hace que el solucionador prefiera bordes de orden superior en lugar de bordes de orden inferior. Las soluciones jerárquicas son más rápidas y se pueden utilizar para simular la preferencia de un conductor que opta por viajar por autopistas en lugar de por carreteras locales cuando sea posible, aunque signifique un viaje más largo. Esta opción es válida solo si el dataset de red de entrada tiene atributos de jerarquía.
  • NO_HIERARCHYEl atributo de jerarquía no se usará para el análisis. Si no se utiliza la jerarquía, el resultado es una ruta exacta para el dataset de red.

El parámetro no se utiliza si no se definen atributos de jerarquía en el dataset de red utilizado para realizar el análisis.

Boolean
hierarchy_settings
(Opcional)

Heredado:

Antes de la versión 10, este parámetro le permitía cambiar los rangos de jerarquía para el análisis de los rangos de jerarquía predeterminados establecidos en el dataset de red. En la versión 10, este parámetro ya no es compatible y se debe especificar como una cadena de caracteres vacía. Para cambiar los rangos de jerarquía del análisis, actualice los rangos de jerarquía predeterminados en el dataset de red.

Network Analyst Hierarchy Settings
output_path_shape
(Opcional)

Especifica el tipo de forma que se utilizará para las entidades de ruta que genere el análisis.

  • TRUE_LINES_WITH_MEASURESLas rutas de salida tendrán la misma forma que las fuentes de red subyacentes. La salida incluye mediciones de ruta para la referenciación lineal. Las mediciones aumentan desde la primera parada y registran la impedancia acumulada para llegar a una posición determinada.
  • TRUE_LINES_WITHOUT_MEASURESLas rutas de salida tendrán la misma forma que las fuentes de red subyacentes.
  • STRAIGHT_LINESLa forma de la ruta de salida será una línea recta simple entre las paradas.
  • NO_LINESNo se generará ninguna forma para las rutas de salida.

Independientemente del tipo de forma de salida que especificado, la mejor ruta siempre se determina por la impedancia de la red y no por la distancia euclidiana. Esto significa que solo las formas de la ruta son diferentes, no los elementos transitables subyacentes de la red.

String
start_date_time
(Opcional)

La fecha y hora de inicio para la ruta. La hora de inicio de una ruta se utiliza típicamente para encontrar rutas en función del atributo de impedancia que varía según el momento del día. Por ejemplo, se puede utilizar la hora de inicio de las 7:00 a.m. para encontrar una ruta en la que se tenga en cuenta el tráfico en hora punta. El valor predeterminado de este parámetro es 8:00 a.m. Una fecha y hora se puede especificar como 21/10/2005 10:30 a.m. Si la ruta abarca varios días, y solamente se especifica la hora de inicio, se utilizará la fecha actual.

Configure el análisis para utilizar una de las fechas especiales siguientes para modelar un día de la semana o la fecha actual en lugar de una fecha estática específica:

  • Hoy, 30/12/1899
  • Domingo, 31/12/1899
  • Lunes, 1/1/1900
  • Martes, 2/1/1900
  • Miércoles, 3/1/1900
  • Jueves, 4/1/1900
  • Viernes, 5/1/1900
  • Sábado, 6/1/1900

Por ejemplo, para especificar que el viaje debería empezar a las 5:00 p.m. el martes, especifique el valor de parámetro como 2/1/1900 5:00 PM.

Después de la resolución, se completan las horas de inicio y fin de la ruta en las rutas de salida. Estas horas de inicio y fin también se usan cuando se generan indicaciones.

Más información sobre cómo se utilizan e interpretan las fechas y horas en un análisis de red

Date

Salida derivada

NombreExplicaciónTipo de datos
output_layer

La capa de análisis de red recién creada.

Capa de Network Analyst

Muestra de código

Ejemplo 1 de MakeRouteLayer (ventana de Python)

Ejecute la herramienta utilizando solo los parámetros requeridos.

network = "C:/Data/SanFrancisco.gdb/Transportation/Streets_ND"
arcpy.na.MakeRouteLayer(network, "WorkRoute", "TravelTime")
Ejemplo 2 de MakeRouteLayer (ventana de Python)

Ejecutar la herramienta utilizando todos los parámetros.

network = "C:/Data/SanFrancisco.gdb/Transportation/Streets_ND"
arcpy.na.MakeRouteLayer(network, "InspectionRoute", "TravelTime",
                        "FIND_BEST_ORDER", "PRESERVE_BOTH", "USE_TIMEWINDOWS",
                        ["Meters", "TravelTime"],
                        "ALLOW_DEAD_ENDS_AND_INTERSECTIONS_ONLY", ["Oneway"],
                        "USE_HIERARCHY", "", "TRUE_LINES_WITH_MEASURES",
                        "1/1/1900 9:00 AM")
Ejemplo 3 de MakeRouteLayer (flujo de trabajo)

En la siguiente secuencia independiente de comandos de Python se muestra cómo se puede utilizar la herramienta MakeRouteLayer para encontrar la mejor ruta para visitar las ubicaciones de parada geocodificadas.

# Name: MakeRouteLayer_Workflow.py
# Description: Find a best route to visit the stop locations and save the
#              route to a layer file. The stop locations are geocoded from a
#              text file containing the addresses.
# 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 = "BestRoute"
    impedance = "TravelTime"
    address_locator = os.path.join(input_gdb, "SanFranciscoLocator")
    address_table = "C:/Data/StopAddresses.csv"
    address_fields = "Street Address;City City;State State;ZIP <None>"
    out_stops = "GeocodedStops"
    output_layer_file = os.path.join(output_dir, layer_name + ".lyrx")

    #Create a new Route layer. For this scenario, the default values for all the
    #remaining parameters statisfy the analysis requirements
    result_object = arcpy.na.MakeRouteLayer(network, layer_name, impedance)

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

    #Get the names of all the sublayers within the route layer.
    sublayer_names = arcpy.na.GetNAClassNames(layer_object)
    #Stores the layer names that we will use later
    stops_layer_name = sublayer_names["Stops"]

    #Geocode the stop locations from a csv file containing the addresses.
    #The Geocode Addresses tool can use a text or csv file as input table
    #as long as the first line in the file contains the field names.
    arcpy.geocoding.GeocodeAddresses(address_table, address_locator,
                                     address_fields, out_stops)

    #Load the geocoded address locations as stops mapping the address field from
    #geocoded stop features as Name property using field mappings.
    field_mappings = arcpy.na.NAClassFieldMappings(layer_object,
                                                            stops_layer_name)
    field_mappings["Name"].mappedFieldName = "Address"
    arcpy.na.AddLocations(layer_object, stops_layer_name, out_stops,
                            field_mappings, "",
                            exclude_restricted_elements="EXCLUDE")

    #Solve the route layer, ignoring any invalid locations such as those that
    #cannot be geocoded
    arcpy.na.Solve(layer_object, "SKIP")

    #Save the solved route 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))
Ejemplo 4 de MakeRouteLayer (flujo de trabajo)

Este ejemplo crea múltiples rutas en una sola solución, la cual a menudo se usa para calcular distancias o tiempos de conducción entre pares origen-destino.

# Name: MakeRouteLayer_MultiRouteWorkflow.py
# Description: Calculate the home-work commutes for a set of people and save
#              the output to a feature class
# 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 local variables
    input_gdb = "C:/data/SanFrancisco.gdb"
    network = os.path.join(input_gdb, "Transportation", "Streets_ND")
    stops_home = os.path.join(input_gdb, "Analysis", "Commuters_Home")
    stops_work = os.path.join(input_gdb, "Analysis", "Commuters_Work")
    layer_name = "Commuters"
    out_routes_featureclass = "Commuter_Routes"
    impedance = "TravelTime"

    #Set the time of day for the analysis to 8AM on a generic Monday.
    start_time = datetime.datetime(1900, 1, 1, 8, 0, 0)

    #Create a new Route layer.  Optimize on TravelTime, but compute the
    #distance traveled by accumulating the Meters attribute.
    result_object = arcpy.na.MakeRouteLayer(network, layer_name, impedance,
                                         accumulate_attribute_name=["Meters"],
                                         hierarchy="NO_HIERARCHY",
                                         start_date_time=start_time)

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

    #Get the names of all the sublayers within the route layer.
    sublayer_names = arcpy.na.GetNAClassNames(layer_object)
    #Stores the layer names that we will use later
    stops_layer_name = sublayer_names["Stops"]
    routes_layer_name = sublayer_names["Routes"]

    #Before loading the commuters' home and work locations as route stops, set
    #up field mapping.  Map the "Commuter_Name" field from the input data to
    #the RouteName property in the Stops sublayer, which ensures that each
    #unique Commuter_Name will be placed in a separate route.  Matching
    #Commuter_Names from stops_home and stops_work will end up in the same
    #route.
    field_mappings = arcpy.na.NAClassFieldMappings(layer_object, stops_layer_name)
    field_mappings["RouteName"].mappedFieldName = "Commuter_Name"

    #Add the commuters' home and work locations as Stops. The same field mapping
    #works for both input feature classes because they both have a field called
    #"Commuter_Name"
    arcpy.na.AddLocations(layer_object, stops_layer_name, stops_home,
                        field_mappings, "",
                        exclude_restricted_elements = "EXCLUDE")
    arcpy.na.AddLocations(layer_object, stops_layer_name, stops_work,
                        field_mappings, "", append="APPEND",
                        exclude_restricted_elements = "EXCLUDE")

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

    # Get the output Routes sublayer and save it to a feature class
    routes_sublayer = layer_object.listLayers(routes_layer_name)[0]
    arcpy.management.CopyFeatures(routes_sublayer, out_routes_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))