Маршруты
Вы можете создавать маршруты для разных видов транспорта двумя способами:
-
Построить новый маршрут по компонентам:
- Точки маршрута: начальная, конечная и, если необходимо, промежуточные.
- Параметры поиска маршрута. Набор параметров зависит от типа транспорта, для которого строится маршрут.
-
Использовать готовый маршрут, который был построен ранее с помощью Routing API. Готовый маршрут уже содержит необходимые данные для отображения и навигации.
Построение маршрута
Для работы с маршрутом вам понадобится два объекта:
- TrafficRouter для создания или загрузки маршрута;
- источник данных RouteMapObjectSource для отображения маршрута на карте.
-
Чтобы создать новый маршрут, вызовите метод findRoute(), передав координаты точек в виде объектов RouteSearchPoint. Дополнительно вы можете указать параметры маршрута (RouteSearchOptions) и список промежуточных точек маршрута (список
RouteSearchPoint).val startSearchPoint = RouteSearchPoint(
coordinates = GeoPoint(latitude = 55.759909, longitude = 37.618806)
)
val finishSearchPoint = RouteSearchPoint(
coordinates = GeoPoint(latitude = 55.752425, longitude = 37.613983)
)
val trafficRouter = TrafficRouter(sdkContext)
val routesFuture = trafficRouter.findRoute(startSearchPoint, finishSearchPoint)Вызов
findRoute()вернёт отложенный результат со списком объектов TrafficRoute. -
Чтобы отобразить найденный маршрут на карте, создайте объекты RouteMapObject на основе полученных объектов
TrafficRouteи добавьте их в источник данных RouteMapObjectSource.// Создать источник данных
val routeMapObjectSource = RouteMapObjectSource(sdkContext, RouteVisualizationType.NORMAL)
map.addSource(routeMapObjectSource)
// Добавить созданный маршрут на карту
routesFuture.onResult { routes: List<TrafficRoute> ->
var isActive = true
var routeIndex = 0
for (route in routes) {
routeMapObjectSource.addObject(
RouteMapObject(route, isActive, routeIndex)
)
isActive = false
routeIndex++
}
}
Вместо пары TrafficRouter и RouteMapObjectSource для построения маршрута можно использовать RouteEditor и RouteEditorSource. В таком случае не нужно обрабатывать список TrafficRoute, достаточно передать координаты маршрута в виде объекта RouteEditorRouteParams в метод setRouteParams(), и маршрут отобразится автоматически.
val routeEditor = RouteEditor(sdkContext)
val routeEditorSource = RouteEditorSource(sdkContext, routeEditor)
map.addSource(routeEditorSource)
routeEditor.setRouteParams(
RouteParams(
startPoint = RouteSearchPoint(
coordinates = GeoPoint(latitude = 55.759909, longitude = 37.618806)
),
finishPoint = RouteSearchPoint(
coordinates = GeoPoint(latitude = 55.752425, longitude = 37.613983)
)
)
)
Точки маршрута
Для построения маршрута необходимо получить точки типа GeoPoint, которые далее используются для создания RouteSearchPoint. Существует множество способов это сделать, ниже описаны некоторые из них.
Получение точек по нажатию на карту
Вы можете получить ScreenPoint точки нажатия и преобразовать его в GeoPoint с помощью метода screenToMap().
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
Подпишитесь на канал tap распознавателя жестов MapController:
val connection = mapController.gestureRecognizer.tap.connect { point ->
val geoPoint: GeoPoint? = map.camera.projection.screenToMap(point)
}
В интерфейсе TouchEventsObserver существуют методы onTap() и onLongTouch(), которые позволяют получить точку нажатия:
override fun onTap(point: ScreenPoint) {
val geoPoint: GeoPoint? = map.camera.projection.screenToMap(point)
}
Получение координат объекта в месте нажатия на карту
Вы можете получить координаты объекта (здания, дороги), который находится в месте клика. Используйте метод getRenderedObjects(). В нём нужно получить объект класса DgisMapObject, который имеет поле id. Этот идентификатор является стабильным числовым идентификатором объекта справочника, с помощью которого можно выполнить поисковый запрос и получить информацию об объекте, в том числе географические координаты его центра.
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
map.getRenderedObjects(point).onResult { objects ->
// Получить ближайший к месту нажатия объект класса DgisMapObject
val renderedObject = objects.firstOrNull { it.item.item is DgisMapObject } ?: return@onResult
val mapObject = renderedObject.item.item as DgisMapObject
// Получить объект справочника по идентификатору
searchManager
.searchByDirectoryObjectIds(listOf(mapObject.id))
.onResult onDirectoryObjectReady@{ directoryObjects ->
// Получить первый найденный объект
val directoryObject = directoryObjects.firstOrNull() ?: return@onDirectoryObjectReady
// Получить координаты объекта в виде GeoPoint
val geoPoint = directoryObject.markerPosition?.point ?: return@onDirectoryObjectReady
}
}
map.getRenderedObjects(point).onResult { objects ->
// Получить ближайший к месту нажатия объект класса DgisMapObject
val renderedObject = objects.firstOrNull { it.item.item is DgisMapObject } ?: return@onResult
val mapObject = renderedObject.item.item as DgisMapObject
// Получить объект справочника по идентификатору
searchManager
.searchByDirectoryObjectId(mapObject.id)
.onResult onDirectoryObjectReady@{ directoryObject ->
directoryObject ?: return@onDirectoryObjectReady
// Получить координаты объекта в виде GeoPoint
val geoPoint = directoryObject.markerPosition?.point ?: return@onDirectoryObjectReady
}
}
Координаты центра для больших объектов (например, МКАД) могут находиться далеко за пределами области видимости камеры, так как полученный объект не учитывает расположение камеры или места нажатия на карту. С такими объектами лучше использовать другие способы получения координат.
Проезд промежуточных точек
Для маршрута с промежуточными точками предполагается, что пользователь посетит каждую из этих точек на маршруте по очереди. Если промежуточная точка пропущена, маршрут может перестроиться:
- Если по данным GPS видно, что пользователь движется не в сторону нужной промежуточной точки, маршрут перестраивается относительно текущего положения пользователя так, чтобы он посетил пропущенную точку. Когда посещение точки будет зафиксировано, маршрут продолжится.
- Если момент посещения промежуточной точки не зафиксирован из-за слабого сигнала GPS, но позже положение пользователя зафиксировано на маршруте по направлению к следующей точке или около него, точка считается пройденной и маршрут продолжается.
Параметры поиска маршрута
Для автомобилей
Чтобы построить маршрут для легкового автомобиля, укажите свойство car в RouteSearchOptions. Дополнительно вы можете настроить параметры построения маршрута CarRouteSearchOptions:
avoidTollRoads: избегать ли платных дорог (по умолчаниюfalse).avoidUnpavedRoads: избегать ли грунтовых дорог (по умолчаниюfalse).avoidFerries: избегать ли паромных переправ (по умолчаниюfalse).avoidLockedRoads: избегать ли закрытых для проезда дорог (по умолчаниюtrue).routeSearchType: способ учёта данных о пробках при построении маршрута. Вы можете строить маршрут с учётом реальных (JAM) или статистических (STATISTIC) данных о пробках или построить кратчайший по расстоянию маршрут, даже если он не является оптимальным по времени (SHORTEST).excludedAreas: список областей (не более 25), которые следует избегать при построении маршрута. Подробнее см. в разделе Исключение областей ниже.
val carOptions = CarRouteSearchOptions(
avoidTollRoads = true,
avoidUnpavedRoads = true,
avoidFerries = true,
avoidLockedRoads = true,
routeSearchType = RouteSearchType.JAM,
excludedAreas = listOf()
)
val routeSearchOptions = RouteSearchOptions(car = carOptions)
Передайте готовые параметры routeSearchOptions в вызов функции findRoute() при построении маршрута.
Для такси
Чтобы построить маршрут для такси, укажите свойство taxi в RouteSearchOptions.
Дополнительно вы можете настроить параметры построения маршрута TaxiRouteSearchOptions. Для поиска маршрута для такси нужно сначала задать параметры поиска обычных автомобильных маршрутов, а затем переиспользовать их в параметре car:
val taxiOptions = TaxiRouteSearchOptions(
car = carOptions
)
val routeSearchOptions = RouteSearchOptions(taxi = taxiOptions)
Передайте готовые параметры routeSearchOptions в вызов функции findRoute() при построении маршрута.
Для грузового транспорта
Чтобы построить маршрут для грузового транспорта, укажите свойство truck в RouteSearchOptions. Дополнительно вы можете настроить параметры построения маршрута TruckRouteSearchOptions:
car: базовые параметры поиска любых автомобильных маршрутов: см. параметры поиска маршрута для автомобилей.truckLength: длина грузовика в миллиметрах.truckHeight: высота грузовика в миллиметрах.truckWidth: ширина грузовика в миллиметрах.actualMass: фактическая масса грузовика в килограммах.maxPermittedMass: разрешённая максимальная масса грузовика в килограммах.axleLoad: нагрузка на ось в килограммах.dangerousCargo: перевозится ли опасный груз (по умолчаниюfalse).explosiveCargo: перевозятся ли взрывчатые вещества в грузе (по умолчаниюfalse).passIds: список идентификаторов пропусков, которые разрешают движение грузового транспорта в пропускных зонах (TruckPassZonePassId).fallbackOnCar: переключаться ли на поиск маршрута для легкового автомобиля, если по заданным параметрам невозможно найти грузовой маршрут (по умолчаниюfalse).
val truckOptions = TruckRouteSearchOptions(
car = carOptions,
truckLength = 12000, // 12 метров
truckHeight = 4200, // 4,2 метра
truckWidth = 2500, // 2,5 метра
actualMass = 18000, // 18 тонн
maxPermittedMass = 20000, // 20 тонн
axleLoad = 8000, // 8 тонн
dangerousCargo = true,
explosiveCargo = false,
passIds = setOf(),
fallbackOnCar = true
)
val routeSearchOptions = RouteSearchOptions(truck = truckOptions)
Передайте готовые параметры routeSearchOptions в вызов функции findRoute() при построении маршрута.
Для построения маршрутов для грузового транспорта используются только онлайн-данные. В офлайн-режиме маршруты не строятся.
Для общественного транспорта
Чтобы построить маршрут для проезда на общественном транспорте, укажите свойство publicTransport в RouteSearchOptions. Дополнительно вы можете настроить параметры построения маршрута PublicTransportRouteSearchOptions:
startTime: время старта маршрута в UTC. Если не указано, используется текущее время.useSchedule: учитывать ли расписание движения общественного транспорта.transportTypes: список типов общественного транспорта, которые могут быть использованы для проезда по маршруту. Если список пустой, маршрут будет строиться для всех поддерживаемых типов транспорта. Полный список типов см. в PublicTransportType.
val publicTransportOptions = PublicTransportRouteSearchOptions(
startTime = TimePoint.now(),
useSchedule = true,
transportTypes = EnumSet.of(
PublicTransportType.BUS, // Автобус
PublicTransportType.TROLLEYBUS, // Троллейбус
PublicTransportType.TRAM, // Трамвай
PublicTransportType.METRO, // Метро
PublicTransportType.SUBURBAN_TRAIN // Пригородные поезда
)
)
val routeSearchOptions = RouteSearchOptions(publicTransport = publicTransportOptions)
Передайте готовые параметры routeSearchOptions в вызов функции findRoute() при построении маршрута.
Для велосипедов
Чтобы построить маршрут для велосипеда, укажите свойство bicycle в RouteSearchOptions. Дополнительно вы можете настроить параметры построения маршрута BicycleRouteSearchOptions:
avoidCarRoads: избегать ли автомобильных дорог (по умолчаниюfalse).avoidStairways: избегать ли лестниц (по умолчаниюfalse).avoidUnderpassesAndOverpasses: избегать ли подземных и надземных переходов (по умолчаниюfalse).excludedAreas: список областей (не более 25), которые следует избегать при построении маршрута. Подробнее см. в разделе Исключение областей ниже.
val bicycleOptions = BicycleRouteSearchOptions(
avoidCarRoads = true,
avoidStairways = true,
avoidUnderpassesAndOverpasses = true,
excludedAreas = listOf()
)
val routeSearchOptions = RouteSearchOptions(bicycle = bicycleOptions)
Передайте готовые параметры routeSearchOptions в вызов функции findRoute() при построении маршрута.
Для самокатов
Чтобы построить маршрут для самоката, укажите свойство scooter в RouteSearchOptions. Дополнительно вы можете настроить параметры построения маршрута ScooterRouteSearchOptions:
avoidCarRoads: избегать ли автомобильных дорог (по умолчаниюtrue).avoidStairways: избегать ли лестниц (по умолчаниюtrue).avoidUnderpassesAndOverpasses: избегать ли подземных и надземных переходов (по умолчаниюtrue).excludedAreas: список областей (не более 25), которые следует избегать при построении маршрута. Подробнее см. в разделе Исключение областей ниже.
val scooterOptions = ScooterRouteSearchOptions(
avoidCarRoads = true,
avoidStairways = true,
avoidUnderpassesAndOverpasses = true,
excludedAreas = listOf()
)
val routeSearchOptions = RouteSearchOptions(scooter = scooterOptions)
Передайте готовые параметры routeSearchOptions в вызов функции findRoute() при построении маршрута.
Для пешеходов
Пешеходные маршруты могут включать в себя перемещения внутри зданий (например, вы можете построить маршрут до определённого магазина в торговом центре). Если одна из точек маршрута находится внутри здания, для неё необходимо указать дополнительные параметры objectId (идентификатор объекта, к которому нужно проложить маршрут) и levelId (идентификатор этажа здания, на котором находится объект).
val indoorPoint = RouteSearchPoint(
coordinates = GeoPoint(latitude = 55.752425, longitude = 37.613983),
objectId = DgisObjectId(objectId = 67890, entranceId = 2),
levelId = LevelId(value = 3)
)
Подробнее о ведении по маршруту внутри зданий см. в разделе Навигация.
Чтобы построить пешеходный маршрут, укажите свойство pedestrian в RouteSearchOptions. Дополнительно вы можете настроить параметры построения маршрута PedestrianRouteSearchOptions:
avoidStairways: избегать ли лестниц (по умолчаниюfalse).avoidUnderpassesAndOverpasses: избегать ли подземных и надземных переходов (по умолчаниюfalse).useIndoor: строить ли маршруты внутри зданий (по умолчаниюtrue).excludedAreas: список областей (не более 25), которые следует избегать при построении маршрута. Подробнее см. в разделе Исключение областей ниже.
val pedestrianOptions = PedestrianRouteSearchOptions(
avoidStairways = true,
avoidUnderpassesAndOverpasses = true,
useIndoor = false,
excludedAreas = listOf()
)
val routeSearchOptions = RouteSearchOptions(pedestrian = pedestrianOptions)
Передайте готовые параметры routeSearchOptions в вызов функции findRoute() при построении маршрута.
Исключение областей
Чтобы исключить определённую область при построении маршрута, создайте объект ExcludedArea со следующими параметрами:
type: геометрическая форма исключаемой области. Список возможных значений см. в ExcludedAreaType.severity: приоритет исключения области (насколько важно её избегать). Список возможных значений см. в ExcludedAreaSeverity.extent: размер исключаемой области (не более 25 км).points: координаты точек исключаемой области типа GeoPoint (не более 500).
Пример исключаемой области в форме многоугольника:
// Вершины многоугольника
val points = listOf(
GeoPoint(latitude = 55.759909, longitude = 37.618806),
GeoPoint(latitude = 55.752425, longitude = 37.613983),
GeoPoint(latitude = 55.753567, longitude = 37.622995),
GeoPoint(latitude = 55.760523, longitude = 37.625613)
)
val polygonExcludedArea = ExcludedArea(
type = ExcludedAreaType.POLYGON,
severity = ExcludedAreaSeverity.HARD,
extent = RouteDistance(500.0),
points = points
)
Готовый маршрут
Вы можете предварительно создать маршрут с помощью Routing API и сохранить его для использования в мобильном SDK. Сохранённый маршрут доступен для использования в течение 24 часов. Маршруты для общественного транспорта недоступны для сохранения.
-
Создайте маршрут с помощью Routing API, сохраните его и скопируйте идентификатор маршрута: см. Сохранение маршрута.
-
Вызовите метод fetchSharedRoute() и передайте идентификатор сохранённого маршрута.
val routeId = "ROUTE_ID"
val trafficRouter = TrafficRouter(sdkContext)
val sharedRouteFuture = trafficRouter.fetchSharedRoute(routeId)Вызов вернёт отложенный результат с объектом SharedRouteData, который содержит набор маршрутов (
List<TrafficRoute>), точки маршрута и параметры поиска. -
Чтобы отобразить маршрут на карте, создайте объекты RouteMapObject на основе полученных объектов
TrafficRouteи добавьте их в источник данных RouteMapObjectSource.// Создаём источник данных
val routeMapObjectSource = RouteMapObjectSource(sdkContext, RouteVisualizationType.NORMAL)
map.addSource(routeMapObjectSource)
// Добавляем полученный маршрут на карту
sharedRouteFuture.onResult { sharedRouteData: SharedRouteData ->
var isActive = true
var routeIndex = 0
for (route in sharedRouteData.routes) {
routeMapObjectSource.addObject(
RouteMapObject(route, isActive, routeIndex)
)
isActive = false
routeIndex++
}
}
Офлайн-режим
По умолчанию построение маршрута работает в гибридном режиме: в первую очередь используются данные с серверов 2ГИС. Если за определённое время не удаётся построить маршрут на онлайн-данных, используются предварительно загруженные данные, если они есть.
Чтобы загрузить данные для работы офлайн, необходимо получить соответствующие права в ключе доступа и скачать необходимые территории. См. подготовительные шаги к работе с офлайн-данными.
Следующие функции доступны только в онлайн-режиме:
- Построение маршрута для грузового транспорта.
- Использование готового маршрута, который был построен ранее с помощью Routing API.