Пользовательские анализаторы

Пользовательские анализаторы позволяют изменять значения стоимости и ограничений для сетевых элементов во время операции решения с помощью скрипта Python. Они могут запрашивать базовое значение элемента и обновлять его по мере необходимости или задавать другое значение на основе других входных данных. Это позволяет вам задавать значения атрибутов во время решения без обновления базового набора сетевых данных или исходных объектов.

Более подробно о сетевых атрибутах и анализаторах

Пользовательский анализатор можно использовать в следующих случаях:

  • Масштабирование стоимости улиц на основе запроса таблицы в другой базе данных.
  • Ограничение объектов улиц на основе чтения идентификатора объекта из внешнего файла.
  • Динамическое масштабирование стоимости улиц в зависимости от времени суток.

Для реализации пользовательских анализаторов создайте класс Python, который наследуется от класса arcpy.nax.AttributeEvaluator, и связывания класса Python с определенным набором сетевых данных. Они могут быть связаны с атрибутами стоимости, ограничения или дескриптора. Они могут обновлять ребра, соединения или повороты как для операций решения с поддержкой времени, так и для операций решения, для которых время не включено. В зависимости от внесенных изменений обновления могут изменить затраты и пути, обнаруженные в ходе анализа.

С отдельным сетевым атрибутом должен быть связан только один пользовательский анализатор, но любое количество сетевых атрибутов может быть связано с анализатором. При реализации пользовательского анализатора ряд объектов можно использовать для сбора информации о сети и элементах, таких как Attribute, Edge, Junction и др.

Класс пользовательского анализатора

Чтобы создать пользовательский анализатор, задайте класс, который наследуется от класса arcpy.nax.AttributeEvaluator и реализует по крайней мере один из методов значения элемента (например edgeValue или edgeValueAtTime). Также можно создать пользовательский анализатор для реализации методов __init__, attach и refresh.

Методы пользовательского анализатора

В подразделах ниже описываются методы, которые можно использовать для задания значений атрибутов во время решения.

Initializer

Вы можете реализовать метод initializer __init__. Если он реализован, метод initializer базового класса должен быть вызван явным способом перед добавлением логики инициализации. Иначе метод initializer базового класса вызывается автоматически.

Метод initializer базового класса будет использовать переданное имя атрибута и имена источников для задания свойств self.attributeName и self.sourceNames для объекта.

class CustomEvaluatorExample(arcpy.nax.AttributeEvaluator):
    """Example custom evaluator."""

    def __init__(self, attributeName, sourceNames=None):
        """Example initializer."""
        super().__init__(attributeName, sourceNames)
        # Do additional custom initialization

Attach

Когда пользовательский анализатор связан с сетевым набором данных, вызывается внутренний метод attach. Внутренний код запрашивает атрибуты сетевого набора данных для получения указанного имени атрибута. Если имя атрибута найдено, свойству self.attribute присваивается значение индекса атрибута; в противном случае пользовательский анализатор не связывается с сетевым набором данных и никакие другие методы класса не вызываются (включая любой метод attach).

Вы можете использовать метод attach, реализованный в пользовательском анализаторе, для изучения и проверки набора сетевых данных, чтобы убедиться, что он соответствует требованиям кода пользовательского анализатора, например, для проверки наличия других атрибутов. Если набор сетевых данных корректен, метод attach возвращает True; в противном случае он возвращает False. Когда возвращается False, пользовательский анализатор не будет связан с сетевым набором данных, и никакие другие методы вызываться не будут.

Реализация метода attach в пользовательском анализаторе необязательна.

Примечание:

Набор сетевых данных может быть открыт несколько раз в зависимости от количества потоков, используемых приложением для доступа к нему.

Обновить

Метод refresh пользовательского анализатора вызывается в начале каждой операции решения, перед вычислением каких-либо элементов. В этом методе может быть задано любое внутреннее состояние (например, кэшированные значения или проверка несетевого набора данных), которое меняется в зависимости от решения. Свойство self.networkQuery доступно в этом методе. Это свойство задается внутренне, после успешного завершения метода attach.

Реализация метода refresh в пользовательском анализаторе необязательна.

Методы значений

Могут быть реализованы следующие методы значений: edgeValue, edgeValueAtTime, junctionValue, junctionValueAtTime, turnValue и turnValueAtTime. Методы с префиксом edge влияют на значения атрибутов для источников ребер, методы с префиксом junction влияют на значения атрибутов для источников соединений и методы с префиксом turn влияют на значения атрибутов для источников поворотов. Методы с суффиксом AtTime вызываются во время операций решения с включенным временем, а методы без этого суффикса вызываются, когда время не используется.

В общем, во время операции решения, когда вычисляется атрибут и имеется подключенный пользовательский анализатор, он переопределяет основной. Значение, возвращаемое методом связанного элемента (например, edgeValue), будет использоваться механизмом решения в оставшейся части анализа. Используя эти методы значений, вы можете реализовать пользовательскую логику для задания конечного значения атрибута элемента.

Методы ValueAtTime предоставляют параметр datetime, который является датой и временем появления элемента на потенциальном маршруте. Эти методы вызываются для каждого элемента, потенциально несколько раз, во время операции решения. Любой код в этих методах должен быть исполняемым.

Вы должны реализовать хотя бы один из этих методов значений.

Примеры

В приведенных ниже примерах показана базовая реализация класса пользовательского анализатора.

Пример 1: Следующий код представляет собой класс пользовательского анализатора, который удваивает стоимость указанного атрибута для всех вычисляемых ребер для решения, не зависящего от времени, без реализации каких-либо необязательных методов:

import arcpy

class EdgeCustomizer(arcpy.nax.AttributeEvaluator):
    """Defines a custom evaluator that multiplies the edge cost by 2."""

    def edgeValue(self, edge: arcpy.nax.Edge):
        """Multiplies the edge cost by 2."""
        base_value = self.networkQuery.attributeValue(edge, self.attribute)
        return base_value * 2

Пример 2: Следующий код представляет собой класс пользовательского анализатора, который удваивает стоимость указанного атрибута для всех вычисляемых ребер как для решения, не зависящего от времени, так и для решения с поддержкой времени, с минимальной реализацией необязательных методов:

import datetime
from typing import Union, Optional, List
import arcpy

class EdgeCustomizer(arcpy.nax.AttributeEvaluator):
    """Defines a custom evaluator that multiplies the edge cost by 2."""

    def __init__(self, attributeName: str, sourceNames: Optional[List] = None):
        """Example initializer."""
        super().__init__(attributeName, sourceNames)
        # Do additional custom initialization

    def attach(self, network_query: arcpy.nax.NetworkQuery) -> bool:
        """Connect to and validate the network dataset."""
        # Do additional validation checks before returning Boolean
        return True

    def refresh(self) -> None:
        """Reset internal state before solve."""
        # Reset internal state in this method as needed
        pass

    def edgeValue(self, edge: arcpy.nax.Edge):
        """Multiplies the edge cost by 2."""
        base_value = self.networkQuery.attributeValue(edge, self.attribute)
        return base_value * 2

    def edgeValueAtTime(
            self, edge: arcpy.nax.Edge,
            time: datetime.datetime, time_usage: arcpy.nax.NetworkTimeUsage
    ) -> Union[int, float, bool]:
        """Multiplies the edge cost by 2 when the solve uses a time of day."""
        base_value_at_time = self.networkQuery.attributeValue(
            edge, self.attribute, time_usage, time)
        return base_value_at_time * 2

Связывание пользовательского анализатора с набором сетевых данных

Существует два способа развернуть пользовательский анализатор, чтобы он был связан с набором сетевых данных и чтобы логика настройки вызывалась во время операции решения: временный и постоянный.

Подсказка:

Создание класса пользовательского анализатора и его тестирование как временного пользовательского анализатора. Затем запустите скрипт в режиме отладки в таком редакторе, как Visual Studio Code. Как только он заработает должным образом, и если необходимо, вы можете сделать его постоянным пользовательским анализатором. Затем проверьте постоянный анализатор, чтобы убедиться, что все работает правильно.

Временный пользовательский анализатор

Временные пользовательские анализаторы связаны только с объектом набора сетевых данных, созданным в скрипте; они не сохраняются постоянно в наборе сетевых данных. Временные пользовательские анализаторы настраиваются с использованием свойства customEvaluators объекта набора сетевых данных в сценарии, выполняющем решение.

Временный пользовательский анализатор можно использовать для приложений, в которых пользовательский анализатор должен вызываться из скрипта Python. Они также могут быть полезны для разработки и отладки постоянных пользовательских анализаторов.

Настройка временного пользовательского анализатора

Чтобы настроить временный пользовательский анализатор, создайте объект пользовательского анализатора и используйте свойство customEvaluators объекта набора сетевых данных, чтобы связать с ним объект пользовательского анализатора.

В приведенном ниже примере показано, как создать экземпляр пользовательского объекта анализатора, который настраивает сетевой атрибут TravelTime, и связать его с объектом набора сетевых данных. Чтобы вызвать пользовательские анализаторы во время решения, создайте экземпляр объекта решения маршрута, используя объект набора сетевых данных.

# Instantiate a custom evaluator object that will customize the
# TravelTime cost attribute
travel_time_customizer = EdgeCustomizer("TravelTime")

# Create a network dataset object
network_dataset = arcpy.nax.NetworkDataset(
    r"C:\Data\Tutorial\SanFrancisco.gdb\Transportation\Streets_ND")

# Attach the custom evaluator object to the network dataset
network_dataset.customEvaluators = [travel_time_customizer]

# Instantiate a route analysis
route = arcpy.nax.Route(network_dataset)
Примечание:

При запуске пользовательского анализатора вы можете предоставить список имен конкретных сетевых источников, где указываются источники, к которым будет применяться пользовательский анализатор. Если список не задан, пользовательский анализатор будет применен ко всем источникам. Подробнее см. документацию к AttributeEvaluator.

Постоянные пользовательские анализаторы

Постоянные пользовательские анализаторы хранят ссылку на класс пользовательских анализаторов как часть схемы набора сетевых данных, которая хранится в базе геоданных. Эти пользовательские анализаторы будут вызываться при каждом выполнении операции решения с использованием этого набора сетевых данных. Такой вариант называется постоянным, поскольку ссылка является частью набора сетевых данных. Они настраиваются с использованием updateNetworkDatasetSchema объекта набора сетевых данных.

При открытии сети с сохраненным пользовательским анализатором, вызывается метод attach, а пользовательский анализатор загружается и кэшируется. Этот кэш сохраняется в течение всего срока работы приложения. Это означает, что любые изменения, внесенные в класс постоянного пользовательского анализатора, не будут прочитаны до тех пор, пока приложение, в котором открыт набор сетевых данных, не будет закрыто и перезапущено. Это применимо и к ArcGIS Pro, и к ArcGIS Server.

Важно отметить, что для постоянных пользовательских анализаторов схема набора сетевых данных содержит только ссылку на пользовательский анализатор, а не код класса. Эта ссылка позволяет набору сетевых данных при доступе к нему неявно найти и загрузить соответствующий пользовательский анализатор. Файл, содержащий код класса, должен находиться в папке site-packages активной среды ArcGIS Pro Python, чтобы набор сетевых данных мог его найти.

Более подробно о средах Python

Примечание:

Если скрипт настройки должен использовать сторонние пакеты Python, которые не включены в среду ArcGIS Pro Python по умолчанию, рекомендуется клонировать среду Python по умолчанию перед установкой дополнительных пакетов. Следуйте инструкциям в разделе Менеджер пакетов, чтобы создать клон среды ArcGIS Pro Python по умолчанию, добавить пакеты и активировать среду. Файл Python пользовательского анализатора должен храниться в каталоге site-packages активной среды Python, в данном случае — клона среды ArcGIS Pro Python по умолчанию.

То же самое касается ArcGIS Server. Если вам необходимо развернуть сохраненную настройку на сайте ArcGIS Server и использовать дополнительные сторонние пакеты, которые не включены в среду ArcGIS Server Python по умолчанию, следуйте инструкциям в разделе Развертывание пользовательских пакетов Python для ArcGIS Server, чтобы клонировать среду Python по умолчанию и добавить пакеты, а затем активируйте клонированную среду. При развертывании сохраненной настройки в ArcGIS Server ее необходимо скопировать в каталог site-packages активной среды Python на ArcGIS Server.

Используйте постоянный пользовательский анализатор, когда вам нужно вызвать пользовательский анализатор при выполнении операции решения вне скрипта Python, например, в ArcGIS Pro или ArcGIS Server.

Если слой сетевого анализа, использующий набор сетевых данных с постоянным пользовательским анализатором, публикуется как сервис, пакет пользовательского анализатора должен быть вручную скопирован в каталог пакетов сайта ArcGIS Server Python. Кроме того, когда пользовательский анализатор используется в сервисе, любой внешний ресурс, который он использует (например, файлы), должен быть доступен пользователю ArcGIS Server, поскольку это зависит от настройки сервера.

Настройка постоянного пользовательского анализатора

Используйте метод updateNetworkDatasetSchema для объекта набора сетевых данных, чтобы постоянно обновлять схему набора сетевых данных, передавая словарь, определяющий сетевой атрибут, для которого следует вызвать пользовательский анализатор, и путь к классу пользовательского анализатора. Этот путь использует точечную нотацию для определения имени папки (в каталоге site-packages), имени файла, в котором находится класс, и имени класса.

В приведенном ниже примере показано, как обновить набор сетевых данных с помощью сохраненного класса пользовательских анализаторов. Класс в этом примере называется EdgeCustomizer, а его код находится в модуле Python с именем customization.py в папке с именем na_customizers, которая находится в папке site-packages для ArcGIS Pro активной среды Python.

import arcpy

# Create a network dataset object
network_dataset = arcpy.nax.NetworkDataset(
    r"C:\Data\Tutorial\SanFrancisco_Persisted.gdb\Transportation\Streets_ND")

# Create a dictionary referencing the custom evaluators to apply to the
# TravelTime attribute
my_custom_evaluators = {
    "TravelTime": {"class": "na_customizers.customization.EdgeCustomizer"}
}

# Update the network dataset to use the custom evaluator
network_dataset.updateNetworkDatasetSchema(custom_evaluators=my_custom_evaluators)
Примечание:

При обновлении схемы со ссылкой на пользовательский анализатор вы можете предоставить список имен определенных сетевых источников, где указываются источники, к которым будет применяться пользовательский анализатор. Если список не задан, пользовательский анализатор будет применен ко всем источникам. Чтобы установить это, включите ключ sourceNames в список имен источников. Ниже приведен пример:

{
    "TravelTime": {
        "class": "na_customizers.customization.EdgeCustomizer",
        "sourceNames": ["Streets"]
    }
}

Когда этот набор сетевых данных и назначенный атрибут используются в сетевом анализе, набор сетевых данных будет вызывать пользовательский анализатор во время решения. Сеть проверит существование указанного атрибута и источников, а также найдет и загрузит указанный пакет и класс из папки пакетов сайта активной среды ArcGIS Pro Python. Если атрибут, имена источников, пакет или класс не найдены, пользовательский анализатор использоваться не будет. Решение завершится появлением предупреждающего сообщения о том, что при использовании пользовательского анализатора возникла проблема.

Если в наборе сетевых данных сохранены пользовательские анализаторы, они будут перечислены в разделе Итоговая информация панели ОбщееИ диалогового окна свойств набора сетевых данных. Они также будут отображаться вместе с указанным сетевым атрибутом при просмотре соответствующей вкладки, например, вкладки Стоимость на вкладке Атрибуты передвижения. Если при загрузке класса возникла проблема, появятся предупреждающие сообщения.

Жизненный цикл объекта

Когда набор сетевых данных изначально создается и имеет постоянный пользовательский анализатор, он создает экземпляр объекта пользовательского анализатора, на который ссылаются на протяжении всего его времени жизни. Время жизни может варьироваться в зависимости от используемой платформы (например, ArcGIS Pro, ArcGIS Server или Python).

Поскольку конкретный экземпляр объекта пользовательского анализатора может использоваться для нескольких решений, важно управлять состоянием этого объекта, в частности, сбрасывать переменные в методе refresh по мере необходимости. Например, если пользовательскому анализатору необходимо записать количество ребер для каждого решения, сбросьте переменную, используемую для отслеживания этого значения, в методе refresh.

В контексте ArcGIS Server каждый процесс SOC (во время запуска и во время перезапуска) создаст новый объект набора сетевых данных, а также создаст новый экземпляр объекта пользовательского анализатора. Этот экземпляр объекта пользовательского анализатора будет использоваться на протяжении всего жизненного цикла процесса SOC; только методы refresh и Value будут запускаться для каждого запроса.

Ограничения

К пользовательским анализаторам применяются следующие ограничения:

  • Пользовательские анализаторы доступны только в ArcGIS Pro и ArcGIS Server.
  • Пользовательские анализаторы могут быть вызваны только для файловой или корпоративной базы геоданных.
  • Атрибуты дескриптора вызываются только тогда, когда на них ссылается атрибут стоимости или ограничения.
  • Из соображений производительности пользовательские анализаторы не поддерживают использование ключевых слов в качестве аргументов.

Создание и использование временного пользовательского анализатора

В следующих разделах описывается, как создать и использовать временный пользовательский анализатор. Каждый пример кода иллюстрирует определенный компонент полного рабочего процесса. Есть следующие компоненты рабочего процесса:

  1. Расчет анализа маршрутов
  2. Настройка класса пользовательского анализатора
  3. Связывание пользовательского анализатора с набором сетевых данных

Последний пример кода показывает, как соединить все компоненты вместе.

Следующие примеры кода созданы на основе руководства по сетевому анализу, которое можно загрузить со страницы загрузки данных.

Расчет анализа маршрутов

В приведенном ниже примере кода показан рабочий процесс для анализа маршрута с использованием объекта механизма расчета arcpy.nax и печати времени передвижения по маршруту.

Примечание:

Путь к базе геоданных в приведенном ниже коде необходимо обновить, чтобы отразить расположение данных в вашей системе.

import arcpy

# Create a network dataset object
network_dataset = arcpy.nax.NetworkDataset(
    r"C:\Data\Tutorial\SanFrancisco.gdb\Transportation\Streets_ND")

# Instantiate a route analysis
route = arcpy.nax.Route(network_dataset)

# Insert stops for the route
with route.insertCursor(
    arcpy.nax.RouteInputDataType.Stops,
    ["NAME", "SHAPE@XY"]
) as cursor:
    cursor.insertRow(["Stop1", (-122.501, 37.757)])
    cursor.insertRow(["Stop2", (-122.445, 37.767)])

# Solve the route
result = route.solve()

# Print the total travel time for the route
for row in result.searchCursor(
    arcpy.nax.RouteOutputDataType.Routes,
    ["Total_Minutes"]
):
    print(f"Solved Total_Minutes: {row[0]}")

Настройка класса пользовательского анализатора

В приведенном ниже примере кода показано определение класса пользовательских анализаторов. В этом примере исходную стоимость времени умножается на коэффициент 2. Время в пути по маршруту, рассчитанному с помощью этого пользовательского анализатора, должно быть в два раза больше времени в пути того же маршрута, решенного без анализатора.

class EdgeCustomizer(arcpy.nax.AttributeEvaluator):
    """Defines a custom evaluator that multiplies the edge cost by 2."""

    def edgeValue(self, edge: arcpy.nax.Edge):
        """Multiplies the edge cost by 2."""
        base_value = self.networkQuery.attributeValue(edge, self.attribute)
        return base_value * 2

Связывание пользовательского анализатора с набором сетевых данных

В приведенном ниже примере кода показано создание экземпляра класса пользовательского анализатора и его связывание с объектом набора сетевых данных для использования с атрибутом стоимости TravelTime. Выполните этот рабочий процесс до вызова расчета маршрута (route.solve()).

# Create a custom evaluator object that will customize the
# TravelTime cost attribute
travel_time_customizer = EdgeCustomizer("TravelTime")

# Attach the custom evaluator object to the network dataset
network_dataset.customEvaluators = [travel_time_customizer]

Сборка всех компонентов

В приведенном ниже примере кода показано, как объединить все компоненты в полный рабочий процесс, который определяет и использует временный пользовательский анализатор для рабочего процесса анализа маршрута.

import arcpy

class EdgeCustomizer(arcpy.nax.AttributeEvaluator):
    """Defines a custom evaluator that multiplies the edge cost by 2."""

    def edgeValue(self, edge: arcpy.nax.Edge):
        """Multiplies the edge cost by 2."""
        base_value = self.networkQuery.attributeValue(edge, self.attribute)
        return base_value * 2

# Create a custom evaluator object that will customize the
# TravelTime cost attribute
travel_time_customizer = EdgeCustomizer("TravelTime")

# Create a network dataset object
network_dataset = arcpy.nax.NetworkDataset(
    r"C:\Data\Tutorial\SanFrancisco.gdb\Transportation\Streets_ND")

# Attach the custom evaluator object to the network dataset
network_dataset.customEvaluators = [travel_time_customizer]

# Instantiate a route analysis
route = arcpy.nax.Route(network_dataset)

# Insert stops for the route
with route.insertCursor(
    arcpy.nax.RouteInputDataType.Stops,
    ["NAME", "SHAPE@XY"]
) as cursor:
    cursor.insertRow(["Stop1", (-122.501, 37.757)])
    cursor.insertRow(["Stop2", (-122.445, 37.767)])

# Solve the route
result = route.solve()

# Print the total travel time for the route
for row in result.searchCursor(
    arcpy.nax.RouteOutputDataType.Routes,
    ["Total_Minutes"]
):
    print(f"Solved Total_Minutes: {row[0]}")

Создание и использование постоянного пользовательского анализатора

В следующих разделах описывается, как создать и использовать постоянный пользовательский анализатор. В этом рабочем процессе создается собственный класс пользовательского анализатора в активной среде Python, обновляется набор сетевых данных для использования пользовательского анализатора и тестируется путем выполнения анализа маршрута. Есть следующие компоненты рабочего процесса:

  1. Клонирование среды Python по умолчанию (дополнительно)
  2. Настройка и сохранение класса пользовательского анализатора
  3. Обновление схемы набора сетевых данных
  4. Сохранение маршрута

Следующие примеры кода созданы на основе руководства по сетевому анализу, которое можно загрузить со страницы загрузки данных.

Клонирование среды Python по умолчанию (дополнительно)

Этот шаг не является обязательным. Клонировать среду Python по умолчанию необходимо только в том случае, если скрипт настройки должен использовать сторонние библиотеки Python, которые не включены в среду ArcGIS Pro Python по умолчанию.

Более подробно о клонировании среды

Настройка и сохранение класса пользовательского анализатора

В приведенном ниже примере кода показано определение класса пользовательских анализаторов. В этом примере исходную стоимость времени умножается на коэффициент 2. Время в пути по маршруту, рассчитанному с помощью этого пользовательского анализатора, должно быть в два раза больше времени в пути того же маршрута, решенного без анализатора.

import arcpy

class EdgeCustomizer(arcpy.nax.AttributeEvaluator):
    """Defines a custom evaluator that multiplies the edge cost by 2."""

    def edgeValue(self, edge: arcpy.nax.Edge):
        """Multiplies the edge cost by 2."""
        base_value = self.networkQuery.attributeValue(edge, self.attribute)
        return base_value * 2

В активной среде Python найдите папку site-packages. В ней создайте папку с именем na_customizers. Сохраните приведенный выше код, определяющий класс пользовательского анализатора, в папку na_customizers как cost_customization.py.

Примечание:

Следующие имена примеров, использованные в примере кода важны, так как в дальнейшем вы обновите схему набора сетевых данных этими значениями.

Обновление схемы набора сетевых данных

Копируйте Network Analyst\Tutorial\SanFrancisco.gdb из данных руководства в SanFrancisco_Persisted.gdb.

Используйте приведенный ниже код в автономном скрипте, чтобы постоянно обновлять набор сетевых данных SanFrancisco_Persisted.gdb, чтобы он ссылался на пользовательский анализатор атрибута стоимости TravelTime. Словарь my_custom_evaluators ссылается на имя папки, имя файла и имя класса пользовательского анализатора, определенного в приведенном выше примере кода.

import arcpy

# Check out ArcGIS Network Analyst extension
arcpy.CheckOutExtension("network")

# Create a network dataset object
network_dataset = arcpy.nax.NetworkDataset(
    r"C:\Data\Tutorial\SanFrancisco_Persisted.gdb\Transportation\Streets_ND")

# Create a dictionary referencing the custom evaluators to apply to the
# TravelTime attribute
my_custom_evaluators = {
    "TravelTime": {"class": "na_customizers.customization.EdgeCustomizer"}
}

# Update the network dataset to use the custom evaluator
network_dataset.updateNetworkDatasetSchema(custom_evaluators=my_custom_evaluators)

Сохранение маршрута

В ArcGIS Pro воспользуйтесь набором сетевых данных SanFrancisco_Persisted.gdb для построения маршрута с использованием режима передвижения Время в пути. Решите второй маршрут, используя SanFrancisco.gdb и те же остановки, и сравните время передвижения для выходного маршрута. Время передвижения по маршруту по SanFrancisco_Persisted.gdb должно быть в два раза больше времени поездки по SanFrancisco.gdb по тому же маршруту из-за пользовательского анализатора.

Подробнее о расчетах в анализе маршрутов в ArcGIS Pro

Развертывание пользовательских анализаторов для их использования в сервисах маршрутизации, размещенных на сайте ArcGIS GIS Server

Вы можете опубликовать два типа сервисов маршрутизации: стандартные сервисы маршрутизации и пользовательские сервисы маршрутизации.

Стандартные сервисы маршрутизации — это картографические сервисы и сервисы геообработки, которые предоставляют готовые возможности, доступные в Расширение ArcGIS Network Analyst. Вы можете опубликовать стандартные сервисы маршрутизации на сайте ArcGIS GIS Server, используя набор сетевых данных, и получите набор точек доступа сервиса маршрутизации с предзаданными параметрами и схемой для входных данных. Эти сервисы маршрутизации обеспечивают полную функциональность и интеграцию с приложениями Esri, такими как ArcGIS Pro и Map Viewer.

Подробные сведения о публикации стандартных сервисов маршрутизации

Пользовательские сервисы маршрутизации — это сервисы геообработки с настраиваемыми возможностями. Пользовательские сервисы маршрутизации позволяют вам выполнять рабочий процесс, который может содержать несколько анализаторов сетевого анализа или других инструментов геообработки. Он также позволяет задать пользовательские параметры и входную схему в соответствии с потребностями приложения.

Подробнее о публикации пользовательских сервисов маршрутизации

Как стандартные, так и пользовательские сервисы маршрутизации могут вызывать пользовательские анализаторы.

Вызов пользовательского анализатора со стандартными сервисами маршрутизации

Для вызова пользовательского анализатора со стандартными сервисами маршрутизации выполните следующие действия:

  1. Создайте постоянный пользовательский анализатор и свяжите его с набором сетевых данных.
  2. Протестируйте пользовательский анализатор в ArcGIS Pro, чтобы убедиться, что он вызывается при решении маршрута.
  3. Скопируйте набор сетевых данных в один и тот же каталог на всех компьютерах, участвующих в сайте ArcGIS Server, который будет использоваться для размещения сервисов маршрутизации.
  4. Скопируйте папку и файл настройки на все компьютеры, участвующие в сайте ArcGIS Server. Поместите папку и файл в папку site-packages активной среды ArcGIS Server Python. Путь на компьютере сервера по умолчанию - <install>\ArcGIS\Server\framework\runtime\ArcGIS\bin\Python\envs\arcgispro-py3\Lib\site-packages. При копировании из папки site-packages среды ArcGIS Pro Python в ArcGIS Server сохраняйте ту же структуру папок для кода настройки. Например, если код настройки находится в файле cost_customization.py в папке na_customizers, скопируйте папку na_customizers в директорию site-packages ArcGIS Server.
  5. Опубликуйте стандартные сервисы маршрутизации.

При использовании сервисов маршрутизации применяются настройки.

Вызов пользовательского анализатора с пользовательскими сервисами маршрутизации

Для вызова пользовательского анализатора с пользовательскими сервисами маршрутизации выполните следующие действия:

  1. Создайте инструмент-скрипт, выполнив действия из раздела Публикация пользовательских сервисов маршрутизации.
  2. Свяжите временный настройщик с набором сетевых данных в инструменте-скрипте.
  3. Опубликуйте сервис, выполнив действия из раздела Публикация пользовательских сервисов маршрутизации.

При использовании сервисов маршрутизации применяются настройки.

Пример кода: использование значений в поле класса объектов с помощью сетевого дескриптора

Пользовательские анализаторы работают с сетевыми элементами (например, с ребрами), что означает, что к значениям полей исходных объектов нельзя получить прямой доступ. Вместо этого вы можете получить доступ к этим значениям косвенно, создав атрибут дескриптора в своей сети, который считает значения полей исходных объектов.

Чтобы использовать это в пользовательском анализаторе, получите атрибутивный индекс дескриптора в методе attach. В приведенном ниже примере кода выполняется поиск атрибутивного индекса RoadClass и сохранение значения в переменной экземпляра road_class. Если атрибут не будет найден, метод возвращает False, что указывает на то, что пользовательский анализатор не может быть присоединен.

    def attach(self, network_query: arcpy.nax.NetworkQuery) -> bool:
        self.road_class_att = network_query.attribute("RoadClass")
        if self.road_class_att is None:
           return False
        else:
           return True

Затем в функциях оценки элемента код запросит значение атрибута дескриптора элемента и будет использовать его в функции по мере необходимости. В приведенном ниже примере значение RoadClass используется для определения способа изменения базового значения.

    def edgeValue(self, edge: arcpy.nax.Edge) :
        base_value = self.networkQuery.attributeValue(edge, self.attribute) 
        road_class_value = self.networkQuery.attributeValue(edge, self.road_class_att)
        if road_class_value in [1,2,3]: 
            return base_value * 2
        else:
            return base_value