Перейти к основному содержимому

Справочник

Вы можете искать объекты в справочнике 2ГИС, обрабатывать результаты поиска, а также использовать подсказки для уточнения поисковых запросов. В справочнике вы можете найти информацию по объектам следующих типов:

  • компании и их филиалы;
  • здания;
  • парковки;
  • остановки общественного транспорта и станции метро;
  • дороги (улицы, перекрёстки, проезды);
  • населённые пункты разного размера (страны, города, регионы, деревни, микрорайоны и т.д.);
  • различные площадные объекты (парки, пляжи и т.д.).

Полный список доступных типов объектов см. в описании класса ObjectType.


Чтобы начать работу со справочником:

  1. Создайте поисковый движок.
  2. Сформируйте поисковый запрос.
  3. Получите, обработайте и отобразите на карте результаты поиска.

Создание поисковика

Для поиска объектов в справочнике создайте объект SearchManager и вызовите один из методов, который определяет режим работы справочника:

  • SearchManager.createOnlineManager() — создаёт онлайн-справочник.
  • SearchManager.createOfflineManager() — создаёт офлайн-справочник, работающий только с предзагруженными данными.
  • SearchManager.createSmartManager() — создаёт комбинированный справочник, работающий с онлайн-данными при наличии сети и с предзагруженными данными при отсутствии сети.

Важно

Некоторые методы работают только в определённом режиме справочника.

Пример создания поисковика с онлайн-справочником:

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

final SearchManager searchManager = sdk.SearchManager.createOnlineManager(context);

Формирование поискового запроса

Чтобы отправить поисковый запрос, создайте объект SearchQuery с помощью SearchQueryBuilder и передайте его в метод search().

Поисковый запрос должен состоять из трёх логических компонентов:

  • Запрос для поиска объекта (что нужно искать?). Вы можете сформулировать запрос с помощью одного из методов ниже:

    • Из текстовой строки с помощью метода fromQueryText(). Вы можете сформулировать текстовый запрос для поиска конкретного объекта (храм Василия Блаженного) или для получения списка множества объектов по критерию (магазины музыкальных инструментов).

    • По идентификаторам рубрик с помощью метода fromRubricIds() или в сочетании с текстовой строкой с помощью метода fromQueryTextAndRubricIds(). Этот способ полезен для создания выборки объектов определённого типа.

    • По идентификатору:

      • Организации с помощью метода fromOrgId(). Если у компании несколько филиалов, в ответе будут перечислены все точки.
      • Здания с помощью метода fromBuildingId().
      • Любого объекта с помощью метода поискового движка searchById().
  • Геоограничение поиска (где нужно искать?). Вы можете ограничить зону поиска с помощью одного из методов ниже:

    • Поиск внутри полигона: задайте координаты с помощью метода setSpatialRestriction().

    • Поиск в прямоугольной области интереса: задайте координаты с помощью метода setAreaOfInterest(). Этот метод задаёт приоритетную зону поиска, но не ограничивает поиск строго: если внутри области интереса результаты не найдены, поиск продолжится за пределами области.

    • Поиск в радиусе вокруг точки: задайте центр поиска с помощью метода setGeoPoint() или fromGeoPoint() и, если необходимо, радиус поиска с помощью метода setRadius().

      Метод fromGeoPoint() работает только в режиме поиска онлайн.

    • Произвольный запрос: если запрос для поиска объекта сформирован с помощью метода fromQueryText(), вы можете в этом же тексте указать и геоограничение (цветы у Бауманской).

  • (Необязательный компонент) Дополнительные ограничения результатов поиска с помощью одного или нескольких методов ниже:

    • Поиск объектов только определённого типа: перечислите интересующие вас типы объектов с помощью метода setAllowedResultTypes() (например, только здания).
    • Фильтрация результатов: задайте критерий фильтрации с помощью метода setDirectoryFilter() (например, по времени работы).
    • Сортировка результатов: задайте критерий сортировки с помощью метода setSortingType() (например, по рейтингу).
    • Количество результатов на странице: задайте ограничение с помощью метода setPageSize().
    • Локаль для поискового запроса: задайте язык и регион с помощью метода setLocale().

Примеры

  • Найти рестораны итальянской кухни в Пресненском районе Москвы, которые открыты сейчас, с сортировкой по рейтингу:

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

    // Создаём фильтр по времени работы
    final filter = sdk.DirectoryFilter(
    workTime: sdk.WorkTimeFilter.isOpenNow(const sdk.IsOpenNow()), // оставить только открытые сейчас объекты
    dynamic_: [],
    );

    final searchQuery = sdk.SearchQueryBuilder
    .fromQueryText("рестораны итальянской кухни в Пресненском районе Москвы")
    .setDirectoryFilter(filter) // фильтрация по времени работы
    .setSortingType(sdk.SortingType.byRating) // сортировка по рейтингу
    .setPageSize(10) // максимум 10 объектов на странице результатов
    .build();
  • Найти все парковки в радиусе 1 км с сортировкой по удалённости:

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

    final searchQuery = sdk.SearchQueryBuilder
    .fromQueryText('Парковки')
    .setAllowedResultTypes([sdk.ObjectType.parking]) // только парковки
    .setGeoPoint(const sdk.GeoPoint(latitude: sdk.Latitude(59.936), longitude: sdk.Longitude(30.351))) // центр поиска
    .setRadius(const sdk.Meter(1000)) // радиус поиска
    .setSortingType(sdk.SortingType.byDistance) // сортировка по удалённости
    .build();
  • Найти все населённые пункты (города, деревни, посёлки и т.д.) внутри полигона:

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

    // Создаём область поиска в виде полигона
    final polygon = [
    const sdk.GeoPoint(
    latitude: sdk.Latitude(55.751244),
    longitude: sdk.Longitude(37.618423),
    ),
    const sdk.GeoPoint(
    latitude: sdk.Latitude(55.751244),
    longitude: sdk.Longitude(37.618423),
    ),
    const sdk.GeoPoint(
    latitude: sdk.Latitude(55.751244),
    longitude: sdk.Longitude(37.618423),
    ),
    const sdk.GeoPoint(
    latitude: sdk.Latitude(55.751244),
    longitude: sdk.Longitude(37.618423),
    ),
    ];

    final searchQuery = sdk.SearchQueryBuilder.fromQueryText('название города')
    .setAllowedResultTypes([
    sdk.ObjectType.admDivCity,
    sdk.ObjectType.admDivSettlement,
    ]) // только города и мелкие населённые пункты
    .setSpatialRestriction(polygon) // область поиска
    .build();
  • Найти все объекты, которые оказывают услуги печати документов, в области интереса:

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

    // Создаём прямоугольную область интереса по координатам двух углов
    const areaOfInterest = sdk.GeoRect(
    southWestPoint: sdk.GeoPoint(
    latitude: sdk.Latitude(59.931),
    longitude: sdk.Longitude(30.344),
    ), // юго-западный угол
    northEastPoint: sdk.GeoPoint(
    latitude: sdk.Latitude(59.936),
    longitude: sdk.Longitude(30.351),
    ), // северо-восточный угол
    );

    final searchQuery =
    sdk.SearchQueryBuilder.fromQueryText('печать документов')
    .setAreaOfInterest(areaOfInterest)
    .build();
  • Найти все компании по адресу «Новосибирск, площадь Карла Маркса, 7»:

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

    final searchQuery = sdk.SearchQueryBuilder
    .fromQueryText('Новосибирск, площадь Карла Маркса, 7')
    .setAllowedResultTypes([sdk.ObjectType.branch]) // только компании
    .setPageSize(10) // максимум 10 объектов на странице результатов
    .build();
  • Найти все филиалы компании по известному идентификатору:

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

    const id = 4504136498310300;

    final searchQuery = sdk.SearchQueryBuilder
    .fromOrgId(const sdk.OrgId(id))
    .build();
  • Найти конкретный объект по известному идентификатору:

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

    const id = 70000001035164789;

    searchManager.searchById('id');

Геокодирование

С помощью SDK вы можете решать задачи геокодирования: определять координаты объекта на карте по его адресу (прямое геокодирование) и наоборот, определять адрес объекта на карте по его координатам (обратное геокодирование).

Прямое геокодирование

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

  • Адрес в текстовом запросе с помощью метода fromQueryText().

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

  • (Рекомендуется) Тип объекта, координаты которого нужно получить, с помощью метода setAllowedResultTypes().

Например, чтобы получить координаты здания по адресу «Москва, ул. Тверская 19а»:

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

final searchQuery = sdk.SearchQueryBuilder
.fromQueryText('Москва, ул. Тверская 19а')
.setAllowedResultTypes([sdk.ObjectType.building])
.build();

В результате поиска вы получите объект справочника DirectoryObject. Координаты объекта будут представлены в поле markerPosition в виде объекта GeoPointWithElevation. Пример:

markerPosition:
GeoPointWithElevation(
latitude: Latitude(value: 55.7659),
longitude: Longitude(value: 37.602827),
elevation: Elevation(value: 18.0),
),

Подробнее о другой информации в результатах поиска см. в разделе Структура данных объекта.

Обратное геокодирование

Чтобы получить адрес объекта по его координатам, сформируйте поисковый запрос, указав координаты объекта с помощью метода setGeoPoint() или fromGeoPoint().

Например, найти адрес объекта по координатам 55.7659, 37.602827:

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

final searchQuery = sdk.SearchQueryBuilder
.fromGeoPoint(const sdk.GeoPoint(latitude: sdk.Latitude(55.7659), longitude: sdk.Longitude(37.602827)))
.build();

В результате поиска вы получите объект справочника DirectoryObject. Адрес объекта будет представлен в поле address в виде объекта Address. Пример:

address:
Address(
drillDown: [
AddressAdmDiv(type: 'country', name: 'Россия'),
AddressAdmDiv(type: 'region', name: 'Москва'),
AddressAdmDiv(type: 'city', name: 'Москва'),
AddressAdmDiv(type: 'district', name: 'Тверской'),
],
components: [
AddressComponent(
AddressStreet(
street: 'Тверская улица',
number: '19а',
fiasCode: null,
),
),
],
buildingName: null,
buildingId: BuildingId(value: 4504235282747324),
postCode: '125009',
buildingCode: null,
fiasCode: null,
addressComment: '1-2 этаж',
),

Подробнее о другой информации в результатах поиска см. в разделе Структура данных объекта.

Изменение параметров поиска

Вы можете изменять или дополнять параметры уже созданного поискового запроса. Для этого создайте новый объект SearchQuery, укажите существующий запрос с помощью метода fromQuery() и укажите параметры, которые нужно дополнительно применить. Например, изменить тип сортировки результатов при поиске парковок:

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

// Создаём изначальный запрос
final searchQuery = sdk.SearchQueryBuilder
.fromQueryText('Парковки')
.setAllowedResultTypes([sdk.ObjectType.parking])
.setGeoPoint(const sdk.GeoPoint(latitude: sdk.Latitude(59.936), longitude: sdk.Longitude(30.351))) // центр поиска
.setRadius(const sdk.Meter(1000))
.setSortingType(sdk.SortingType.byDistance) // сортировка по удалённости
.build();

// Создаём новый запрос с другим типом сортировки
final searchQueryUpdated = sdk.SearchQueryBuilder
.fromQuery(searchQuery) // указание на изначальный запрос
.setSortingType(sdk.SortingType.byRating) // сортировка по рейтингу
.build();

Остальные параметры изначального запроса сохраняются.

Получение результатов поиска

Вызов метода search() возвращает отложенный результат SearchResult, содержащий список найденных объектов (DirectoryObject), разделенный на страницы:

final SearchResult result = await widget._searchManager.search(searchQuery).value;

final Page? searchPage = result.firstPage;

Чтобы получить следующую страницу результатов поиска, вызовите метод страницы fetchNextPage(), который вернёт отложенный результат Page:

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

final Page? nextPage = await searchPage?.fetchNextPage()?.value;

Отображение результатов на карте

Координаты всех найденных объектов возвращаются в поле itemMarkerInfos результата поиска SearchResult в виде списка элементов ItemMarkerInfo. Список может содержать не более 15000 элементов.

Чтобы отобразить на карте маркеры всех найденных объектов:

  1. Подготовьте список объектов Marker. Чтобы задать позицию маркера (параметр position), используйте координаты из поля ItemMarkerInfo.geoPoint.
  2. Добавьте готовый набор маркеров на карту с помощью метода addObjects() менеджера объектов MapObjectManager. Подробнее см. в инструкции Добавление нескольких объектов на карту.
import 'package:dgis_mobile_sdk/dgis.dart';

Future<void> displaySearchResultMarkers(sdk.Map map, sdk.SearchResult searchResult) async {
// Получаем список маркеров из результатов поиска
final loader = sdk.ImageLoader(sdkContext);
final markerInfos = await searchResult.itemMarkerInfos.value;
if (markerInfos == null) return;

// Создаём менеджер объектов для добавления маркеров на карту
final mapObjectManager = sdk.MapObjectManager(map);

// Подготавливаем список маркеров
final markers = markerInfos.map((itemMarkerInfo) async {
final position = itemMarkerInfo.geoPoint;

return sdk.Marker(
sdk.MarkerOptions(
position: position,
icon: await loader.loadPngFromAsset('assets/icons/marker_icon.png', 100, 100),
),
);
}).whereType<sdk.Marker>().toList();

// Добавляем маркеры на карту
mapObjectManager.addObjects(markers);
}

Структура данных объекта

Результаты поиска по справочнику представлены в виде списка объектов DirectoryObject с наборами свойств. В зависимости от типа объекта часть свойств может не содержать значений.

Важно

Получение некоторой информации об объектах в доступно только при дополнительной настройке ключа за отдельную плату: см. описания полей объектов DirectoryObject, Address и ItemMarkerInfo. Обратитесь в службу поддержки 2ГИС, чтобы обновить настройки вашего ключа доступа.

  • Основные свойства для классификации объекта:

    • Тип объекта (types) из ObjectType. Один объект может относиться к нескольким типам (например, ТЦ Сан Сити — это одновременно и филиал организации и здание). В этом случае все типы будут перечислены в списке, где первый элемент — основной тип объекта.
    • Название объекта (title) в зависимости от его типа: название организации, достопримечательности, географического объекта. Для жилых домов без названия — адрес.
    • Подтип объекта (subtitle) для уточнения. Например, кофейня как подтип организации или жилой дом как подтип здания.
    • Описание объекта (description).
    • Категории, к которым относится объект (rubricIds).
    • Идентификатор организации в справочнике и информация о ней (orgInfo). Для компаний с множеством филиалов — информация о головной организации.
    • (Данные по запросу) Объединение объектов разного типа в одной карточке справочника (group). Подробнее см. ниже.
  • Уникальный идентификатор объекта в справочнике (id). Для компаний с множеством филиалов — идентификатор конкретного филиала.

  • Географические свойства:

    • Координаты для размещения маркера на карте (markerPosition).
    • Полный адрес объекта (address). Некоторые компоненты адреса доступны только по запросу: см. описание объекта Address.
    • (Данные по запросу) Информация об этаже здания, на котором расположен объект (levelId и buildingLevels). Актуально для компаний, которые расположены на определённом этаже многоэтажного здания.
    • (Данные по запросу) Информация о входах в объект (entrances) с координатами и другими данными. Актуально как для компаний и зданий, так и для других объектов с физически обозначенными входами (например, парков).
    • (Данные по запросу) Дополнительная информация для уточнения адреса (titleAddition). Например, номер подъезда или номер квартиры.
  • Время работы:

    • Смещение локального времени объекта от UTC в виде временной метки (timeZoneOffset). Например, 03:00:00 для часового пояса UTC+3.
    • Время работы (openingHours) в виде списка временных промежутков или флага круглосуточной работы. Актуально для компаний.
    • Текущий статус работы (workStatus).
  • Прочие данные:

    • (Данные по запросу) Информация о торговой лицензии организации (tradeLicense).
    • Контакты для связи с организацией (contactInfos): номер телефона, e-mail, ссылки на сайт и соцсети и другое.
    • Рейтинг объекта на основе отзывов пользователей (reviews).
    • Дополнительные свойства парковок (parkingInfo).
    • Дополнительные свойства электрозаправок (chargingStation).
    • Информация о здании (buildingInfo).

Объединение объектов

Некоторые геообъекты в справочнике могут быть представлены в виде группы объектов разного типа. Например, здание суда — это одновременно и отдельно стоящее здание, и организация внутри этого здания, то есть, два разных DirectoryObject с характеристиками здания и организации соответственно. Но поскольку эти DirectoryObject относятся к одному и тому же геообъекту, в их структуре данных содержатся ссылки друг на друга.

Информация о связанных объектах содержится в поле group в виде списка элементов GroupItem. Для каждого связанного объекта представлен его тип и идентификатор (DgisObjectId), который вы можете в дальнейшем использовать для обращения к этому объекту.

Доступ к данным в поле group предоставляется только при дополнительной настройке ключа за отдельную плату. Обратитесь в службу поддержки 2ГИС.

Пример наполнения поля group с одним связанным объектом:

group: [
GroupItem(
id: DgisObjectId(objectId: 70030076538159915, entranceId: 0),
type: ObjectType.attraction,
),
],

Примеры

Ниже представлены примеры DirectoryObject разных типов объектов справочника.

  • Филиал организации:

    DirectoryObject
    // Тип объекта — организация
    types: [ObjectType.branch],
    // Название организации
    title: 'Шоколадница',
    titleAddition: null,
    // Подтип организации — кофейня
    subtitle: 'Кофейня',
    // ID объекта (данного филиала организации)
    id: DgisObjectId(objectId: 4504128908451067, entranceId: 0),
    // Координаты маркера для размещения на карте
    markerPosition: GeoPointWithElevation(
    latitude: Latitude(value: 55.7659),
    longitude: Longitude(value: 37.602827),
    elevation: Elevation(value: 18.0),
    ),
    // Адрес организации — Москва, ул. Тверская 19а
    address: Address(
    drillDown: [
    AddressAdmDiv(type: 'country', name: 'Россия'),
    AddressAdmDiv(type: 'region', name: 'Москва'),
    AddressAdmDiv(type: 'city', name: 'Москва'),
    AddressAdmDiv(type: 'district', name: 'Тверской'),
    ],
    components: [
    AddressComponent(
    AddressStreet(
    street: 'Тверская улица',
    number: '19а',
    fiasCode: null,
    ),
    ),
    ],
    buildingName: null,
    buildingId: BuildingId(value: 4504235282747324),
    postCode: '125009',
    buildingCode: null,
    fiasCode: null,
    addressComment: '1-2 этаж',
    ),
    attributes: [],
    contextAttributes: [],
    // Локальный часовой пояс — UTC+3
    timeZoneOffset: Duration(hours: 3),
    // Время работы филиала: воскресенье-четверг с 7:00 до 23:00, пятница с 7:00 до 24:00, суббота — круглосуточно
    openingHours: OpeningHours(
    weekOpeningHours: [
    [
    WeekTimeInterval(
    startTime: WeekTime(weekDay: WeekDay.monday, time: DayTime(hours: 7, minutes: 0)),
    finishTime: WeekTime(weekDay: WeekDay.monday, time: DayTime(hours: 23, minutes: 0)),
    ),
    ],
    [
    WeekTimeInterval(
    startTime: WeekTime(weekDay: WeekDay.tuesday, time: DayTime(hours: 7, minutes: 0)),
    finishTime: WeekTime(weekDay: WeekDay.tuesday, time: DayTime(hours: 23, minutes: 0)),
    ),
    ],
    [
    WeekTimeInterval(
    startTime: WeekTime(weekDay: WeekDay.wednesday, time: DayTime(hours: 7, minutes: 0)),
    finishTime: WeekTime(weekDay: WeekDay.wednesday, time: DayTime(hours: 23, minutes: 0)),
    ),
    ],
    [
    WeekTimeInterval(
    startTime: WeekTime(weekDay: WeekDay.thursday, time: DayTime(hours: 7, minutes: 0)),
    finishTime: WeekTime(weekDay: WeekDay.thursday, time: DayTime(hours: 23, minutes: 0)),
    ),
    ],
    [
    WeekTimeInterval(
    startTime: WeekTime(weekDay: WeekDay.friday, time: DayTime(hours: 7, minutes: 0)),
    finishTime: WeekTime(weekDay: WeekDay.friday, time: DayTime(hours: 24, minutes: 0)),
    ),
    ],
    [
    WeekTimeInterval(
    startTime: WeekTime(weekDay: WeekDay.saturday, time: DayTime(hours: 0, minutes: 0)),
    finishTime: WeekTime(weekDay: WeekDay.saturday, time: DayTime(hours: 24, minutes: 0)),
    ),
    ],
    [
    WeekTimeInterval(
    startTime: WeekTime(weekDay: WeekDay.sunday, time: DayTime(hours: 0, minutes: 0)),
    finishTime: WeekTime(weekDay: WeekDay.sunday, time: DayTime(hours: 23, minutes: 0)),
    ),
    ],
    ],
    isOpen24x7: false,
    ),
    contactInfos: [],
    // Рейтинг 3.4 на основе 85 отзывов
    reviews: Reviews(rating: 3.4, count: 85),
    parkingInfo: null,
    // В данный момент филиал открыт и работает до 23:00
    workStatus: WorkStatus(isOpen: true, description: 'Открыто до 23:00'),
    levelId: null,
    buildingLevels: null,
    // У организации один вход
    entrances: [
    EntranceInfo(
    id: DgisObjectId(objectId: 4504128908451067, entranceId: 70030076156031010),
    buildingNumber: null,
    porchName: null,
    porchNumber: null,
    apartmentRanges: [],
    geometry: EntranceGeometry(
    entrancePoints: [
    GeoPoint(
    latitude: Latitude(value: 55.76590646318491),
    longitude: Longitude(value: 37.60283837242394),
    ),
    ],
    entrancePolylines: [
    [
    GeoPoint(
    latitude: Latitude(value: 55.765971),
    longitude: Longitude(value: 37.602949),
    ),
    GeoPoint(
    latitude: Latitude(value: 55.765906),
    longitude: Longitude(value: 37.602838),
    ),
    ],
    ],
    ),
    ),
    ],
    chargingStation: null,
    // Объект относится к трём категориям
    rubricIds: [
    RubricId(value: 162),
    RubricId(value: 1203),
    RubricId(value: 161),
    ],
    // Информация о головной организации и общем количестве филиалов
    orgInfo: OrgInfo(
    branchCount: 225,
    id: OrgId(value: 4504136498310300),
    name: 'Шоколадница, кофейня',
    ),
    group: [],
  • Жилое здание:

    DirectoryObject
    // Тип объекта — здание
    types: [ObjectType.building],
    // Название объекта — адрес здания
    title: '2-я Черногрязская улица, 1',
    titleAddition: null,
    // Подтип объекта — жилой дом
    subtitle: 'Жилой дом',
    // ID объекта
    id: DgisObjectId(objectId: 4504235282792806, entranceId: 0),
    // Координаты маркера для размещения на карте
    markerPosition: GeoPointWithElevation(
    latitude: Latitude(value: 55.760651),
    longitude: Longitude(value: 37.545995),
    elevation: Elevation(value: 3.0),
    ),
    // Адрес объекта — Москва, 2-я Черногрязская улица 1
    address: Address(
    drillDown: [
    AddressAdmDiv(type: 'country', name: 'Россия'),
    AddressAdmDiv(type: 'region', name: 'Москва'),
    AddressAdmDiv(type: 'city', name: 'Москва'),
    AddressAdmDiv(type: 'district', name: 'Пресненский'),
    ],
    components: [
    AddressComponent(
    AddressStreet(
    street: '2-я Черногрязская улица',
    number: '1',
    fiasCode: '91e0431b-5721-40b9-8bf0-5eb5377063a8',
    ),
    ),
    ],
    buildingName: null,
    buildingId: BuildingId(value: 4504235282792806),
    postCode: '123100',
    buildingCode: null,
    fiasCode: null,
    addressComment: null,
    ),
    attributes: [],
    contextAttributes: [],
    timeZoneOffset: null,
    openingHours: null,
    contactInfos: [],
    // Нет отзывов об объекте для подсчёта рейтинга
    reviews: Reviews(rating: 0.0, count: 0),
    parkingInfo: null,
    workStatus: WorkStatus(isOpen: false, description: ''),
    levelId: null,
    buildingLevels: null,
    // У жилого здания два входа
    entrances: [
    EntranceInfo(
    id: DgisObjectId(objectId: 4504235282792806, entranceId: 4504643304435799),
    buildingNumber: null,
    porchName: null,
    porchNumber: null,
    apartmentRanges: [],
    geometry: EntranceGeometry(
    entrancePoints: [
    GeoPoint(
    latitude: Latitude(value: 55.76073452440514),
    longitude: Longitude(value: 37.54591428882596),
    ),
    ],
    entrancePolylines: [
    [
    GeoPoint(
    latitude: Latitude(value: 55.760822),
    longitude: Longitude(value: 37.545949),
    ),
    GeoPoint(
    latitude: Latitude(value: 55.760735),
    longitude: Longitude(value: 37.545914),
    ),
    ],
    ],
    ),
    ),
    EntranceInfo(
    id: DgisObjectId(objectId: 4504235282792806, entranceId: 70030076156588095),
    buildingNumber: null,
    porchName: '1 подъезд',
    porchNumber: 1,
    apartmentRanges: [
    ApartmentRange(start: 1, end: 80),
    ],
    geometry: EntranceGeometry(
    entrancePoints: [
    GeoPoint(
    latitude: Latitude(value: 55.7605167221199),
    longitude: Longitude(value: 37.54581996572112),
    ),
    ],
    entrancePolylines: [
    [
    GeoPoint(
    latitude: Latitude(value: 55.760497),
    longitude: Longitude(value: 37.545975),
    ),
    GeoPoint(
    latitude: Latitude(value: 55.760517),
    longitude: Longitude(value: 37.54582),
    ),
    ],
    ],
    ),
    ),
    ],
    chargingStation: null,
    rubricIds: [],
    orgInfo: null,
    group: [],
  • Улица:

    DirectoryObject
    // Тип объекта — улица
    types: [ObjectType.street],
    // Название объекта
    title: 'Улица Петрова',
    titleAddition: null,
    // Подтип объекта — улица
    subtitle: 'Street',
    // ID объекта
    id: DgisObjectId(objectId: 4504338361766218, entranceId: 0),
    // Координаты маркера для размещения на карте
    markerPosition: GeoPointWithElevation(
    latitude: Latitude(value: 55.643536),
    longitude: Longitude(value: 38.053038),
    elevation: Elevation(value: 0.0),
    ),
    // Адрес объекта — Московская область, пгт Удельная
    address: Address(
    drillDown: [
    AddressAdmDiv(type: 'country', name: 'Россия'),
    AddressAdmDiv(type: 'region', name: 'Московская область'),
    AddressAdmDiv(type: 'district_area', name: 'Раменский муниципальный округ'),
    AddressAdmDiv(type: 'settlement', name: 'пгт Удельная'),
    ],
    components: [],
    buildingName: null,
    buildingId: null,
    postCode: null,
    buildingCode: null,
    fiasCode: '0d8e2b4c-eef7-4176-bbec-be9ac0ace587',
    addressComment: null,
    ),
    attributes: [],
    contextAttributes: [],
    timeZoneOffset: null,
    openingHours: null,
    contactInfos: [],
    reviews: null,
    parkingInfo: null,
    workStatus: WorkStatus(isOpen: false, description: ''),
    levelId: null,
    buildingLevels: null,
    entrances: [],
    chargingStation: null,
    rubricIds: [],
    orgInfo: null,
    group: [],
  • Площадной объект (парк):

    DirectoryObject
    // Основной тип объекта — площадной объект, дополнительный — достопримечательность
    types: [ObjectType.admDivPlace, ObjectType.attraction],
    // Название объекта
    title: 'Парк "Красногвардейские пруды"',
    titleAddition: null,
    // Подтип объекта — место
    subtitle: 'Место',
    // ID объекта
    id: DgisObjectId(objectId: 4504286822138295, entranceId: 0),
    // Координаты маркера для размещения на карте
    markerPosition: GeoPointWithElevation(
    latitude: Latitude(value: 55.756656),
    longitude: Longitude(value: 37.545756),
    elevation: Elevation(value: 0.0),
    ),
    // Адрес объекта — Москва
    address: Address(
    drillDown: [
    AddressAdmDiv(type: 'country', name: 'Россия'),
    AddressAdmDiv(type: 'region', name: 'Москва'),
    AddressAdmDiv(type: 'city', name: 'Москва'),
    ],
    components: [],
    buildingName: null,
    buildingId: null,
    postCode: null,
    buildingCode: null,
    fiasCode: null,
    addressComment: null,
    ),
    attributes: [],
    contextAttributes: [],
    timeZoneOffset: null,
    openingHours: null,
    contactInfos: [],
    // Рейтинг 4.8 на основе 62 отзывов
    reviews: Reviews(rating: 4.8, count: 62),
    parkingInfo: null,
    workStatus: WorkStatus(isOpen: false, description: ''),
    levelId: null,
    buildingLevels: null,
    entrances: [],
    chargingStation: null,
    // Объект относится к одной категории
    rubricIds: [RubricId(value: 168)],
    orgInfo: null,
    // Объект одновременно является и площадным объектом, и достопримечательностью
    group: [
    GroupItem(
    id: DgisObjectId(objectId: 70030076538159915, entranceId: 0),
    type: ObjectType.attraction,
    ),
    ],

Поисковые подсказки

Вы можете формировать подсказки для пользователей при текстовом поиске объектов. Для этого создайте объект SuggestQuery с помощью SuggestQueryBuilder и передайте его в метод suggest():

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

final SuggestQuery suggestQuery = sdk.SuggestQueryBuilder.fromQueryText(query).build();

final SuggestQuery = await searchManager.suggest(suggestQuery).value;

Вызов вернёт отложенный результат SuggestResult, содержащий список подсказок (Suggest). Подробнее о формировании подсказок см. в документации Suggest API.

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

Пример функции для применения всех типов обработчика:

void handleSuggestHandler(sdk.SuggestHandler handler) {
handler.match<void>(
objectHandler: (sdk.SuggestObjectHandler? value) {
print('Вернуть объект справочника: {value.item}');
},
performSearchHandler: (sdk.PerformSearchHandler? value) {
print('Вернуть объект поискового запроса: {value.searchQuery}');
},
incompleteTextHandler: (sdk.IncompleteTextHandler? value) {
print('Вернуть дополненный текст подсказки: ${value?.queryText}');
},
);
}

История поиска

Вы можете работать с историей поиска с помощью SearchHistory.

В истории поиска могут храниться элементы двух типов: объекты справочника (DirectoryObject) и поисковые запросы (SearchQueryWithInfo).

Добавление элементов в историю поиска

Вы можете добавить элементы в историю поиска в виде объектов SearchHistoryItem по одному или списком. Порядок элементов в списке сохранится при добавлении в историю.

  1. Создайте объект SearchHistoryItem и передайте ему один из следующих объектов в зависимости от типа добавляемого элемента:

    • Для поискового запроса: SearchQueryWithInfo с указанием нужного поискового запроса в параметре searchQuery. Дополнительно SearchQueryWithInfo может содержать заголовок и подзаголовок, которые отобразятся в выдаче истории поиска.

      // Создаём объект SearchQueryWithInfo
      final searchQueryWithInfo = sdk.SearchQueryWithInfo(
      searchQuery, // готовый поисковый запрос
      "Nearby Cafes",
      "Restaurants and cafes nearby",
      );

      final searchHistoryItem = sdk.SearchHistoryItem.searchQuery(searchQueryWithInfo);
      final searchHistoryItem = sdk.SearchHistoryItem.directoryObject(directoryObject);
  2. Создайте объект SearchHistory:

    final searchHistory = sdk.SearchHistory(sdkContext);
  3. Добавьте элементы в историю поиска по одному или списком с помощью методов addItem() или addItems() объекта SearchHistory соответственно:

    • Добавить один элемент:

      searchHistory.addItem(searchHistoryItem);
    • Добавить список элементов:

      searchHistory.addItems(searchHistoryItemsList);

Если в истории поиска уже существует добавленный элемент, более старый дубликат будет удалён.

Отображение истории поиска

Чтобы показать страницу поиска со списком элементов, создайте объект SearchHistoryPage и передайте его в метод items(). Дополнительно вы можете настроить следующие параметры:

  • Ограничить количество элементов на странице (параметр limit). Значение по умолчанию — 100.
  • Задать смещение относительно начала списка (параметр offset): сколько элементов с начала списка пропустить. Значение по умолчанию — 0 (смещение отсутствует, список отображается с самого начала).
  • Отфильтровать список по типу элементов (параметр filter). Доступные фильтры перечислены в SearchHistoryFilter. Например, чтобы показывать в истории только поисковые запросы, используйте значение searchQuery. По умолчанию фильтрация отсутствует.
// Создаём объект SearchHistory
final searchHistory = SearchHistory(sdkContext);

// Создаём страницу истории с лимитом 10 элементов и смещением 0
final page = sdk.SearchHistoryPage(
limit: 10, // Максимум 10 элементов на странице
filter: sdk.SearchHistoryFilterEnumSet(), // Без фильтров
);

// Получаем элементы страницы истории
searchHistory.items(page).then((result) {
for (final item in result.items) {
// Логируем каждый элемент истории
print('Элемент истории: $item');
}
});

Элементы на странице упорядочены по времени добавления в историю (от новых к старым).

Очистка истории поиска

Чтобы убрать отдельные элементы из истории поиска:

Чтобы очистить историю поиска полностью, используйте метод clear() объекта SearchHistory:

searchHistory.clear();

Подписка на изменения истории

Чтобы отслеживать изменения истории поиска (добавление и удаление элементов), вы можете подписаться на канал onHistoryChanged:

final searchHistory = SearchHistory(sdkContext);

searchHistory.onHistoryChanged.listen((changeType) {
switch (changeType) {
case sdk.ChangeType.add:
print('Элемент добавлен в историю');
break;
case sdk.ChangeType.remove:
print('Элемент удалён из истории');
break;
}
});

Информация о подъездах в справочнике

Вы можете искать адреса в справочнике с точностью до квартиры или подъезда.

Например, по запросу "Томск Кирова 17 кв 5" вы получите объект, который содержит информацию с точностью до подъезда.

DgisObjectId содержит два идентификатора:

  • objectId — стабильный числовой идентификатор объекта;
  • entranceId — стабильный числовой идентификатор входа/подъезда для объекта.

Если entranceId отличен от нуля, то результатом поиска является не просто дом, а конкретный подъезд в доме.

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

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

sdk.GeoPoint? getMarkerPosition(sdk.DirectoryObject directoryObject) {
final int entranceId = directoryObject.id?.entranceId ?? 0;
if (entranceId != 0) {
return directoryObject.entrances
.firstWhere((entrance) => entrance.id.entranceId == entranceId)
.geometry
?.entrancePoints
.firstOrNull ??
directoryObject.markerPosition?.point;
}
return null;
}