Directory
You can search for objects in the directory, get search suggestions and search results.
Usage scenarios
Typical scenarios of working with the directory:
- Search in a certain area. Example: find all coffee shops within a specified polygon on the map.
- Search in the area of interest. Example: find all flower shops in the viewport of the map.
- Search near a certain point. Example: find public transport stops near the location of a user.
- Search within a point radius. Example: find all gas stations within a radius of 1000 m of the car destination.
- Search by object type. Example: find parking lots by the text query
parking lots
within a radius of 1000 m from the car destination. - Search by object ID in the directory.
You can run these scenarios by building a search query in multiple ways:
- As a text query (fromQueryText() method) with different levels of precision: with a particular object name or with a category of interest.
- By specifying an ID of a particular rubric (fromRubricIds() method), organization (fromOrgId() method), or building (fromBuildingId() method).
- By specifying the coordinates of the search center (fromGeoPoint() method).
Creating a search engine
To search for objects in the directory, create a SearchManager object and call one of the methods that determines the directory operating mode:
- SearchManager.createOnlineManager() - creates an online directory.
- SearchManager.createOfflineManager() - creates an offline directory (preloaded data only).
- SearchManager.createSmartManager() - creates a combined directory that works primarily with online data and switches to offline mode when the network goes down.
An example of creating a search engine with an online directory:
let searchManager = SearchManager.createOnlineManager(context: sdk.context)
Building a search query
Search in a certain area
To search for objects in a certain area, create a SearchQuery object using SearchQueryBuilder and pass it to the search() method. Specify a search area restriction as a polygon using the setSpatialRestriction() method:
let query = SearchQueryBuilder.fromQueryText(queryText: "pizza").setPageSize(pageSize: 10).build()
Search in the area of interest
To search for objects in the area of interest, create a SearchQuery object using SearchQueryBuilder and pass it to the search() method. Specify the coordinates of the rectangular area of interest using the setAreaOfInterest() method:
let geoRect = GeoRect(
southWestPoint: GeoPoint(latitude: 59.931, longitude: 30.344),
northEastPoint: GeoPoint(latitude: 59.936, longitude: 30.351)
)
let searchQuery = SearchQueryBuilder
.fromQueryText(queryText: "text")
.setAreaOfInterest(rect: areaOfInterest)
.build()
Search near a certain point
To search for objects near a certain point, create a SearchQuery object using SearchQueryBuilder and pass it to the search() method. Specify the coordinates of the search center point using the setGeoPoint() method:
let searchQuery = SearchQueryBuilder
.fromQueryText(queryText: "text")
.setGeoPoint(geoPoint: GeoPoint(latitude: 59.936, longitude: 30.351))
.build()
Search within a point radius
To search for objects within a point radius, create a SearchQuery object using SearchQueryBuilder and pass it to the search() method. Specify the coordinates of the search center point using the setGeoPoint() method and the radius of the search area using the setRadius() method:
let searchQuery = SearchQueryBuilder
.fromQueryText(queryText: "text")
.setGeoPoint(geoPoint: GeoPoint(latitude: 59.936, longitude: 30.351))
.setRadius(radius: Meter(value: 1000))
.build()
Search by object type
To search for objects by type, create a SearchQuery object using SearchQueryBuilder and pass it to the search() method. Specify the object type using the setAllowedResultTypes() method:
let searchQuery = SearchQueryBuilder
.fromQueryText(queryText: "text")
.setAllowedResultTypes(allowedResultTypes: [.building])
.build()
Search by object ID
If the object ID in the directory is known, to get information about the object, use the searchById() method:
searchManager.searchById(id: id).sink { object in
print(object?.title)
}
The method returns a deferred result DirectoryObject.
Getting search results
Calling the search() method returns a deferred SearchResult, which contains a paginated list of found objects (DirectoryObject):
searchManager.search(query: query).sink{ searchResult in
// Get the first object of the first page
let directoryObjectTitle = searchResult.firstPage?.items?.first?.title ?? "NotFound"
print(directoryObjectTitle)
}
To get the next page of search results, call the fetchNextPage()page method, which returns a deferred result Page:
firstPage?.fetchNextPage().sink{ nextPage in
let directoryObject = nextPage?.items?.first
}
Search suggestions
You can build suggestions when text searching for objects (see Suggest API). To do this, create a SuggestQuery object using SuggestQueryBuilder and pass it to the suggest() method:
let query = SuggestQueryBuilder.fromQueryText(queryText: "pizz").setLimit(limit: 10).build()
searchManager.suggest(query: query).sink{ suggestResult in
// Get the first suggestion from the list
let firstSuggestTitle = suggestResult.suggests.first ?? ""
print(firstSuggestTitle)
}
The method returns a deferred SuggestResultб which contains a list of suggestions (Suggest).
Information about entrances in the directory
You can search for addresses in the directory with the exact apartment or entrance number.
DgisObjectId contains two identifiers:
- objectId - stable numeric identifier of the object.
- entranceId - stable numeric identifier of the object entrance.
If the entranceId is non-zero, then the search result is not a building but a specific entrance.
If you need to draw a marker on a specific entrance or get its coordinates to calculate a route, do not use markerPosition. This property contains the position related to the marker of the building. To get the entrance position, use the information from entrances:
func getMarkerPosition(directoryObject: DirectoryObject) -> GeoPoint?
{
let entranceId = directoryObject.id?.entranceId ?? 0
if (entranceId != 0)
{
let info = directoryObject.buildingEntrances.first(where: {info in
info.id.entranceId == entranceId})
return info?.geometry?.entrancePoints.first ?? directoryObject.markerPosition?.point
}
return directoryObject.markerPosition?.point
}