Справочник
Вы можете искать объекты в справочнике 2ГИС, обрабатывать результаты поиска, а также использовать подсказки для уточнения поисковых запросов. В справочнике вы можете найти информацию по объектам следующих типов:
- компании и их филиалы;
- здания;
- парковки;
- остановки общественного транспорта и станции метро;
- дороги (улицы, перекрёстки, проезды);
- населённые пункты разного размера (страны, города, регионы, деревни, микрорайоны и т. д.);
- различные площадные объекты (парки, пляжи и т. д.).
Полный список доступных типов объектов см. в описании класса ObjectType.
Чтобы начать работу со справочником:
- Создайте поисковый движок.
- Сформируйте поисковый запрос.
- Получите, обработайте и отобразите на карте результаты поиска.
Создание поисковика
Для поиска объектов в справочнике создайте объект SearchManager и вызовите один из методов, который определяет режим работы справочника:
- SearchManager.createOnlineManager() — создаёт онлайн-справочник.
- SearchManager.createOfflineManager() — создаёт офлайн-справочник, работающий только с предзагруженными данными.
- SearchManager.createSmartManager() — создаёт комбинированный справочник, работающий с онлайн-данными при наличии сети и с предзагруженными данными при отсутствии сети.
Пример создания поискового движка с онлайн-справочником:
let searchManager = SearchManager.createOnlineManager(context: sdk.context)
Некоторые методы работают только в определённом режиме справочника. Возможные ограничения указаны в описании методов.
Формирование поискового запроса
Чтобы отправить поисковый запрос, создайте объект SearchQuery с помощью SearchQueryBuilder и передайте его в метод search().
Поисковый запрос должен состоять из трёх логических компонентов:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
-
Запрос для поиска объекта (что нужно искать?). Вы можете сформулировать запрос с помощью одного из методов ниже:
-
Из текстовой строки с помощью метода setQueryText(). Вы можете сформулировать текстовый запрос для поиска конкретного объекта (
храм Василия Блаженного) или для получения списка множества объектов по критерию (магазины музыкальных инструментов). -
По идентификаторам рубрик с помощью метода setRubricIds(). Этот способ полезен для создания выборки объектов определённого типа.
-
По идентификатору:
- Организации с помощью метода setOrgId(). Если у организации несколько филиалов, в ответе будут перечислены все точки.
- Зданий с помощью метода setBuildingIds().
- Любых объектов с помощью методов поискового движка searchByIds() и searchByDirectoryObjectIds().
-
-
Геоограничение поиска (где нужно искать?). Вы можете ограничить зону поиска с помощью одного из методов ниже:
- Поиск внутри полигона: задайте область поиска с помощью метода setRestrictionGeometry() и объекта PolygonGeometry.
- Поиск в прямоугольной области интереса: задайте координаты с помощью метода setAreaOfInterest(). Этот метод задаёт приоритетную зону поиска, но не ограничивает поиск строго: если внутри области интереса результаты не найдены, поиск продолжится за пределами области.
- Поиск в радиусе вокруг точки: задайте центр поиска с помощью метода setRestrictionGeometry() и объекта PointGeometry, а радиус — с помощью метода setRadius().
- Произвольный запрос: если запрос для поиска объекта сформирован с помощью метода setQueryText(), вы можете в этом же тексте указать и геоограничение (
цветы у Бауманской).
-
(Необязательный компонент) Дополнительные ограничения результатов поиска с помощью одного или нескольких методов ниже:
- Поиск объектов определённого типа: перечислите типы объектов с помощью метода setAllowedResultTypes() (например, только здания).
- Фильтрация результатов: задайте критерий фильтрации с помощью метода setDirectoryFilter() (например, по времени работы).
- Сортировка результатов: задайте критерий сортировки с помощью метода setSortingType() (например, по рейтингу).
- Количество результатов на странице: задайте ограничение с помощью метода setPageSize().
- Номер страницы поисковой выдачи: по умолчанию возвращается первая страница. Чтобы получить следующие страницы, используйте метод fetchNextPage().
- Локаль для поискового запроса: задайте язык и регион с помощью метода setLocale().
-
Запрос для поиска объекта (что нужно искать?). Вы можете сформулировать запрос с помощью одного из методов ниже:
-
Из текстовой строки с помощью метода fromQueryText(). Вы можете сформулировать текстовый запрос для поиска конкретного объекта (
храм Василия Блаженного) или для получения списка множества объектов по критерию (магазины музыкальных инструментов). -
По идентификаторам рубрик с помощью метода fromRubricIds() или в сочетании с текстовой строкой с помощью метода fromQueryTextAndRubricIds(). Этот способ полезен для создания выборки объектов определённого типа.
-
По идентификатору:
- Организации с помощью метода fromOrgId(). Если у организации несколько филиалов, в ответе будут перечислены все точки.
- Здания с помощью метода fromBuildingId().
- Любого объекта с помощью метода поискового движка searchById().
-
-
Геоограничение поиска (где нужно искать?). Вы можете ограничить зону поиска с помощью одного из методов ниже:
-
Поиск внутри полигона: задайте координаты с помощью метода setSpatialRestriction().
-
Поиск в прямоугольной области интереса: задайте координаты с помощью метода setAreaOfInterest(). Этот метод задаёт приоритетную зону поиска, но не ограничивает поиск строго: если внутри области интереса результаты не найдены, поиск продолжится за пределами области.
-
Поиск в радиусе вокруг точки: задайте центр поиска с помощью метода setGeoPoint() или fromGeoPoint() и, если необходимо, радиус поиска с помощью метода setRadius().
Метод fromGeoPoint() работает только в режиме поиска онлайн.
-
Произвольный запрос: если запрос для поиска объекта сформирован с помощью метода fromQueryText(), вы можете в этом же тексте указать и геоограничение (
цветы у Бауманской).
-
-
(Необязательный компонент) Дополнительные ограничения результатов поиска с помощью одного или нескольких методов ниже:
- Поиск объектов определённого типа: перечислите типы объектов с помощью метода setAllowedResultTypes() (например, только здания).
- Фильтрация результатов: задайте критерий фильтрации с помощью метода setDirectoryFilter() (например, по времени работы).
- Сортировка результатов: задайте критерий сортировки с помощью метода setSortingType() (например, по рейтингу).
- Количество результатов на странице: задайте ограничение с помощью метода setPageSize().
- Номер страницы поисковой выдачи: по умолчанию возвращается первая страница. Чтобы получить следующие страницы, используйте метод fetchNextPage().
- Локаль для поискового запроса: задайте язык и регион с помощью метода setLocale().
Примеры
-
Найти рестораны итальянской кухни в Пресненском районе Москвы, которые открыты сейчас, с сортировкой по рейтингу:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
// Создать фильтр по времени работыlet filter = DirectoryFilter(workTime: .isOpenNow(IsOpenNow()), // оставить только открытые сейчас объектыdynamic: [])let searchQuery = SearchQueryBuilder().setQueryText(queryText: "рестораны итальянской кухни в Пресненском районе Москвы").setDirectoryFilter(filter: filter) // фильтрация по времени работы.setSortingType(sortingType: .byRating) // сортировка по рейтингу.setPageSize(pageSize: 10) // максимум 10 объектов на странице результатов.build()// Создать фильтр по времени работыlet filter = DirectoryFilter(workTime: .openNow // оставить только открытые сейчас объекты)let searchQuery = SearchQueryBuilder.fromQueryText(queryText: "рестораны итальянской кухни в Пресненском районе Москвы").setDirectoryFilter(filter: filter) // фильтрация по времени работы.setSortingType(sortingType: .byRating) // сортировка по рейтингу.setPageSize(pageSize: 10) // максимум 10 объектов на странице результатов.build() -
Найти все парковки в радиусе 1 км с сортировкой по удалённости:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
let searchQuery = SearchQueryBuilder().setQueryText(queryText: "Парковки").setAllowedResultTypes(allowedResultTypes: [.parking]) // только парковки.setRestrictionGeometry(restrictionGeometry: PointGeometry(point: GeoPoint(latitude: 59.936, longitude: 30.351))) // центр поиска.setRadius(radius: Meter(value: 1000)) // радиус поиска.setSortingType(sortingType: .byDistance) // сортировка по удалённости.build()let searchQuery = SearchQueryBuilder.setAllowedResultTypes(allowedResultTypes: [.parking]) // только парковки.setGeoPoint(geoPoint: GeoPoint(latitude: 59.936, longitude: 30.351)) // центр поиска.setRadius(radius: Meter(value: 1000)) // радиус поиска.setSortingType(sortingType: .byDistance) // сортировка по удалённости.build() -
Найти все населённые пункты (города, деревни, посёлки и т.д.) внутри полигона:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
// Создать область поиска в виде полигонаlet polygon = [GeoPoint(latitude: 55.72014932919687, longitude: 37.562599182128906),GeoPoint(latitude: 55.72014932919687, longitude: 37.67555236816406),GeoPoint(latitude: 55.78004852149085, longitude: 37.67555236816406),GeoPoint(latitude: 55.78004852149085, longitude: 37.562599182128906)]let searchQuery = SearchQueryBuilder().setQueryText(queryText: "название города").setAllowedResultTypes(allowedResultTypes: [.admDivCity, .admDivSettlement]) // только города и мелкие населённые пункты.setRestrictionGeometry(restrictionGeometry: PolygonGeometry(contours: [polygon])) // область поиска.build()// Создать область поиска в виде полигонаlet polygon = [GeoPoint(latitude: 55.72014932919687, longitude: 37.562599182128906),GeoPoint(latitude: 55.72014932919687, longitude: 37.67555236816406),GeoPoint(latitude: 55.78004852149085, longitude: 37.67555236816406),GeoPoint(latitude: 55.78004852149085, longitude: 37.562599182128906)]let searchQuery = SearchQueryBuilder.setAllowedResultTypes(allowedResultTypes: [.admDivCity, .admDivSettlement]) // только города и мелкие населённые пункты.setSpatialRestriction(spatialRestriction: polygon) // область поиска.build() -
Найти все объекты, которые оказывают услуги печати документов, в области интереса:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
// Создать прямоугольную область интереса по координатам двух угловlet areaOfInterest = GeoRect(southWestPoint: GeoPoint(latitude: 59.931, longitude: 30.344), // юго-западный уголnorthEastPoint: GeoPoint(latitude: 59.936, longitude: 30.351) // северо-восточный угол)let searchQuery = SearchQueryBuilder().setQueryText(queryText: "печать документов").setAreaOfInterest(rect: areaOfInterest).build()// Создать прямоугольную область интереса по координатам двух угловlet areaOfInterest = GeoRect(southWestPoint: GeoPoint(latitude: 59.931, longitude: 30.344), // юго-западный уголnorthEastPoint: GeoPoint(latitude: 59.936, longitude: 30.351) // северо-восточный угол)let searchQuery = SearchQueryBuilder.fromQueryText(queryText: "печать документов").setAreaOfInterest(rect: areaOfInterest).build() -
Найти все компании по адресу «Новосибирск, площадь Карла Маркса, 7»:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
let searchQuery = SearchQueryBuilder().setQueryText(queryText: "Новосибирск, площадь Карла Маркса, 7").setAllowedResultTypes(allowedResultTypes: [.branch]) // только компании.setPageSize(pageSize: 10) // максимум 10 объектов на странице результатов.build()let searchQuery = SearchQueryBuilder.fromQueryText(queryText: "Новосибирск, площадь Карла Маркса, 7").setAllowedResultTypes(allowedResultTypes: [.branch]) // только компании.setPageSize(pageSize: 10) // максимум 10 объектов на странице результатов.build() -
Найти все филиалы компании по известному идентификатору:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
let orgId = OrgId(value: 4504136498310300)let searchQuery = SearchQueryBuilder().setOrgId(orgId: orgId).build()let id = 4504136498310300let searchQuery = SearchQueryBuilder.fromOrgId(orgId: id).build() -
Найти конкретный объект по известному идентификатору:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
- Для версии SDK 12.x
let id = "70000001035164789"searchManager.searchByIds(ids: [id]).sinkOnMainThread { objects inprint(objects.first?.title)} failure: { error inprint(error)}let id = 70000001035164789searchManager.searchById(id: id).sinkOnMainThread { object inprint(object?.title)} failure: { error inprint(error)}let id = 70000001035164789searchManager.searchById(id: id).sink { object inprint(object?.title)}
Геокодирование
С помощью SDK вы можете решать задачи геокодирования: определять координаты объекта на карте по его адресу (прямое геокодирование) и наоборот, определять адрес объекта на карте по его координатам (обратное геокодирование).
Прямое геокодирование
Чтобы получить координаты объекта по его адресу, сформируйте поисковый запрос, указав следующие данные:
-
Адрес в текстовом запросе:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
Используйте метод setQueryText().
Используйте метод fromQueryText().
Для более точных результатов укажите в тексте город (посёлок, деревню), где выполняется поиск. Название небольшого населённого пункта (например, деревни) рекомендуется указывать вместе с названием области и другими объединениями, к которым он относится (например, сельским или городским поселением).
-
(Рекомендуется) Тип объекта, координаты которого нужно получить, с помощью метода setAllowedResultTypes().
Например, чтобы получить координаты здания по адресу «Москва, ул. Тверская 19а»:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
let searchQuery = SearchQueryBuilder().setQueryText(queryText: "Москва, ул. Тверская 19а").setAllowedResultTypes(allowedResultTypes: [.building]).build()let searchQuery = SearchQueryBuilder.fromQueryText(queryText: "Москва, ул. Тверская 19а").setAllowedResultTypes(allowedResultTypes: [.building]).build()
В результате поиска вы получите объект справочника DirectoryObject. Координаты объекта будут представлены в поле markerPosition в виде объекта GeoPointWithElevation. Пример:
markerPosition:
GeoPointWithElevation(
latitude: Latitude(value: 55.7659),
longitude: Longitude(value: 37.602827),
elevation: Elevation(value: 18.0)
),
Подробнее о другой информации в результатах поиска см. в разделе Структура данных объекта.
Обратное геокодирование
Чтобы получить адрес объекта по его координатам, сформируйте поисковый запрос, указав координаты объекта.
Например, найти адрес объекта по координатам 55.7659, 37.602827:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
Используйте метод setRestrictionGeometry() и объект PointGeometry:
let searchQuery = SearchQueryBuilder()
.setRestrictionGeometry(restrictionGeometry: PointGeometry(point: GeoPoint(latitude: 55.7659, longitude: 37.602827)))
.build()
Используйте метод fromGeoPoint():
let searchQuery = SearchQueryBuilder
.fromGeoPoint(geoPoint: GeoPoint(latitude: 55.7659, 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: nil))
],
buildingName: nil,
buildingId: BuildingId(value: 4504235282747324),
postCode: "125009",
buildingCode: nil,
fiasCode: nil,
addressComment: "1-2 этаж"
),
Подробнее о другой информации в результатах поиска см. в разделе Структура данных объекта.
Изменение параметров поиска
Чтобы изменить или дополнить параметры созданного поискового запроса, создайте новый объект SearchQuery, укажите существующий запрос с помощью метода fromQuery() и укажите параметры, которые нужно дополнительно применить. Например, изменить тип сортировки результатов при поиске парковок:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
// Создать изначальный запрос
let searchQuery = SearchQueryBuilder()
.setRestrictionGeometry(restrictionGeometry: PointGeometry(point: GeoPoint(latitude: 59.936, longitude: 30.351)))
.setRadius(radius: Meter(value: 1000))
.setAllowedResultTypes(allowedResultTypes: [.parking])
.setSortingType(sortingType: .byDistance) // сортировка по удалённости
.build()
// Создать новый запрос с другим типом сортировки
let searchQueryUpdated = SearchQueryBuilder
.fromQuery(query: searchQuery) // указание на изначальный запрос
.setSortingType(sortingType: .byRating) // сортировка по рейтингу
.build()
// Создать изначальный запрос
let searchQuery = SearchQueryBuilder
.fromGeoPoint(geoPoint: GeoPoint(latitude: 59.936, longitude: 30.351))
.setRadius(radius: Meter(value: 1000))
.setAllowedResultTypes(allowedResultTypes: [.parking])
.setSortingType(sortingType: .byDistance) // сортировка по удалённости
.build()
// Создать новый запрос с другим типом сортировки
let searchQueryUpdated = SearchQueryBuilder
.fromQuery(query: searchQuery) // указание на изначальный запрос
.setSortingType(sortingType: .byRating) // сортировка по рейтингу
.build()
Остальные параметры изначального запроса сохраняются.
Получение результатов поиска
Вызов метода search() возвращает отложенный результат SearchResult, содержащий список найденных объектов (DirectoryObject), разделённый на страницы:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
- Для версии 12.x
searchManager.search(query: searchQuery).sinkOnMainThread { searchResult in
// Получить название первого объекта с первой страницы
let directoryObjectTitle = searchResult.firstPage?.items?.first?.title ?? "NotFound"
print(directoryObjectTitle)
} failure: { error in
print(error)
}
searchManager.search(query: searchQuery).sinkOnMainThread { searchResult in
// Получить название первого объекта с первой страницы
let directoryObjectTitle = searchResult.firstPage?.items?.first?.title ?? "NotFound"
print(directoryObjectTitle)
} failure: { error in
print(error)
}
searchManager.search(query: searchQuery).sink { searchResult in
// Получить название первого объекта с первой страницы
let directoryObjectTitle = searchResult.firstPage?.items?.first?.title ?? "NotFound"
print(directoryObjectTitle)
}
Чтобы получить следующую страницу результатов поиска, вызовите метод страницы fetchNextPage(), который вернёт отложенный результат Page:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
- Для версии SDK 12.x
firstPage?.fetchNextPage().sinkOnMainThread { nextPage in
let directoryObject = nextPage?.items?.first
} failure: { error in
print(error)
}
firstPage?.fetchNextPage().sinkOnMainThread { nextPage in
let directoryObject = nextPage?.items?.first
} failure: { error in
print(error)
}
firstPage?.fetchNextPage().sink { nextPage in
let directoryObject = nextPage?.items?.first
}
Отображение результатов на карте
Координаты всех найденных объектов возвращаются в поле itemMarkerInfos результата поиска SearchResult в виде списка элементов ItemMarkerInfo. Список может содержать не более 15000 элементов.
Чтобы отобразить на карте маркеры всех найденных объектов:
- Подготовьте список объектов Marker. Чтобы задать позицию маркера (параметр
position), используйте координаты из поля ItemMarkerInfo.geoPoint. - Добавьте готовый набор маркеров на карту с помощью метода
addObjects()менеджера объектов MapObjectManager. Подробнее см. в инструкции Добавление нескольких объектов на карту.
Пример:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
- Для версии SDK 12.x
func displaySearchResultMarkers(map: Map, searchResult: SearchResult, sdk: DGis.Container) {
// Получить список маркеров из результатов поиска
let cancellable = searchResult.itemMarkerInfos.sinkOnMainThread { markerInfos in
guard let markerInfos = markerInfos else { return }
do {
// Создать менеджер объектов для добавления маркеров на карту
let mapObjectManager = MapObjectManager(map: map)
// Подготовить список маркеров
let markers = try markerInfos.compactMap { itemMarkerInfo -> Marker? in
let position = itemMarkerInfo.geoPoint
let icon = try sdk.imageFactory.make(image: UIImage(systemName: "mappin.circle.fill")!)
let options = MarkerOptions(
position: position,
icon: icon
)
return try Marker(options: options)
}
// Добавить маркеры на карту
mapObjectManager.addObjects(objects: markers)
} catch {
print("Ошибка создания маркеров: \(error.localizedDescription)")
}
} failure: { error in
print("Ошибка получения маркеров: \(error.localizedDescription)")
}
}
func displaySearchResultMarkers(map: Map, searchResult: SearchResult, sdk: DGis.Container) {
// Получить список маркеров из результатов поиска
let cancellable = searchResult.itemMarkerInfos.sinkOnMainThread { markerInfos in
guard let markerInfos = markerInfos else { return }
do {
// Создать менеджер объектов для добавления маркеров на карту
let mapObjectManager = MapObjectManager(map: map)
// Подготовить список маркеров
let markers = try markerInfos.compactMap { itemMarkerInfo -> Marker? in
let position = itemMarkerInfo.geoPoint
let icon = try sdk.imageFactory.make(image: UIImage(systemName: "mappin.circle.fill")!)
let options = MarkerOptions(
position: position,
icon: icon
)
return try Marker(options: options)
}
// Добавить маркеры на карту
mapObjectManager.addObjects(objects: markers)
} catch {
print("Ошибка создания маркеров: \(error.localizedDescription)")
}
} failure: { error in
print("Ошибка получения маркеров: \(error.localizedDescription)")
}
}
func displaySearchResultMarkers(map: Map, searchResult: SearchResult, sdk: DGis.Container) {
// Получить список маркеров из результатов поиска
let cancellable = searchResult.itemMarkerInfos.sink { markerInfos in
guard let markerInfos = markerInfos else { return }
do {
// Создать менеджер объектов для добавления маркеров на карту
let mapObjectManager = MapObjectManager(map: map)
// Подготовить список маркеров
let markers = try markerInfos.compactMap { itemMarkerInfo -> Marker? in
let position = itemMarkerInfo.geoPoint
let icon = try sdk.imageFactory.make(image: UIImage(systemName: "mappin.circle.fill")!)
let options = MarkerOptions(
position: position,
icon: icon
)
return try Marker(options: options)
}
// Добавить маркеры на карту
mapObjectManager.addObjects(objects: markers)
} catch {
print("Ошибка создания маркеров: \(error.localizedDescription)")
}
} failure: { error in
print("Ошибка получения маркеров: \(error.localizedDescription)")
}
}
Структура данных объекта
Результаты поиска по справочнику представлены в виде списка объектов 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). Актуально для организаций.В зависимости от версии SDK наполнение
workStatusможет отличаться:- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
workStatus: WorkStatus(openStatus: .opened(Opened(timeUntilClose: nil)),openStatusHint: "Открыто до 23:00",scheduleHint: "Сегодня до 23:00",breakHint: nil),workStatus: WorkStatus(isOpen: true, description: "Открыто до 23:00"),
-
-
Прочие данные:
- (Данные по запросу) Информация о торговой лицензии организации (
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: .attraction
)
]
Примеры
Ниже представлены примеры DirectoryObject разных типов объектов справочника.
-
Филиал организации:
DirectoryObject// Тип объекта — организацияtypes: [.branch],// Название организацииtitle: "Шоколадница",titleAddition: nil,// Подтип организации — кофейня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: nil))],buildingName: nil,buildingId: BuildingId(value: 4504235282747324),postCode: "125009",buildingCode: nil,fiasCode: nil,addressComment: "1-2 этаж"),attributes: [],contextAttributes: [],// Локальный часовой пояс — UTC+3timeZoneOffset: 3 * 3600,// Время работы филиала: понедельник-четверг с 7:00 до 23:00, пятница с 7:00 до 24:00,// суббота — круглосуточно, воскресенье с 0:00 до 23:00openingHours: OpeningHours(weekOpeningHours: [[WeekTimeInterval(startTime: WeekTime(weekDay: .monday, time: DayTime(hours: 7, minutes: 0)),finishTime: WeekTime(weekDay: .monday, time: DayTime(hours: 23, minutes: 0)))],[WeekTimeInterval(startTime: WeekTime(weekDay: .tuesday, time: DayTime(hours: 7, minutes: 0)),finishTime: WeekTime(weekDay: .tuesday, time: DayTime(hours: 23, minutes: 0)))],[WeekTimeInterval(startTime: WeekTime(weekDay: .wednesday, time: DayTime(hours: 7, minutes: 0)),finishTime: WeekTime(weekDay: .wednesday, time: DayTime(hours: 23, minutes: 0)))],[WeekTimeInterval(startTime: WeekTime(weekDay: .thursday, time: DayTime(hours: 7, minutes: 0)),finishTime: WeekTime(weekDay: .thursday, time: DayTime(hours: 23, minutes: 0)))],[WeekTimeInterval(startTime: WeekTime(weekDay: .friday, time: DayTime(hours: 7, minutes: 0)),finishTime: WeekTime(weekDay: .friday, time: DayTime(hours: 24, minutes: 0)))],[WeekTimeInterval(startTime: WeekTime(weekDay: .saturday, time: DayTime(hours: 0, minutes: 0)),finishTime: WeekTime(weekDay: .saturday, time: DayTime(hours: 24, minutes: 0)))],[WeekTimeInterval(startTime: WeekTime(weekDay: .sunday, time: DayTime(hours: 0, minutes: 0)),finishTime: WeekTime(weekDay: .sunday, time: DayTime(hours: 23, minutes: 0)))]],isOpen24x7: false),contactInfos: [],// Рейтинг 3.4 на основе 85 отзывовreviews: Reviews(rating: 3.4, count: 85),parkingInfo: nil,// В данный момент филиал открыт и работает до 23:00workStatus: WorkStatus(openStatus: .opened(Opened(timeUntilClose: nil)),openStatusHint: "Открыто до 23:00",scheduleHint: "Сегодня до 23:00",breakHint: nil),levelId: nil,buildingLevels: nil,// У организации один входentrances: [EntranceInfo(id: DgisObjectId(objectId: 4504128908451067, entranceId: 70030076156031010),buildingNumber: nil,porchName: nil,porchNumber: nil,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: nil,// Объект относится к трём категориямrubricIds: [RubricId(value: 162),RubricId(value: 1203),RubricId(value: 161)],// Информация о головной организации и общем количестве филиаловorgInfo: OrgInfo(branchCount: 225,id: OrgId(value: 4504136498310300),name: "Шоколадница, кофейня"),group: [] -
Жилое здание:
DirectoryObject// Тип объекта — зданиеtypes: [.building],// Название объекта — адрес зданияtitle: "2-я Черногрязская улица, 1",titleAddition: nil,// Подтип объекта — жилой дом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-я Черногрязская улица 1address: 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: nil,buildingId: BuildingId(value: 4504235282792806),postCode: "123100",buildingCode: nil,fiasCode: nil,addressComment: nil),attributes: [],contextAttributes: [],timeZoneOffset: nil,openingHours: nil,contactInfos: [],// Нет отзывов об объекте для подсчёта рейтингаreviews: Reviews(rating: 0.0, count: 0),parkingInfo: nil,workStatus: nil,levelId: nil,buildingLevels: nil,// У жилого здания два входаentrances: [EntranceInfo(id: DgisObjectId(objectId: 4504235282792806, entranceId: 4504643304435799),buildingNumber: nil,porchName: nil,porchNumber: nil,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: nil,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: nil,rubricIds: [],orgInfo: nil,group: [] -
Улица:
DirectoryObject// Тип объекта — улицаtypes: [.street],// Название объектаtitle: "Улица Петрова",titleAddition: nil,// Подтип объекта — улица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: .districtArea, name: "Раменский муниципальный округ"),AddressAdmDiv(type: .settlement, name: "пгт Удельная")],components: [],buildingName: nil,buildingId: nil,postCode: nil,buildingCode: nil,fiasCode: "0d8e2b4c-eef7-4176-bbec-be9ac0ace587",addressComment: nil),attributes: [],contextAttributes: [],timeZoneOffset: nil,openingHours: nil,contactInfos: [],reviews: nil,parkingInfo: nil,workStatus: nil,levelId: nil,buildingLevels: nil,entrances: [],chargingStation: nil,rubricIds: [],orgInfo: nil,group: [] -
Площадной объект (парк):
DirectoryObject// Основной тип объекта — площадной объект, дополнительный — достопримечательностьtypes: [.admDivPlace, .attraction],// Название объектаtitle: "Парк \"Красногвардейские пруды\"",titleAddition: nil,// Подтип объекта — место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: nil,buildingId: nil,postCode: nil,buildingCode: nil,fiasCode: nil,addressComment: nil),attributes: [],contextAttributes: [],timeZoneOffset: nil,openingHours: nil,contactInfos: [],// Рейтинг 4.8 на основе 62 отзывовreviews: Reviews(rating: 4.8, count: 62),parkingInfo: nil,workStatus: nil,levelId: nil,buildingLevels: nil,entrances: [],chargingStation: nil,// Объект относится к одной категорииrubricIds: [RubricId(value: 168)],orgInfo: nil,// Объект одновременно является и площадным объектом, и достопримечательностьюgroup: [GroupItem(id: DgisObjectId(objectId: 70030076538159915, entranceId: 0),type: .attraction)]
Поисковые подсказки
Вы можете формировать подсказки для пользователей при текстовом поиске объектов. Для этого создайте объект SuggestQuery с помощью SuggestQueryBuilder и передайте его в метод suggest():
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
let query = SuggestQueryBuilder(queryText: "пицц").setLimit(limit: 10).build()
searchManager.suggest(query: query).sink { suggestResult in
// Получить первую подсказку из списка
let firstSuggestTitle = suggestResult.suggests.first ?? ""
print(firstSuggestTitle)
}
let query = SuggestQueryBuilder.fromQueryText(queryText: "пицц").setLimit(limit: 10).build()
searchManager.suggest(query: query).sink { suggestResult in
// Получить первую подсказку из списка
let firstSuggestTitle = suggestResult.suggests.first ?? ""
print(firstSuggestTitle)
}
Вызов вернёт отложенный результат SuggestResult, содержащий список подсказок (Suggest). Подробнее о формировании подсказок см. в документации Suggest API.
Когда пользователь выбирает одну из предложенных подсказок, вы можете настроить реакцию на это событие с помощью обработчика SuggestHandler одного из следующих типов:
- SuggestObjectHandler — возвращает объект справочника DirectoryObject.
- PerformSearchHandler — возвращает объект поискового запроса SearchQuery. Вы можете использовать этот объект для дальнейшего поиска: передайте его в метод SearchManager.search() или создайте на его основе новый SearchQuery с дополнительными параметрами с помощью метода fromQuery() (подробнее см. в разделе Изменение параметров поиска).
- IncompleteTextHandler — возвращает автоматически дополненный текст подсказки, который можно использовать для дальнейшего формирования поискового запроса с помощью метода setQueryText() в SDK 14.0.0 и выше или fromQueryText() в SDK 13.x.
Пример функции для применения всех типов обработчика:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
func apply(suggest: Suggest) {
switch suggest.handler {
// Вернуть дополненный текст подсказки
case .incompleteTextHandler(let incompleteTextHandler):
let queryText = incompleteTextHandler?.queryText
let searchQuery = queryText.map { SearchQueryBuilder().setQueryText(queryText: $0).build() }
showSearchResults(searchQuery: searchQuery)
// Вернуть объект справочника
case .objectHandler(let objectHandler):
showObjectInfo(object: objectHandler?.item)
// Вернуть объект поискового запроса
case .performSearchHandler(let performSearchHandler):
showSearchResults(searchQuery: performSearchHandler?.searchQuery)
@unknown default:
fatalError()
}
}
func apply(suggest: Suggest) {
switch suggest.handler {
// Вернуть дополненный текст подсказки
case .incompleteTextHandler(let incompleteTextHandler):
let queryText = incompleteTextHandler?.queryText
let searchQuery = queryText.map { SearchQueryBuilder.fromQueryText(queryText: $0).build() }
showSearchResults(searchQuery: searchQuery)
// Вернуть объект справочника
case .objectHandler(let objectHandler):
showObjectInfo(object: objectHandler?.item)
// Вернуть объект поискового запроса
case .performSearchHandler(let performSearchHandler):
showSearchResults(searchQuery: performSearchHandler?.searchQuery)
@unknown default:
fatalError()
}
}
История поиска
Вы можете работать с историей поиска с помощью SearchHistory.
В истории поиска могут храниться элементы двух типов: объекты справочника (DirectoryObject) и поисковые запросы (SearchQueryWithInfo).
Добавление элементов в историю поиска
Вы можете добавить элементы в историю поиска в виде объектов SearchHistoryItem по одному или списком. Порядок элементов в списке сохранится при добавлении в историю.
-
Создайте объект SearchHistoryItem и передайте ему один из следующих объектов в зависимости от типа добавляемого элемента:
-
Для поискового запроса: SearchQueryWithInfo с указанием нужного поискового запроса в параметре
searchQuery. ДополнительноSearchQueryWithInfoможет содержать заголовок и подзаголовок, которые отобразятся в выдаче истории поиска.// Создать объект SearchQueryWithInfolet searchQueryWithInfo = SearchQueryWithInfo(searchQuery: searchQuery, // готовый поисковый запросtitle: "Кафе рядом",subtitle: "Рестораны и кафе поблизости")let searchHistoryItem = SearchHistoryItem.searchQuery(searchQueryWithInfo) -
Для объекта справочника: DirectoryObject.
let searchHistoryItem = SearchHistoryItem.directoryObject(directoryObject)
-
-
Создайте объект SearchHistory:
let searchHistory = SearchHistory(context: context) -
Добавьте элементы в историю поиска по одному или списком с помощью методов
addItem()илиaddItems()объекта SearchHistory соответственно:-
Добавить один элемент:
searchHistory.addItem(item: searchHistoryItem) -
Добавить список элементов:
searchHistory.addItems(items: searchHistoryItemsList)
-
Если в истории поиска уже существует добавленный элемент, более старый дубликат будет удалён.
Отображение истории поиска
Чтобы показать страницу поиска со списком элементов, создайте объект SearchHistoryPage и передайте его в метод items(). Дополнительно вы можете настроить следующие параметры:
- Ограничить количество элементов на странице (параметр
limit). Значение по умолчанию — 100. - Задать смещение относительно начала списка (параметр
offset): сколько элементов с начала списка пропустить. Значение по умолчанию — 0 (смещение отсутствует, список отображается с самого начала). - Отфильтровать список по типу элементов (параметр
filter). Доступные фильтры перечислены в SearchHistoryFilter. Например, чтобы показывать в истории только поисковые запросы, используйте значениеSEARCH_QUERY. По умолчанию фильтрация отсутствует.
Пример:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
- Для версии SDK 12.x
// Создать объект SearchHistory
let searchHistory = SearchHistory(context: context)
// Создать страницу истории с лимитом 10 элементов и смещением 0
let page = SearchHistoryPage(
limit: 10, // Максимум 10 элементов на странице
offset: 0, // Смещение 0 (начало списка)
filter: [] // Без фильтров
)
// Получить элементы страницы истории
searchHistory.items(page: page).sinkOnMainThread { result in
result.items.forEach { item in
// Логируем каждый элемент истории
print("Элемент истории: \(item)")
}
} failure: { error in
print("Ошибка при получении страницы из истории поиска: \(error)")
}
// Создать объект SearchHistory
let searchHistory = SearchHistory(context: context)
// Создать страницу истории с лимитом 10 элементов и смещением 0
let page = SearchHistoryPage(
limit: 10, // Максимум 10 элементов на странице
offset: 0, // Смещение 0 (начало списка)
filter: [] // Без фильтров
)
// Получить элементы страницы истории
searchHistory.items(page: page).sinkOnMainThread { result in
result.items.forEach { item in
// Логируем каждый элемент истории
print("Элемент истории: \(item)")
}
} failure: { error in
print("Ошибка при получении страницы из истории поиска: \(error)")
}
// Создать объект SearchHistory
let searchHistory = SearchHistory(context: context)
// Создать страницу истории с лимитом 10 элементов и смещением 0
let page = SearchHistoryPage(
limit: 10, // Максимум 10 элементов на странице
offset: 0, // Смещение 0 (начало списка)
filter: [] // Без фильтров
)
// Получить элементы страницы истории
searchHistory.items(page: page).sink { result in
result.items.forEach { item in
// Логируем каждый элемент истории
print("Элемент истории: \(item)")
}
} failure: { error in
print("Ошибка при получении страницы из истории поиска: \(error)")
}
Элементы на странице упорядочены по времени добавления в историю (от новых к старым).
Очистка истории поиска
Чтобы убрать отдельные элементы из истории поиска:
-
Чтобы убрать один элемент, используйте метод
removeItem()объекта SearchHistory и передайте ему нужный объект SearchHistoryItem. Подробнее о наполненииSearchHistoryItemсм. в инструкции Добавление элементов в историю поиска.searchHistory.removeItem(item: searchHistoryItem) -
Чтобы убрать несколько элементов, используйте метод
removeItems()объекта SearchHistory и передайте ему список нужных объектов SearchHistoryItem. Подробнее о наполненииSearchHistoryItemсм. в инструкции Добавление элементов в историю поиска.searchHistory.removeItems(items: searchHistoryItemsList)
Чтобы очистить историю поиска полностью, используйте метод clear() объекта SearchHistory:
searchHistory.clear()
Подписка на изменения истории
Чтобы отслеживать изменения истории поиска (добавление и удаление элементов), вы можете подписаться на канал onHistoryChanged:
- Для версии SDK 14.0.0 и выше
- Для версии SDK 13.x
- Для версии SDK 12.x
let searchHistory = SearchHistory.instance(context: context)
searchHistory.onHistoryChanged.sinkOnMainThread { changeType in
switch changeType {
case .add:
print("Элемент добавлен в историю")
case .remove:
print("Элемент удалён из истории")
@unknown default:
print("Неизвестное изменение в истории")
}
}
let searchHistory = SearchHistory.instance(context: context)
searchHistory.onHistoryChanged.sinkOnMainThread { changeType in
switch changeType {
case .add:
print("Элемент добавлен в историю")
case .remove:
print("Элемент удалён из истории")
@unknown default:
print("Неизвестное изменение в истории")
}
}
let searchHistory = SearchHistory(context: context)
searchHistory.onHistoryChanged.sink { changeType in
switch changeType {
case .add:
print("Элемент добавлен в историю")
case .remove:
print("Элемент удалён из истории")
@unknown default:
print("Неизвестное изменение в истории")
}
}
Информация о подъездах в справочнике
Вы можете искать адреса в справочнике с точностью до квартиры или подъезда.
Например, по запросу "Томск Кирова 17 кв 5" вы получите объект, который содержит информацию с точностью до подъезда.
DgisObjectId содержит два идентификатора:
- objectId — стабильный числовой идентификатор объекта;
- entranceId — стабильный числовой идентификатор входа/подъезда для объекта.
Если entranceId отличен от нуля, то результатом поиска является не просто дом, а конкретный подъезд в доме.
Если необходимо нарисовать маркер на конкретном подъезде или взять его координаты для построения маршрута, не используйте markerPosition. В этом свойстве будет располагаться позиция, относящаяся к маркеру дома. Для получения позиции подъезда используйте информацию из entrances:
func getMarkerPosition(directoryObject: DirectoryObject) -> GeoPoint? {
guard let entranceId = directoryObject.id?.entranceId,
let info = directoryObject.entrances.first(where: { $0.id.entranceId == entranceId }),
let entrancePoint = info.geometry?.entrancePoints.first else {
return directoryObject.markerPosition?.point
}
return entrancePoint
}