Слой навигации

NavigationLayer в NaviKit SDK представляет собой дополнительный слой на карте, который включает в себя пользовательский интерфейс (маршруты, точки маршрута, метка пользователя и баллуны) и логику их отображения. Кроме того, NavigationLayer предоставляет API камеры, которое позволяет изменять положение карты на основе различных навигационных сценариев, например: слежение за меткой пользователя, обзор всего маршрута и свободный режим.

Создание

Используйте метод NavigationLayerFactory.createNavigationLayer для создания нового экземпляра навигационного слоя.

val navigationLayer = NavigationLayerFactory.createNavigationLayer(
    mapWindow,
    roadEventsLayer,
    navigationStyleProvider,
    navigation
)

Процесс создания roadEventsLayer был рассмотрен тут, создание navigation - тут.

После создания NavigationLayer при включенном отслеживании локации у Navigation, на карте отобразиться метка с текущим местоположением пользователя.

NavigationStyleProvider

Отображение UI-элементов на навигационном слое карты определяется при помощи интерфейса NavigationStyleProvider.

С помощью реализации NavigationStyleProvider можно настроить стили отображения отдельных UI-элементов с помощью реализации нужного провайдера стилей:

Класс AutomotiveNavigationStyleProvider - это готовая реализация итерфейса NavigationStyleProvider, которая содержит UI-элементы в фирменном стиле Яндекс Карт. Она поставляется в виде отдельной зависимости.

Для того, чтобы изменить некоторые стили UI-элементов, можно реализовать новый NavigationStyleProvider, используя AutomotiveNavigationStyleProvider в качестве делегата:

class NavigationStyleProviderImpl(private val context: Context) : NavigationStyleProvider {

    private val styleProvider = AutomotiveNavigationStyleProvider(context)

    // Default style provider implementation
    override fun balloonImageProvider() = styleProvider.balloonImageProvider()
    override fun requestPointStyleProvider() = styleProvider.requestPointStyleProvider()
    override fun userPlacemarkStyleProvider() = styleProvider.userPlacemarkStyleProvider()
    override fun routePinsStyleProvider() = styleProvider.routePinsStyleProvider()

    // Override the route style logic
    override fun routeViewStyleProvider(): RouteViewStyleProvider {
        return object : RouteViewStyleProvider {

            private val routeViewStyleProvider = styleProvider.routeViewStyleProvider()

            override fun provideRouteStyle(
                flags: Flags,
                isSelected: Boolean,
                isNightMode: Boolean,
                routeStyle: RouteStyle
            ) {
                routeViewStyleProvider.provideRouteStyle(flags, isSelected, isNightMode, routeStyle)
                // Only the current route will display traffic jams
                routeStyle.setShowJams(isSelected)
            }

            // Implementations of other methods through routeViewStyleProvider ...
        }
    }
}

Таким образом, можно реализовать отдельный провайдер стилей для линии маршрута RouteViewStyleProvider и изменить стиль отображения пробок на маршрутах. Для остальных UI-элементов используется стандартная реализация с помощью делегата AutomotiveNavigationStyleProvider.

Стили из NavigationStyleProvider обновляются на каждый вызов NavigationLayer.refreshStyle.

Подробнее с примером реализации NavigationStyleProvider можно ознакомиться в демо-приложении.

Маршруты

Слой навигации отвечает за отображение маршрутов, которые хранятся в Navigation.

Отображение маршрутов

Слой навигации способен отображать маршруты на карте. Отрисовка маршрутов происходит по следующему сценарию:

  1. При создании NavigationLayer в него передается объект Navigation, с помощью которого слой подписывается на состояние навигации и отслеживает изменение маршрутов в нем. Например, после запроса маршрутов с помощью обработчика событий NavigationListener.onRoutesRequested навигация сообщает, что маршрут был запрошен и слой переводит камеру в режим обзора маршрутов.
  2. Затем навигация сообщает об успешном получении маршрутов, происходит вызов метода NavigationListener.onRoutesBuilt и слой отображает маршруты на карте по обновленным данным.

Таким образом, слой навигации отлеживает состояние маршрутов внутри Navigation, отображает их на карте и при необходимости перерисовывает.

Мгновенное ведение

Чтобы пропустить этап сравнения альтернативных маршрутов в режиме обзора маршрутов и начать ведение по первому найденному маршруту следует начинать ведение сразу же после получения результатов запроса маршрутов в методе обработчике события NavigationListener.onRoutesBuilt.

При этом, в момент когда маршруты уже были запрошена, но ведение еще не началось, можно заметить "промаргивание" UI-маршрутов. Чтобы этого избежать нужно скрыть UI навигационного слоя до начала ведения по маршруту. Например, используя метод NavigationLayer.setIsVisible, или спрятать линии маршрута используя переопределение стилей через NavigationStyleProvider.

Источники маршрутов

NavigationLayer.getRoutesSources определяет какой именно тип маршрутов в данный момент отображает слой навигации:

  • NAVIGATION - результат запроса маршрутов через Navigation при отображении маршрутов в режиме обзора.
  • GUIDANCE - текущий маршрут во время ведения при отображении маршрутов во время ведения.

Текущий маршрут

NavigationLayer хранит информацию о текущем выбранном маршруте. При помощи вызова NavigationLayer.selectRoute можно изменить текущий выбранный маршрут в режиме обзора.

Пример назначения текущего маршрута:

val routeViewListener = object : RouteViewListener {
    override fun onRouteViewTap(routeView: RouteView) {
        when (navigationLayer.routesSource) {
            RoutesSource.NAVIGATION -> navigationLayer.selectRoute(routeView)
            RoutesSource.GUIDANCE -> navigationLayer.navigation.guidance.switchToRoute(routeView.route)
        }
    }

    override fun onRouteViewsChanged() {
        if (navigationLayer.selectedRoute() != null) return
        val route = navigationLayer.routes.firstOrNull() ?: return
        navigationLayer.selectRoute(route)
    }
}
navigationLayer.addRouteViewListener(routeViewListener)

Для подписки на состояние маршрутов на карте навигационного слоя используется интерфейс RouteViewListener.

Примечание

По умолчанию после запроса маршрутов через Navigation текущий маршрут в навигационном слое отсутствует, поэтому его нужно назначить вручную, например, с помощью RouteViewListener.onRouteViewsChanged.

Точки маршрута

Слой навигации отвечает за отображение from, to и via точек во время ведения и обзора маршрута.

Для подписки на изменение точек и их нажатия используется интерфейс RequestPointListener.

Пользовательская метка

Пользовательской меткой называют модель на карте, которая отвечает за отображение текущей локации пользователя и направления его движения. Модель состоит из файла .OBJ и текстуры в формате .PNG.

Баллуны

Баллуны представляют собой UI-элементы на карте с надписью. Существует несколько видов баллунов:

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

Для подписки на события, связанные с баллунами, используется интерфейс BalloonViewListener.

Камера

Управление камерой происходит с помощью объета Camera, который можно получить используя вызов NavigationLayer.getCamera.

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

  • Following - режим слежения камеры за меткой пользователя во время ведения.
  • Overview - обзор запрошенных маршрутов.
  • Free - режим по умолчанию.

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

При помощи методов Camera и NavigationLayer можно изменять следующие параметры камеры:

  • автоматическое приближение камеры;
  • автоматический поворот камеры;
  • автоматическое переключение режимов камеры;
  • параметр корректировки приближения во время ведения;
  • включение/отключение 2D режима камеры.

При создании комплексного интерфейса поверх карты UI-элементы могут перекрывать некоторые области карты. Для того, чтобы это избежать существует возможность настроить параметры видимой области карты.

Поддержаны следующие настройки видимой области карты:

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