Навигация | Mobile SDK | 2GIS Documentation
Android SDK

Навигация

Чтобы создать навигатор, можно использовать готовые элементы интерфейса и класс NavigationManager.

Для этого нужно добавить в MapView элементы NavigationView и DefaultNavigationControls.

<ru.dgis.sdk.map.MapView
    android:id="@+id/mapView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <ru.dgis.sdk.navigation.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
        <ru.dgis.sdk.navigation.DefaultNavigationControls
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </ru.dgis.sdk.navigation.NavigationView>
</ru.dgis.sdk.map.MapView>

После этого нужно добавить на карту маркер с текущим местоположением и создать объект NavigationManager.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    sdkContext = DGis.initialize(applicationContext, apiKeys)

    // Регистрируем источник геопозиции
    locationProvider = ManagerLocationSource(applicationContext)
    registerPlatformLocationSource(sdkContext, locationProvider)

    setContentView(R.layout.activity_navigation)

    findViewById<MapView>(R.id.mapView).apply { mapView ->
        lifecycle.addObserver(mapView)

        mapView.getMapAsync { map ->
            // Добавляем маркер с текущим местоположением
            map.addSource(
                MyLocationMapObjectSource(
                    sdkContext,
                    MyLocationDirectionBehaviour.FOLLOW_SATELLITE_HEADING,
                    createSmoothMyLocationController()
                )
            )
        }
    }

    // Создаём объект NavigationManager
    navigationManager = NavigationManager(sdkContext)

    findViewById<NavigationView>(R.id.navigationView).apply {
        // Привязываем созданный объект NavigationManager к элементу интерфейса NavigationView
        navigationManager = this@NavigationActivity.navigationManager
    }

    // Запускаем навигатор в режиме свободной навигации
    navigationManager.start()
}

Навигатор может работать в трёх режимах: свободная навигация, ведение по маршруту и симуляция ведения.

Настройки навигатора можно изменить через свойства NavigationManager.

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

Чтобы запустить навигатор в этом режиме, нужно вызвать метод start() без параметров.

navigationManager.start()

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

Чтобы запустить навигатор в этом режиме, нужно вызвать метод start() и указать объект RouteBuildOptions - координаты точки назначения и настройки маршрута.

val routeBuildOptions = RouteBuildOptions(
    finishPoint = RouteSearchPoint(
        coordinates = GeoPoint(latitude = 55.752425, longitude = 37.613983)
    ),
    routeSearchOptions = CarRouteSearchOptions(
        avoidTollRoads = true,
        avoidUnpavedRoads = false,
        avoidFerry = false,
        routeSearchType = RouteSearchType.JAM
    )
)

navigationManager.start(routeBuildOptions)

Дополнительно при вызове метода start() можно указать объект TrafficRoute - готовый маршрут для навигации (см. раздел Построение маршрута). В таком случае навигатор не будет пытаться построить маршрут от текущего местоположения, а начнёт ведение по указанному маршруту.

navigationManager.start(routeBuildOptions, trafficRoute)

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

Чтобы запустить навигатор в режиме симуляции, нужно вызвать метод startSimulation(), указав готовый маршрут (TrafficRoute) и его настройки (RouteBuildOptions).

Скорость движения можно изменить с помощью свойства SimulationSettings.speed (метры в секунду).

navigationManager.simulationSettings.speed = 30 / 3.6
navigationManager.startSimulation(routeBuildOptions, trafficRoute)

Остановить симуляцию можно с помощью метода stop().

navigationManager.stop()

Чтобы включить показ дорожного трафика, нужно добавить на карту источник данных TrafficSource.

val trafficSource = TrafficSource(sdkContext)
map.addSource(trafficSource)

В рамках SDK можно использовать произвольный источник геопозиции. Для этого нужно реализовать интерфейс LocationSource.

public class CustomLocationSource: LocationSource {
    override fun activate(listener: LocationChangeListener?) {
        // Включение источника геопозиции
    }

    override fun deactivate() {
        // Выключение источника геопозиции
    }

    override fun setDesiredAccuracy(accuracy: DesiredAccuracy?) {
        // Изменение требуемого уровня точности
    }
}

Чтобы зарегистрировать созданный источник в SDK, нужно вызвать функцию registerPlatformLocationSource().

val customSource = CustomLocationSource()
registerPlatformLocationSource(sdkContext, customSource)

Основная точка входа в интерфейс - функция activate(). Когда SDK потребуется геопозиция, в эту функцию будет передан объект LocationChangeListener. После этого, чтобы сообщить текущую геопозицию, нужно передать в него массив объектов Location (от более старой позиции к более новой), используя метод onLocationChanged().

val location = Location(...)
val newLocations = arrayOf(location)
listener.onLocationChanged(newLocations)

Чтобы сообщить изменение доступности источника, можно вызвать метод onAvailabilityChanged().

Дополнительно можно менять логику определения геопозиции в зависимости от требуемой точности. Требуемая точность передаётся в функцию setDesiredAccuracy() в виде объекта DesiredAccuracy.

Когда источник геопозиции больше не требуется, будет вызвана функция deactivate().