Маршруты | Mobile SDK | 2GIS Documentation
Flutter SDK

Маршруты

Для того, чтобы проложить маршрут на карте, нужно создать два объекта: TrafficRouter для поиска оптимального маршрута и источник данных RouteMapObjectSource для отображения маршрута на карте.

Чтобы найти маршрут между двумя точками, нужно вызвать метод findRoute(), передав координаты точек в виде объектов RouteSearchPoint. Дополнительно можно указать параметры маршрута (RouteSearchOptions), а также список промежуточных точек маршрута (список RouteSearchPoint).

import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;

final routeSearchOptions = sdk.RouteSearchOptions.car(sdk.CarRouteSearchOptions());
final startPoint = sdk.RouteSearchPoint(coordinates: GeoPoint(latitude: 55.759909, longitude: 37.618806));
final finishPoint = sdk.RouteSearchPoint(coordinates: GeoPoint(latitude: 55.752425, longitude: 37.613983));

final trafficRouter = sdk.TrafficRouter(sdkContext);
final routesFuture = trafficRouter.findRoute(startPoint, finishPoint, routeSearchOptions);

Вызов вернёт отложенный результат со списком объектов TrafficRoute. Чтобы отобразить найденный маршрут на карте, нужно на основе этих объектов создать объекты RouteMapObject и добавить их в источник данных RouteMapObjectSource.

import 'package:dgis_mobile_sdk_full/dgis.dart' as sdk;

// Создаём источник данных
final sdk.RouteMapObjectSource routeMapObjectSource = sdk.RouteMapObjectSource(sdkContext, RouteVisualizationType.NORMAL)
map.addSource(routeMapObjectSource)

// Ищем маршрут
final trafficRouter = sdk.TrafficRouter(sdkContext);
final List<sdk.TrafficRoute> routes = await trafficRouter.findRoute(startSearchPoint, finishSearchPoint).value;

// После получения маршрута добавляем его на карту
int routeIdx = 0;
bool isActive = true;
routes.forEach((sdk.TrafficRoute route) {
  routeMapObjectSource.addObject(sdk.RouteMapObject(route, isActive, routeIdx));
  routeIdx += 1;
  isActive = false;
})

Вместо пары TrafficRouter и RouteMapObjectSource для построения маршрута можно использовать RouteEditor и RouteEditorSource. В таком случае не нужно обрабатывать список TrafficRoute, достаточно передать координаты маршрута в виде объекта RouteEditorRouteParams в метод setRouteParams(), и маршрут отобразится автоматически.

final routeEditor = sdk.RouteEditor(sdkContext);
final routeEditorSource = sdk.RouteEditorSource(sdkContext, routeEditor);
map.addSource(routeEditorSource);

routeEditor.setRouteParams(
  sdk.RouteEditorRouteParams(
    startPoint: startPoint,
    finishPoint: finishPoint,
    routeSearchOptions: routeSearchOptions,
  ),
);

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

Можно получить координаты объекта (здания, дороги), который находится в месте клика. Для этого понадобится метод getRenderedObjects(). В нем нужно получить объект класса DgisMapObject, который имеет поле id. Этот идентификатор является стабильным числовым идентификатором объекта справочника, с помощью которого можно выполнить поисковый запрос и получить информацию об объекте, в том числе географические координаты его центра.

import 'package:dgis_mobile_sdk_map/dgis.dart' as sdk;

map.getRenderedObjects(sdk.ScreenPoint()).then((List<sdk.RenderedObjectInfo> info) {
  // Получим ближайший к месту нажатия объект внутри установленного радиуса
  final sdk.RenderedObject obj = info.first.item;

  // В этом примере мы хотим найти информацию о выбранном объекте в справочнике.
  // Для этого мы должны убедиться, что тип этого объекта может быть найден
  if (obj.source is sdk.DgisSource && obj.item is sdk.DgisMapObject) {
    final source = obj.source as sdk.DgisSource;

    // Произведем поиск
    final foundObject =
        await sdk.SearchManager.createOnlineManager(sdkContext)
            .searchByDirectoryObjectId((obj.item as sdk.DgisMapObject).id)
            .value;

    final sdk.GeoPoint? geoPoint = foundObject.markerPosition?.point;
  }
});

Важно

Нужно учитывать, что координаты центра для больших объектов (например, МКАД) могут находиться далеко за пределами области видимости камеры, так как полученный объект ничего не знает о том, где находится камера или место нажатия на карту. В случае с такими объектами лучше использовать другие способы получения координат.