Disponible con una licencia de Network Analyst.
Puede utilizar el módulo arcpy.nax Python para automatizar los flujos de trabajo de análisis de red. Después de escribir un script Python con arcpy.nax, puede convertir un script en una herramienta de script para que se pueda ejecutar como cualquier otra herramienta de geoprocesamiento. En este tutorial, aprenderá cómo codificar un flujo de trabajo de análisis de red simple y a configurar una herramienta de script para ejecutarla.
Nota:
Aunque en este tutorial aprenderá cómo crear una herramienta de script en una caja de herramientas de .atbx, también puede crear una herramienta de geoprocesamiento personalizada con Python y el módulo arcpy.nax con una caja de herramientas de Python (.pyt). Aprenda las diferencias entre una herramienta de script y una caja de herramientas de Python (.pyt). Muchas de las lecciones de este tutorial se aplican a ambos tipos de herramientas.
La herramienta de script que creará en este tutorial ejecutará un análisis de área de servicio y escribirá los polígonos de área de servicio resultantes en una clase de entidad.
Nota:
Este tutorial utiliza el análisis de área de servicio como ejemplo; sin embargo, puede crear una herramienta de script para ejecutar cualquier tipo de análisis de red.
La herramienta incluirá los siguientes parámetros, que el usuario de la herramienta puede establecer:
- Instalaciones de entrada: los puntos alrededor de los cuales se calcularán los polígonos del área de servicio
- Polígonos de salida: la clase de entidad de salida que creará la herramienta
- Red: el dataset de red o servicio de análisis de red utilizado para calcular las áreas de servicio
- Modo de viaje: el modo de viaje utilizado para el análisis
- Valores límite: el tiempo de viaje o el límite de distancia del área de servicio
- Unidades de valor límite: las unidades de tiempo o distancia en las que se debe interpretar el valor del parámetro Valores límite
- Hora del día: fecha y hora del día que se utilizan para el análisis
Recopilar datos de prueba
El objetivo de este tutorial es crear una herramienta de script que se pueda utilizar con cualquier dato de entrada. No se requieren datos específicos, pero debe tener lo siguiente para probar la herramienta de script:
- Un dataset de red o acceso a un servicio de análisis de red
- Una clase de entidad de punto con algunos puntos de prueba en la misma área geográfica que la red
Si no tiene sus propios datos, puede descargar y usar los datos del tutorial que se proporcionan.
Nota:
Este tutorial se puede completar utilizando como fuente de datos de red, ya sea el dataset de red del tutorial designado, ArcGIS Online o un servicio de asignación de ruta de ArcGIS Enterprise publicado con un dataset de red que cubre la geografía de los datos de entrada del análisis. Si utiliza ArcGIS Online, consumirá créditos. Más información sobre el análisis de red con un servicio.Sugerencia:
Los datos del tutorial proporcionados incluyen una herramienta de script completada creada siguiendo los pasos de este tutorial. Puede encontrarla en la carpeta Tutorial\ScriptTool de los datos extraídos del tutorial.
- Vaya a la página de descarga de datos.
- Haga clic en el botón Descargar y guarde localmente el archivo.
- Descomprima el archivo descargado.
Crear la herramienta
Primero, creará la herramienta en una nueva caja de herramientas y definirá sus parámetros de entrada y salida.
Cree la caja de herramientas
Cree una caja de herramientas para almacenar la herramienta de script.
- Abra ArcGIS Pro y cree un nuevo proyecto con un mapa.
- En el panel Catálogo, que se encuentra en el lado derecho de la aplicación de forma predeterminada, haga clic con el botón derecho en Carpetas y elija Agregar conexión a carpetas .
Se abrirá el cuadro de diálogo Agregar conexión de carpeta.
- Conéctese a la carpeta que prefiera.
Creará la caja de herramientas y almacenará el archivo Python .py de la herramienta de script en esta carpeta.
- Haga clic con el botón derecho en la conexión a carpetas y haga clic en Nueva > Caja de herramientas (.atbx).
Se crea un archivo de caja de herramientas con la extensión .atbx. El nombre de la caja de herramientas se pone en modo de edición.
- Actualice el nombre de la caja de herramientas a TutorialHerramientaScript.atbx.
- Haga clic con el botón derecho en la caja de herramientas y haga clic en Propiedades.
Aparece el cuadro de diálogo Propiedades de caja de herramientas.
- En el cuadro Etiqueta, actualice la etiqueta de la caja de herramientas a Tutorial de la herramienta de script.
- En el cuadro Alias, actualice el alias de la caja de herramientas a TutorialHerramientaScript.
El alias de la caja de herramientas se utiliza cuando se invoca una herramienta desde un proceso Python.
- Haga clic en Aceptar para cerrar el cuadro de diálogo Propiedades de la caja de herramientas.
Crear la herramienta de script en la caja de herramientas
A continuación, cree la herramienta de script en la caja de herramientas y actualice sus propiedades básicas.
- Haga clic con el botón derecho en la caja de herramientas que creó en la sección anterior y haga clic en Nuevo > Script.
Aparece el cuadro de diálogo Nueva secuencia de comandos.
- En la lista de pestañas laterales, haga clic en la pestaña General si aún no está seleccionada.
- En el cuadro de texto Nombre, escriba TutorialHerramientaScriptÁreaServicio.
El nombre se utiliza cuando se invoca la herramienta desde un proceso Python. Utilice solamente caracteres alfanuméricos para el nombre. No puede tener espacios ni caracteres especiales.
- En el cuadro de texto Etiqueta, escriba Tutorial de la herramienta de script del área de servicio.
La etiqueta es el nombre de visualización para la herramienta de script (como aparece en el panel Geoprocesamiento) y puede contener espacios.
- En el cuadro de texto Descripción, escriba una descripción para la herramienta de script si lo desea.
Definir los parámetros de la herramienta
El siguiente paso es definir los parámetros de la herramienta. Los parámetros aparecen en el cuadro de diálogo de la herramienta y permiten al usuario elegir datos de entrada, ubicaciones de salida y otras opciones. Cuando se ejecuta la herramienta, los valores de parámetro se envían al script Python de la herramienta. El script recupera los valores del parámetro y los utiliza en el análisis.
Creará siete parámetros, tal y como se describe al principio de este tutorial.
Más información sobre cómo configurar los parámetros de la herramienta de script
- En la lista de pestañas laterales, haga clic en la pestaña Parámetros.
- Para crear el parámetro Instalaciones de entrada, siga los siguientes pasos:
El parámetro Instalaciones de entrada permitirá al usuario elegir una clase de entidad o una capa de puntos alrededor de la cual se calcularán los polígonos del Área de servicio.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Instalaciones de entrada y pulse Intro.
Se crea el parámetro Instalaciones de entrada. La celda de la columna Nombre se actualiza automáticamente a Input_Facilities.
- Haga clic en el botón Opciones en la celda Tipo de datos para abrir el cuadro de diálogo Tipo de datos del parámetro.
- En el cuadro de diálogo Tipo de datos del parámetro, en el menú desplegable, seleccione Capa de entidades y haga clic en Aceptar para cerrar el cuadro de diálogo.
Un parámetro de tipo Capa de entidades permite al usuario de la herramienta seleccionar una capa del mapa o utilizar una ruta de catálogo a una clase de entidad como entrada para este parámetro.
- Haga clic en la celda de la columna Filtro. Desplácese hacia la derecha para buscar esta columna en caso necesario.
- En el menú desplegable, seleccione la opción Tipo de entidad.
Aparece el cuadro de diálogo Filtro del tipo de entidad.
- En el cuadro de diálogo Filtro del tipo de entidad, active la opción Punto y haga clic en Aceptar para cerrar el cuadro de diálogo.
Las instalaciones del Área de servicio deben ser puntos. Después de definir este filtro de tipo de entidad, el parámetro Instalaciones de entrada solo permitirá como entrada clases de entidad de puntos y capas. Por ejemplo, si el usuario selecciona una clase de entidad poligonal o de línea, el parámetro de la herramienta mostrará automáticamente un error.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Instalaciones de entrada y pulse Intro.
- Para crear el parámetro Polígonos de salida, siga los siguientes pasos:
El parámetro Polígonos de salida permitirá al usuario elegir la ubicación en la cual la herramienta guardará la clase de entidad poligonal del Área de servicio creada durante la ejecución de la herramienta.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Polígonos de salida y pulse Intro.
Se crea el parámetro Polígonos de salida. La celda de la columna Nombre se actualiza automáticamente a Output_Polygons.
- Al igual que hizo al definir el tipo de datos para el parámetro Instalaciones de entrada, haga clic en la celda Tipo de datos para abrir el cuadro de diálogo Tipo de datos del parámetro. Esta vez, establezca el tipo de datos como Clase de entidad.
Un parámetro de salida de tipo Clase de entidad le permite elegir la ruta del catálogo para una nueva clase de entidad.
- Haga clic en la celda en la columna Dirección y, en el menú desplegable, elija la opción Salida.
Dado que este parámetro se configura como un parámetro de salida, el usuario puede elegir una ruta de archivo de salida y un nombre para una clase de entidad que todavía no existe.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Polígonos de salida y pulse Intro.
- Para crear el parámetro Red, siga estos pasos:
El parámetro Red permitirá al usuario elegir el dataset de red o el servicio de análisis de red para calcular las Áreas de servicio.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Red y pulse Intro.
Se crea el parámetro Red. La celda de la columna Nombre se actualiza automáticamente a Red.
- En la columna Tipo de datos, defina el tipo de datos como Fuente de datos de red.
El tipo de parámetro Fuente de datos de red permite al usuario elegir una capa de dataset de red, una ruta de catálogo de dataset de red o la dirección URL de un servicio de análisis de red. Para un parámetro de tipo Capa de dataset de red, el usuario puede elegir una capa de dataset de red o una ruta de catálogo de dataset de red únicamente, sin la opción de utilizar una dirección URL de servicio. El tipo de parámetro Dataset de red solo permite una ruta de catálogo de dataset de red y se utiliza más comúnmente como un tipo de parámetro de salida que para las entradas.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Red y pulse Intro.
- Para crear el parámetro Modo de viaje, siga estos pasos:
El parámetro Modo de viaje permitirá al usuario elegir el modo de viaje utilizado para el análisis. Configurará este parámetro con una dependencia para que la lista de opciones se actualice automáticamente para reflejar los modos de viaje disponibles con el valor del parámetro Red seleccionado.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Modo de viaje y pulse Intro.
Se crea el parámetro Modo de viaje. La celda de la columna Nombre se actualiza automáticamente a Modo de viaje.
- En la columna Tipo de datos, defina el tipo de datos como Modo de viaje de red.
- Haga clic en la celda de la columna Dependencia. Desplácese hacia la derecha para buscar esta columna en caso necesario.
- En el menú desplegable de la celda de la columna Dependencia, seleccione la opción Red.
El parámetro Modo de viaje está ahora vinculado al parámetro Red. El cuadro de diálogo de la herramienta actualiza automáticamente la lista de opciones del parámetro Modo de viaje según el valor establecido en el parámetro Red.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Modo de viaje y pulse Intro.
- Para crear el parámetro Valores límite, siga estos pasos:
El parámetro Valores límite permitirá al usuario elegir uno o más valores numéricos que designan los límites de distancia o tiempo de viaje del Área de servicio. Los polígonos del Área de servicio mostrarán el área a la que se puede llegar desde las instalaciones de entrada dentro de estos límites. Si se introducen varios valores, se creará un polígono de Área de servicio para cada instalación y cada valor límite. Por ejemplo, la salida podría incluir polígonos que representan un tiempo de recorrido de 10 minutos y 15 minutos alrededor de cada instalación.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Valores límite y pulse Intro.
Se crea el parámetro Valores límite. La celda de la columna Nombre se actualiza automáticamente a Valores límite.
- Haga clic en el botón Opciones en la celda Tipo de datos para abrir el cuadro de diálogo Tipo de datos del parámetro.
- En el cuadro de diálogo Tipo de datos del parámetro, en el menú desplegable, seleccione Doble.
- En el cuadro de diálogo Tipo de datos del parámetro, active la opción Valores múltiples.
La opción Valores múltiples permite al usuario introducir más de un valor para el parámetro.
- Haga clic en Aceptar para cerrar el cuadro de diálogo Tipo de datos del parámetro.
Los valores límite del área de servicio deben ser superiores a cero. No tiene sentido crear un polígono que represente un tiempo de conducción de cero minutos o incluso negativo. Es posible configurar un parámetro numérico con un filtro de rango seleccionando la opción Rango en la columna Filtro. Se mostrará automáticamente un mensaje de error si el usuario selecciona un número fuera de este rango. Sin embargo, los filtros de rango solo admiten rangos numéricos inclusivos y usted quiere excluir el límite inferior de 0 y seguir permitiendo valores decimales, tales como 0,5. Por consiguiente, en lugar de utilizar el filtro de rango proporcionado, utilizará la validación de la herramienta para crear su propio filtro de rango utilizando el código Python. Este código se describe más adelante en este tutorial.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Valores límite y pulse Intro.
- Para crear el parámetro Valores límite, siga estos pasos:
El parámetro Unidades de valores límite permitirá al usuario especificar la unidad de medida en la que se va a interpretar el valor del parámetro Valores límite.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Unidades de valores límite y pulse Intro.
Se crea el parámetro Unidades de valores límite. La celda de la columna Nombre se actualiza automáticamente a Cutoff_Units.
- En la columna Tipo de datos, confirme que el tipo de datos esté definido como Cadena de caracteres y actualícelo si es necesario.
Para configurar una lista de opciones para un parámetro, puede seleccionar la opción Lista de valores en la columna Filtro e introducir la lista de valores que desea presentar al usuario. Sin embargo, para el parámetro Unidades de valor límite, quiere que la lista de opciones sea dinámica dependiendo de si el valor del parámetro Modo de viaje seleccionado por el usuario tiene unidades de tiempo o distancia. En la siguiente sección, utilizará la validación de la herramienta para crear una lista de opciones dinámica con el código Python.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Unidades de valores límite y pulse Intro.
- Para crear el parámetro Hora del día, complete los siguientes pasos:
El parámetro Hora del día permitirá al usuario definir la fecha y hora del día para el análisis. Esta es la fecha y hora en que los vehículos o peatones abandonan las instalaciones. Dado que la hora del día no siempre es relevante, configurará este parámetro como opcional. El usuario puede configurarlo si lo desea, o puede dejarlo en blanco.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Hora del día y pulse Intro.
Se crea el parámetro Hora del día. La celda de la columna Nombre se actualiza automáticamente a Time_Of_Day.
- En la columna Tipo de datos, defina el tipo de datos como Fecha.
- Haga clic en la celda en la columna Tipo y, en el menú desplegable, elija la opción Opcional.
Dado que este parámetro se configura como opcional, el usuario puede dejarlo en blanco sin recibir ningún error.
- Haga clic en la primera celda vacía de la columna Etiqueta, escriba Hora del día y pulse Intro.
- Compruebe la configuración del parámetro. Debería parecerse a la imagen siguiente:
- Haga clic en Aceptar en el cuadro de diálogo Nueva secuencia de comandos para confirmar los cambios y cerrar el cuadro de diálogo.
Verificar los parámetros de la herramienta
Ahora que ya ha configurado los parámetros de la herramienta, debe verificar que funcionen según deseado. Todavía hay trabajo por hacer para configurar la validación personalizada para algunos parámetros y todavía no puede ejecutar la herramienta ya que aún no ha escrito el código de ejecución de la herramienta; sin embargo, tómese un momento para verificar la configuración del parámetro hasta ahora.
- En el panel Catálogo, busque la nueva herramienta de script Tutorial de la herramienta de script del área de servicio en la caja de herramientas.
- Haga doble clic en la herramienta para abrirla.
La herramienta Tutorial de la herramienta de script del Área de servicio se abre en el panel Geoprocesamiento. Los siete parámetros que creó en la sección anterior son visibles.
- Examine cada parámetro y confirme que el comportamiento es el esperado.
- Examine el parámetro Instalaciones de entrada.
Solo debería poder seleccionar capas de puntos y clases de entidad con este parámetro. Las clases de entidad poligonal y de línea no aparecen en la lista de opciones y, si introduce una manualmente, verá un mensaje de error que indica que la entrada tiene un tipo de geometría no válido.
Sugerencia:
Si su mapa no tiene capas de entidades, no verá ninguna lista de opciones. Si desea ver el comportamiento del parámetro, agregue algunas capas a su mapa. - Examine el parámetro Polígonos de salida.
Debería poder elegir la ubicación de salida. Si elige una clase de entidad existente, el parámetro debería mostrar una advertencia indicando que la salida ya existe.
- Examine los parámetros Red y Modo de viaje.
El parámetro Modo de viaje debería estar vacío inicialmente y no debe tener ninguna lista de opciones. El parámetro Red debería permitirle seleccionar una capa de dataset de red, una ruta de catálogo de dataset de red o una dirección URL de un servicio de análisis de red.
- Elija un valor para el parámetro Red.
La lista de opciones del parámetro Modo de viaje se actualiza automáticamente para incluir la lista de modos de viaje disponibles asociados con el valor Red.
- Examine el parámetro Valores límite.
Puede introducir más de un valor numérico.
Actualmente, puede introducir números negativos o 0 y el parámetro no mostrará ningún error. Más adelante, usará la validación de la herramienta para actualizar este comportamiento.
- Examine el parámetro Unidades de valores límite.
Actualmente, el parámetro no muestra una lista de opciones. Más adelante, usará la validación de la herramienta para proporcionar una lista de opciones dependiendo del valor Modo de viaje.
- Examine el parámetro Hora del día.
A diferencia del resto de parámetros, este no muestra un asterisco rojo cuando está vacío, ya que es opcional. Puede usar la utilidad de selector de fecha y hora o introducir una fecha y hora manualmente.
- Examine el parámetro Instalaciones de entrada.
Escribir el script de Python
En esta sección, escribirá el script de Python que ejecutará la herramienta de script. La herramienta de script hará lo siguiente:
- Recuperar los parámetros de entrada.
- Realizar un check-out de la licencia de Extensión ArcGIS Network Analyst, si es necesario.
- Inicializar el análisis del Área de servicio.
- Definir la configuración del análisis del Área de servicio.
- Cargar las instalaciones de entrada.
- Resolver el análisis del Área de servicio y manejar los errores del solucionador.
- Escribir los polígonos de salida del Área de servicio en una clase de entidad.
- Cree un archivo llamado ServiceAreaTutorialScriptTool.py en la misma carpeta en la que creó anteriormente la caja de herramientas y ábralo para editarlo en el entorno de desarrollo integrado (IDE, por sus siglas en inglés) o el editor de texto que prefiera.
Puede utilizar cualquier IDE Python o editor de texto para este ejercicio.
- Lea las subsecciones siguientes para comprender los componentes del código que utilizará para la herramienta de script.
- El código completo se incluye en la parte inferior de esta sección. Copie y pegue este código en el archivo ServiceAreaTutorialScriptTool.py y guarde el archivo.
Precaución:
Compruebe que la sangría del código es correcta después de pegarla en el archivo ServiceAreaTutorialScriptTool.py.
Recuperar los parámetros de entrada
El código de la herramienta de script debe recuperar las entradas del usuario desde los parámetros de la herramienta utilizando la función GetParameter o GetParameterAsText de ArcPy. La función GetParameter devuelve el valor del parámetro en el tipo de datos definido en el parámetro y la función GetParameterAsText siempre devuelve el valor del parámetro como una cadena de caracteres.
En este fragmento de código, el script recupera los parámetros de la herramienta y los asigna a las variables. La función GetParameter se utiliza cuando desea conservar el tipo de datos del parámetro de entrada. La función GetParameterAsText se utiliza cuando se recuperan las instalaciones de entrada y la fuente de datos de red, aunque esas entradas pueden ser capas porque se pueden utilizar los nombres de cadenas de caracteres de las capas como entradas válidas para las herramientas de geoprocesamiento y las funciones de ArcPy. Los valores de índice que se utilizan aquí con GetParameter y GetParameterAsText coinciden con el orden de los parámetros que definió anteriormente.input_facilities = arcpy.GetParameterAsText(0)
output_polygons = arcpy.GetParameterAsText(1)
network = arcpy.GetParameterAsText(2)
travel_mode = arcpy.GetParameter(3)
cutoffs = arcpy.GetParameter(4)
cutoff_units = arcpy.GetParameterAsText(5)
time_of_day = arcpy.GetParameter(6)
Realizar un check-out de la licencia de Extensión ArcGIS Network Analyst
Se requiere la licencia de Extensión ArcGIS Network Analyst si el usuario de la herramienta elige un dataset de red para el parámetro Red. Si, en su lugar, el usuario elige usar un servicio de análisis de red designando una dirección URL del portal, no se requiere la licencia de la Extensión ArcGIS Network Analyst.
En este fragmento de código, el script intenta verificar la licencia de la extensión si la red de entrada no comienza con http, que se presupone que es un servicio de análisis de red. Si la extensión no está disponible, se muestra un error. El manejo de errores se explicará más adelante en este tutorial.# Check out the Network Analyst extension license if the input network
# is a local network dataset and not a service.
if not network.startswith("http"):
if arcpy.CheckExtension("network") == "Available":
arcpy.CheckOutExtension("network")
else:
# Throw an error if the license cannot be checked out.
arcpy.AddError("The Network Analyst license is unavailable.")
raise CustomError
Inicializar el análisis del Área de servicio
El primer paso de un flujo de trabajo de análisis de red con arcpy.nax es crear una instancia del objeto del análisis del solucionador utilizando la fuente de datos de red designada.
Más información sobre los pasos en un flujo de trabajo de análisis de red con arcpy.nax
En este fragmento de código, el objeto del análisis del Área de servicio se inicializa.# Instantiate the ServiceArea solver object
sa = arcpy.nax.ServiceArea(network)
Definir la configuración del análisis del Área de servicio
Para este análisis, codificará algunos ajustes del análisis del Área de servicio que no desea que el usuario cambie. Establecerá otros ajustes basándose en las opciones del usuario de los parámetros de la herramienta.
Más información sobre la configuración del análisis del Área de servicio
En este fragmento de código, algunos ajustes de análisis están codificados. El modo de viaje, la hora del día y los valores límite de impedancia predeterminados se establecen utilizando los valores recuperados de los parámetros de la herramienta.# Hard-code some non-default Service Area settings that we don't want
# the user to change
sa.geometryAtCutoff = arcpy.nax.ServiceAreaPolygonCutoffGeometry.Disks
sa.polygonBufferDistance = 150
sa.polygonBufferDistanceUnits = arcpy.nax.DistanceUnits.Feet
# Set analysis properties chosen by the user and passed in via tool
# parameters
sa.travelMode = travel_mode
sa.timeOfDay = time_of_day
sa.defaultImpedanceCutoffs = cutoffs
También tiene que establecer las unidades de valor límite, pero requiere un poco de procesamiento adicional. El parámetro de la herramienta se configurará como una cadena de caracteres y deberá convertir el nombre de unidad basado en cadena de caracteres al valor adecuado de enumeración TimeUnits o DistanceUnits.
En este fragmento de código, las unidades de tiempo o distancia se establecen dependiendo del valor pasado desde el parámetro de la herramienta con la ayuda de dos funciones para convertir un valor de cadena de caracteres al valor de enumeración apropiado. En esta herramienta de ejemplo, solo admitirá una lista limitada de unidades posibles de tiempo y distancia. El parámetro de la herramienta se analizará más adelante en este tutorial.# Do special handling of cutoff units to convert them to the correct
# arcpy.nax enum
if cutoff_units in ["Hours", "Minutes"]:
sa.timeUnits = convert_time_units_to_nax(cutoff_units)
elif cutoff_units in ["Kilometers", "Meters", "Miles", "Yards", "Feet"]:
sa.distanceUnits = convert_distance_units_to_nax(cutoff_units)
En este fragmento de código, se definen dos funciones para convertir los nombres de unidad basados en cadenas de caracteres al valor de enumeración correcto. No se incluyen todos los valores posibles de las enumeraciones TimeUnits y DistanceUnits porque, en este ejemplo, limitará las opciones de unidades que se presentan a los usuarios. Las funciones generan un error si se pasa una unidad no válida.def convert_time_units_to_nax(time_units_str):
"""Convert string-based time units to the correct arcpy.nax enum."""
if time_units_str == "Hours":
return arcpy.nax.TimeUnits.Hours
if time_units_str == "Minutes":
return arcpy.nax.TimeUnits.Minutes
arcpy.AddError(f"Invalid time units: {time_units_str}")
raise CustomError
def convert_distance_units_to_nax(dist_units_str):
"""Convert string-based distance units to the correct arcpy.nax enum."""
if dist_units_str == "Kilometers":
return arcpy.nax.DistanceUnits.Kilometers
if dist_units_str == "Meters":
return arcpy.nax.DistanceUnits.Meters
if dist_units_str == "Miles":
return arcpy.nax.DistanceUnits.Miles
if dist_units_str == "Yards":
return arcpy.nax.DistanceUnits.Yards
if dist_units_str == "Feet":
return arcpy.nax.DistanceUnits.Feet
arcpy.AddError(f"Invalid distance units: {dist_units_str}")
raise CustomError
Cargar las instalaciones de entrada
A continuación, utilice el método load para agregar las instalaciones del usuario al análisis del Área de servicio.
Más información sobre cómo establecer entradas de análisis
En este fragmento de código, las instalaciones de entrada se agregan al análisis del Área de servicio utilizando el método load. El valor de enumeración ServiceAreaInputDataType.Facilities se utiliza como parámetro del método load para indicar que las entradas se deben agregar como instalaciones.# Load the input facilities
sa.load(arcpy.nax.ServiceAreaInputDataType.Facilities, input_facilities)
Resolver el análisis del Área de servicio y manejar los errores del solucionador
Ahora que se han configurado los ajustes del Área de servicio y que se han cargado los datos de entrada, está listo para resolver el análisis y recuperar el resultado. Resolver el análisis utilizando el método de resolución produce una instancia de un objeto ServiceAreaResult, el cual incluye propiedades y métodos para trabajar con las salidas del análisis.
En este fragmento de código, el análisis del Área de servicio se resuelve utilizando el método solve. La variable result se puede utilizar para trabajar con las salidas de análisis.# Solve the analysis
result = sa.solve()
A veces, un análisis puede fallar o puede ser correcto, pero devolver mensajes de advertencia al usuario sobre posibles problemas. En su herramienta, quiere devolver los errores y advertencias del solucionador al usuario. Si la solución falla, quiere detener la ejecución de la herramienta.
En este fragmento de código, el método ServiceAreaResult del objeto solverMessages se utiliza para recuperar mensajes de advertencia utilizando el valor de enumeración MessageSeverity.Warning. Cada mensaje de advertencia recibido se agrega a los mensajes de advertencia de la herramienta usando la función AddWarning.# Print warning messages if there are any
for warning in result.solverMessages(arcpy.nax.MessageSeverity.Warning):
arcpy.AddWarning(warning[1])
En este fragmento de código, comprobará si el análisis del área de servicio se realizó correctamente con la propiedad ServiceAreaResult del objeto solveSucceeded. De lo contrario, el método solverMessages se utiliza para recuperar los mensajes de error y la función AddError los agrega a los errores de la herramienta. Además, se produce un error para detener la ejecución de la herramienta. Más adelante, se explica el manejo de errores.# Handle failed solves
if not result.solveSucceeded:
arcpy.AddError("The Service Area solve failed.")
# Print error messages and stop the tool from running further
for error in result.solverMessages(arcpy.nax.MessageSeverity.Error):
arcpy.AddError(error[1])
# Stop tool run by raising an error
raise CustomError
Escribir los polígonos de salida del Área de servicio en una clase de entidad
Finalmente, escriba la salida del análisis del área de servicio en la clase de entidad designada por el usuario utilizando el método export. Además, cuente el número de polígonos de la salida utilizando el recuento method y escriba esta información como un mensaje.
Más información sobre otras formas de acceder y trabajar con los resultados de un análisis
En este fragmento de código, el número de polígonos en la salida se escribe como un mensaje utilizando la función AddMessage y los polígonos del Área de servicio se exportan a una clase de entidad. El valor de enumeración ServiceAreaOutputDataType.Polygons se utiliza para trabajar con los polígonos de salida en lugar de con uno de los otros tipos de salidas de análisis.# Add a message with the total number of polygons that were generated
# in the analysis
num_polygons = result.count(
arcpy.nax.ServiceAreaOutputDataType.Polygons)
arcpy.AddMessage(f"Number of polygons generated: {num_polygons}.")
# Export the Service Area polygons to the output feature class
result.export(
arcpy.nax.ServiceAreaOutputDataType.Polygons, output_polygons)
Manejar los errores
Cuando se encuentra un error conocido, quiere que la herramienta deje de ejecutarse y genere un mensaje de error útil. Puede hacerlo incorporando una excepción personalizada y escribiendo el código de ejecución de la herramienta en un bloque try/except.
En este fragmento de código, se define una excepción personalizada. No hace nada, pero sirve para detener la ejecución de la herramienta cuando se encuentra un problema conocido.class CustomError(Exception):
pass
El código de ejecución de la herramienta se escribe en un bloque try/except. Si se detecta un CustomError, el código no hace nada porque el mensaje de error ya se ha agregado a los errores de la herramienta. Si se produce un error desconocido, el código recupera el trazado inverso y lo agrega como un error de herramienta para ayudar con la depuración.try:
[...]
except CustomError:
# We caught a known error and already added the message. Do nothing.
pass
except Exception:
# An unknown error occurred. Add the traceback as an error message.
arcpy.AddError(
"An unknown error occurred when generating Service Areas.")
import traceback
arcpy.AddError(traceback.format_exc())
Combinarlo todo
El siguiente fragmento de código incluye el script Python completo que contiene todos los componentes analizados anteriormente. Puede copiar y pegar este código en el archivo ServiceAreaTutorialScriptTool.py.import arcpy
class CustomError(Exception):
pass
def convert_time_units_to_nax(time_units_str):
"""Convert string-based time units to the correct arcpy.nax enum."""
if time_units_str == "Hours":
return arcpy.nax.TimeUnits.Hours
if time_units_str == "Minutes":
return arcpy.nax.TimeUnits.Minutes
arcpy.AddError(f"Invalid time units: {time_units_str}")
raise CustomError
def convert_distance_units_to_nax(dist_units_str):
"""Convert string-based distance units to the correct arcpy.nax enum."""
if dist_units_str == "Kilometers":
return arcpy.nax.DistanceUnits.Kilometers
if dist_units_str == "Meters":
return arcpy.nax.DistanceUnits.Meters
if dist_units_str == "Miles":
return arcpy.nax.DistanceUnits.Miles
if dist_units_str == "Yards":
return arcpy.nax.DistanceUnits.Yards
if dist_units_str == "Feet":
return arcpy.nax.DistanceUnits.Feet
arcpy.AddError(f"Invalid distance units: {dist_units_str}")
raise CustomError
def generate_service_areas():
"""Generate Service Area polygons."""
try:
input_facilities = arcpy.GetParameterAsText(0)
output_polygons = arcpy.GetParameterAsText(1)
network = arcpy.GetParameterAsText(2)
travel_mode = arcpy.GetParameter(3)
cutoffs = arcpy.GetParameter(4)
cutoff_units = arcpy.GetParameterAsText(5)
time_of_day = arcpy.GetParameter(6)
# Check out the Network Analyst extension license if the input network
# is a local network dataset and not a service.
if not network.startswith("http"):
if arcpy.CheckExtension("network") == "Available":
arcpy.CheckOutExtension("network")
else:
# Throw an error if the license cannot be checked out.
arcpy.AddError("The Network Analyst license is unavailable.")
raise CustomError
# Instantiate the ServiceArea solver object
sa = arcpy.nax.ServiceArea(network)
# Hard-code some non-default Service Area settings that we don't want
# the user to change
sa.geometryAtCutoff = arcpy.nax.ServiceAreaPolygonCutoffGeometry.Disks
sa.polygonBufferDistance = 150
sa.polygonBufferDistanceUnits = arcpy.nax.DistanceUnits.Feet
# Set analysis properties chosen by the user and passed in via tool
# parameters
sa.travelMode = travel_mode
sa.timeOfDay = time_of_day
sa.defaultImpedanceCutoffs = cutoffs
# Do special handling of cutoff units to convert them to the correct
# arcpy.nax enum
if cutoff_units in ["Hours", "Minutes"]:
sa.timeUnits = convert_time_units_to_nax(cutoff_units)
elif cutoff_units in ["Kilometers", "Meters", "Miles", "Yards", "Feet"]:
sa.distanceUnits = convert_distance_units_to_nax(cutoff_units)
# Load the input facilities
sa.load(arcpy.nax.ServiceAreaInputDataType.Facilities, input_facilities)
# Solve the analysis
result = sa.solve()
# Print warning messages if there are any
for warning in result.solverMessages(arcpy.nax.MessageSeverity.Warning):
arcpy.AddWarning(warning[1])
# Handle failed solves
if not result.solveSucceeded:
arcpy.AddError("The Service Area solve failed.")
# Print error messages and stop the tool from running further
for error in result.solverMessages(arcpy.nax.MessageSeverity.Error):
arcpy.AddError(error[1])
# Stop tool run by raising an error
raise CustomError
# Add a message with the total number of polygons that were generated
# in the analysis
num_polygons = result.count(
arcpy.nax.ServiceAreaOutputDataType.Polygons)
arcpy.AddMessage(f"Number of polygons generated: {num_polygons}.")
# Export the Service Area polygons to the output feature class
result.export(
arcpy.nax.ServiceAreaOutputDataType.Polygons, output_polygons)
except CustomError:
# We caught a known error and already added the message. Do nothing.
pass
except Exception:
# An unknown error occurred. Add the traceback as an error message.
arcpy.AddError(
"An unknown error occurred when generating Service Areas.")
import traceback
arcpy.AddError(traceback.format_exc())
if __name__ == "__main__":
generate_service_areas()
Configurar la herramienta de script para ejecutar el archivo de script Python
Anteriormente, creó la herramienta de script y definió sus parámetros. A continuación, escribió un script Python para hacer el análisis. Ahora, debe configurar la herramienta para ejecutar el script Python. Cuando ejecute la herramienta, esta ejecutará el código en el script Python, y el script Python recuperará las entradas que se le entregan desde los parámetros de la herramienta y completará el análisis.
- Abra el cuadro de diálogo de las propiedades de la herramienta de script haciendo clic con el botón derecho en la herramienta de script y haciendo clic en Propiedades.
Aparecerá el cuadro de diálogo Propiedades de la herramienta.
- En la lista de pestañas laterales, haga clic en la pestaña Ejecución.
- Haga clic en el botón de la Carpeta y vaya a la ubicación de su archivo de script ServiceAreaTutorialScriptTool.py.
Sugerencia:
Si el archivo ServiceAreaTutorialScriptTool.py no aparece en el cuadro de diálogo de navegación, haga clic en el botón Refrescar situado junto a la barra de direcciones en la parte superior.El código que se muestra en la pestaña Ejecución se actualiza para mostrar el contenido del archivo de script Python. Ahora la herramienta está configurada para ejecutar el script Python.
Personalizar la validación de una herramienta
La validación se refiere al proceso que comprueba y actualiza los valores de los parámetros de una herramienta antes de ejecutar dicha herramienta. La validación permite garantizar que los valores introducidos para los parámetros sean del tipo o rango de valores correctos. La validación también puede actualizar listas de opciones de parámetros o incluso ocultar o exponer parámetros en función del valor de otros parámetros.
Algunos procesos de validación se integran en ciertos tipos de parámetros y configuraciones. Por ejemplo, anteriormente configuró el parámetro Instalaciones de entrada con un filtro Tipo de entidad para aceptar únicamente clases de entidad de puntos. Cuando el usuario selecciona una entrada para este parámetro, la validación verifica que la entrada sea del tipo correcto y muestra un mensaje de error si no lo es.
A veces, sin embargo, el autor de una herramienta de script tiene que implementar una validación más sofisticada o personalizada. Se puede hacer utilizando la clase ToolValidator. Esta clase especial Python se puede actualizar con código personalizado para actualizar los parámetros y realizar comprobaciones que generen mensajes de error y advertencia cuando sea necesario.
En este tutorial, programará la clase ToolValidator en la herramienta de script para que genere un error si un valor en el parámetro Valores límite es menor o igual que 0 y para que actualice la lista de opciones del parámetro Unidades de valor límite con una lista de unidades de tiempo o distancia dependiendo del valor del parámetro Modo de viaje.
El código ToolValidator es independiente del script Python que ha escrito anteriormente en el que la herramienta se ejecuta y se edita por separado.
Nota:
También puede crear una herramienta de geoprocesamiento personalizada en una caja de herramientas Python (.pyt). En este caso, tanto el código de validación como el código de ejecución de la herramienta se incluyen en el mismo script Python.
Más información sobre lo que puede hacer con la validación de la herramienta de script
Busque la clase ToolValidator y ábrala para editarla
Cuando se crea una herramienta de script, la clase ToolValidator se crea de forma automática. Puede acceder a ella a través del cuadro de diálogo de propiedades de la herramienta de script y abrirla para editarla.
- Si fuera necesario, abra el cuadro de diálogo de las propiedades de la herramienta de script haciendo clic con el botón derecho en la herramienta de script y haciendo clic en Propiedades.
Aparecerá el cuadro de diálogo Propiedades de la herramienta.
- En la lista de pestañas laterales, haga clic en la pestaña Validación.
La clase ToolValidator de la herramienta de script es visible. Puede editar el código directamente en el cuadro de diálogo o hacer clic en el botón Abrir en Editor de script para abrir ToolValidator en un archivo separado en un IDE o un editor de texto.
Sugerencia:
Puede controlar qué IDE o editor de texto abre el archivo con la configuración del Editor de script en las Opciones de geoprocesamiento.
Generar un error si el valor del parámetro Valores límite es menor o igual que 0
El método updateMessages de la clase ToolValidator se puede utilizar para comprobar los valores de los parámetros y agregar mensajes de error o advertencia. En esta sección, modificará el método updateMessages para generar un error si un valor del parámetro Valores límite es menor o igual que 0.
- Busque el método updateMessages de la clase ToolValidator.
De forma predeterminada, el método updateMessages contiene solo una instrucción return. No realiza ninguna validación personalizada.
- Cambie el método updateMessages para utilizar el siguiente código:
Precaución:
Compruebe la sangría del código de validación después de pegarlo en la clase ToolValidator.def updateMessages(self): # Customize messages for the parameters. # This gets called after standard validation. # Raise an error if any of the cutoffs are <= 0 cutoffs_param = self.params[4] if cutoffs_param.valueAsText: for cutoff in cutoffs_param.values: if cutoff <= 0: cutoffs_param.setErrorMessage("Cutoffs must be positive.") break return
En este fragmento de código, se agrega un mensaje de error al parámetro Valores límite si cualquiera de sus valores es menor o igual que 0.
El parámetro Valores límite se recupera con la variable self.params, que es una lista de parámetros de herramienta integrados en la clase ToolValidator. El parámetro Valores límite es el quinto parámetro, de modo que se accede a él mediante el índice 4 de la lista. El valor recuperado es un objeto Parameter.
Si el parámetro está vacío, no es necesario comprobar los valores. La propiedad valueAsText del objeto Parameter es una forma rápida de determinar si el parámetro está vacío.
Dado que se trata de un parámetro multivalor, la lista de valores se recupera con la propiedad values. El código se itera sobre los valores actuales del parámetro.
Si el valor límite es menor o igual que 0, se utiliza Parameter del objeto setErrorMessage para establecer un mensaje de error. Este mensaje aparecerá en el parámetro de la interfaz de usuario de la herramienta.
Si se encuentra un valor no válido, la instrucción break detiene la iteración. No es necesario comprobar el resto de valores una vez que se ha encontrado uno no válido.
Nota:
Incluso si agrega un código de validación personalizado, la validación interna básica asociada con cada parámetro sigue aplicándose. Por ejemplo, dado que definió el parámetro Valores límite para que sea de tipo doble, la validación interna comprobará automáticamente que la entrada sea un valor numérico válido y generará un error si es necesario. Cualquier validación personalizada que agregue para su parámetro se proporciona automáticamente para ese tipo de parámetro, junto a la validación interna.
Rellene el parámetro Unidades de valor límite con una lista de unidades de distancia o de tiempo
Un modo de viaje incluye varios ajustes que controlan cómo se modela el viaje a través de una red. Determina qué variable se optimiza al encontrar la ruta más corta a través de la red. Normalmente, es una medida de tiempo o distancia, aunque los datasets de red también se pueden configurar para optimizar otro tipo de variable, como la energía o el coste monetario del viaje.
El parámetro Valores límite permite al usuario especificar valores numéricos para el límite de coste de viaje del Área de servicio. El parámetro Unidades de valores límite permite al usuario especificar la unidad de medida en la que se van a interpretar esos valores.
Para su herramienta, quiere ofrecer al usuario una lista de unidades válidas; sin embargo, si el modo de viaje seleccionado optimiza el tiempo, quiere mostrar solo las unidades de tiempo; si el modo de viaje seleccionado optimiza la distancia, quiere mostrar solo las unidades de distancia. En el caso poco común de que el modo de viaje optimice algún otro tipo de coste, no quiere mostrar unidades de tiempo ni de distancia.
Se puede utilizar el método updateParameters de la clase ToolValidator para actualizar las listas de opciones de parámetros. En esta sección, modificará el método updateParameters para establecer la lista de opciones de Unidades de valor límite con una lista apropiada de unidades, dependiendo del valor del parámetro Modo de viaje.
- Busque el método updateParameters de la clase ToolValidator.
De forma predeterminada, el método updateParameters contiene solo una instrucción return. No actualiza los parámetros.
- Cambie el método updateParameters para utilizar el siguiente código:
Precaución:
Compruebe la sangría del código de validación después de pegarlo en la clase ToolValidator.def updateParameters(self): # Modify parameter values and properties. # This gets called each time a parameter is modified, before # standard validation. # Set filter list of units in cutoff units parameter based on what type # of travel mode is selected travel_mode_param = self.params[3] cutoff_units_param = self.params[5] if travel_mode_param.valueAsText: try: tm_object = travel_mode_param.value if tm_object.impedance == tm_object.timeAttributeName: # The impedance has units of time, so present time units as # options cutoff_units_param.filter.list = ["Hours", "Minutes"] elif tm_object.impedance == tm_object.distanceAttributeName: # The impedance has units of distance, so present distance # units as options cutoff_units_param.filter.list = [ "Kilometers", "Meters", "Miles", "Yards", "Feet"] else: # The impedance has units that are neither time nor # distance, so present only one option, "Other". The # Service Area cutoffs will be interpreted in the impedance # units. cutoff_units_param.filter.list = ["Other"] except Exception: pass return
En este fragmento de código, la lista de valores posibles del parámetro Unidades de valor límite se actualiza basándose en el valor actual del parámetro Modo de viaje.
Los parámetros se recuperan con la variable self.params. El parámetro Modo de viaje está en el índice 3 (el cuarto parámetro) y el parámetro Unidades de valor límite está en el índice 5 (el sexto parámetro).
Si el parámetro Modo de viaje está vacío, no es necesario actualizar el parámetro Unidades de valor límite. La propiedad Parameter del objeto valueAsText es una forma rápida de determinar si el parámetro está vacío.
El valor del parámetro Modo de viaje se recupera como un objeto TravelMode mediante la propiedad Parameter del objeto value.
La forma más sencilla de determinar si el modo de viaje optimiza el tiempo, la distancia o alguna otra unidad de medida es comparar la propiedad TravelMode del objeto impedance con la propiedad timeAttributeName y la propiedad distanceAttributeName. La propiedad impedance devuelve el nombre del atributo de red que se está optimizando. Los modos de viaje también incluyen un atributo de tiempo (timeAttributeName) y un atributo de distancia (distanceAttributeName) predeterminados. Si impedance coincide con timeAttributeName, el modo de viaje optimiza el tiempo y el parámetro Unidades de valor límite se actualiza para mostrar una lista de unidades de tiempo. Si impedance coincide con distanceAttributeName, el modo de viaje optimiza la distancia y el parámetro Unidades de valor límite se actualiza para mostrar una lista de unidades de distancia. Si impedance no coincide con ninguno, el modo de viaje optimiza alguna otra variable y los valores límite del Área de servicio se interpretarán en esas unidades. El parámetro Unidades de valores límite se actualiza para mostrar solo una opción: Otro.
En todos los casos, la lista de opciones se especifica estableciendo la propiedad filter.list del objeto Parameterde las Unidades de valor límite.
El bloque de código se escribe en un bloque try/except. Si se encuentran errores al leer el modo de viaje, el código no hace nada y no actualiza la lista de opciones.
Verificar la validación de la herramienta
En esta sección, guardará y probará el código de validación.
- Si abrió la clase ToolValidator en un IDE o un editor de texto, guarde y cierre el archivo.
- Haga clic en Aceptar en el cuadro de diálogo Propiedades de herramienta para confirmar los cambios.
- En el panel Catálogo, haga doble clic en la herramienta para abrirla.
La herramienta Tutorial de la herramienta de script del Área de servicio se abre en el panel Geoprocesamiento.
- Introduzca un número menor o igual que 0 en el parámetro Valores límite.
Aparece un símbolo de error en el parámetro Valores límite. Si mantiene el puntero o hace clic en él, aparece el mensaje de error en la Información sobre herramientas.
- Verifique que la lista de opciones de Unidades de valor límite se actualice para mostrar la lista de unidades correcta cuando seleccione un valor en el parámetro Modo de viaje.
- Elija un valor para el parámetro Red.
Sugerencia:
Si está utilizando los datos del tutorial proporcionados, use el dataset de red, SanFrancisco.gdb/Transportation/Streets_ND, para el parámetro Red. Puede utilizar la ruta del catálogo al dataset de red o puede agregarla al mapa primero y utilizar su representación de capa como entrada para la herramienta.Cuando el parámetro Red está vacío, el parámetro Modo de viaje no incluye una lista de opciones. Cuando se introduce un valor para el parámetro Red, la lista de opciones del parámetro Modo de viaje se actualiza automáticamente para incluir la lista de modos de viaje disponibles asociados con el valor Red.
- Elija un valor para el parámetro Modo de viaje.
Cuando el parámetro Modo de viaje está vacío, el parámetro Unidades de valor límite no incluye una lista de opciones. Cuando se introduce un valor para el parámetro Modo de viaje, la lista de opciones del parámetro Unidades de valor límite se actualiza automáticamente para mostrar una lista de unidades de tiempo o de distancia (o la opción única para Otro).
- Elija un valor para el parámetro Red.
Ejecutar la herramienta
Ha creado y configurado la herramienta de script, ha escrito el código de la herramienta y ha personalizado la validación de la herramienta. Ahora ya está lista para ejecutarse y se puede utilizar como cualquier otra herramienta de geoprocesamiento. Además de ejecutar la herramienta desde el panel Geoprocesamiento, puede agregarla a un modelo, invocarla desde un script Python y compartirla como herramienta web.
- Si es necesario, abra la herramienta haciendo doble clic en ella en el panel Catálogo.
- Elija opciones válidas para cada uno de los parámetros de la herramienta.
Asegúrese de que los puntos que utiliza para el parámetro Instalaciones de entrada estén en la misma área geográfica que la red que utiliza para el parámetro Red.
Sugerencia:
Si utiliza los datos del tutorial que se proporcionan, utilice los datasets de la geodatabase SanFrancisco.gdb para probar la herramienta. La clase de entidad de punto de las estaciones de bomberos, SanFrancisco.gdb/Analysis/FireStations, se puede utilizar para el parámetro Instalaciones de entrada y el dataset de red, SanFrancisco.gdb/Transportation/Streets_ND, se puede utilizar para el parámetro Red. Puede usar las rutas del catálogo a los datos o puede agregar los datos al mapa primero y utilizar las capas como entradas para la herramienta. Un buen valor límite para modelar el tiempo de respuesta de una estación de bomberos es de dos a cuatro minutos. - Haga clic en el botón Ejecutar en la parte inferior de la herramienta.
La herramienta se ejecuta correctamente y agrega la capa de polígonos al mapa.
Nota:
La herramienta puede generar mensajes de advertencia.