Search

With MapKit SDK, you can search for map locations and objects by name. For example, you can use the search API to get a list of nearby restaurants, see if there are any gas stations along the route, or find a location based on its exact address. In addition to name search, MapKit SDK offers Geocoder queries. With this feature, you can locate an object's coordinates based on its address, or vice versa — find out an object's address based on its coordinates.

Warning

The search functionality is available in the full version of the MapKit SDK.

Executing a search query

Let's examine the general algorithm for executing a search query with the MapKit SDK:

  1. Create an instance of the SearchManagerType class to use as the entry point to the MapKit SDK search API.

    val searchManager = SearchFactory.getInstance().createSearchManager(SearchManagerType.COMBINED)
    

    When instantiating SearchManager, specify its SearchManagerType, which determines the mode of operation: offline, online, or mixed.

  2. Determine which search query type should be used in your case.

    For example, use the SearchManager.submit(String, Geometry, SearchOptions, SearchListener) method to search for text within a geometry.

  3. Create an instance of the SearchOptions class to set the search parameters for the query.

    Example of parameter values for limiting the search to organizations:

    val searchOptions = SearchOptions().apply {
        searchTypes = SearchType.Biz
        resultPageSize = 32
    }
    
  4. Create a new search session using the method from the SearchManager class that corresponds to the search query type you need.

    Example of a search session for finding places to eat, such as cafes and restaurants:

    val session = searchManager.submit(
        "where to eat",
        VisibleRegionUtils.toPolygon(map.visibleRegion),
        searchOptions,
        searchSessionListener,
    )
    
  5. When creating the search session, use the following mechanism to retrieve the search query results.

    Create an object of the SearchListener interface:

    val searchSessionListener = object : SearchSessionListener {
        override fun onSearchResponse(response: Response) {
            // Handle search response.
        }
    
        override fun onSearchError(error: Error) {
            // Handle search error.
        }
    }
    

    Pass an implementation of this interface as an argument whenever you call a method for creating a search session.

Search query types

The MapKit SDK offers several search query types, each tailored to specific search scenarios. Queries are organized into the following groups:

Let's examine the main features and differences of each search query type.

This type executes a search based on the text entered by the user.

Text search is very flexible. For example, depending on the entered text, you can search by:

  • Organization name
  • Address
  • Category name (for example, "Restaurants" or "Fitness")
  • Activity (for example, "Where to go for a walk in the evening")
  • Coordinates (for example, (59.935493, 30.327392))

There are two types of methods that can be used to create a text search session:

  1. SearchManager.submit(String, Geometry, SearchOptions, SearchListener): Executes a search based on the query text, looking for objects within a specific geometry on the map: along a polyline, near a point, or inside a boundingBox or polygon.

  2. SearchManager.submit(String, Polyline, Geometry, SearchOptions, SearchListener): Searches along a polyline but within a specific boundingBox or polygon. This method is useful for searching along the route section visible within the map viewport. For example, you can use it to search for gas stations located along a route.

When searching along a route, the MapKit SDK sorts the search results based on the distance between the found objects and the passed polyline and returns the closest ones.

Reverse geocoding

Reverse geocoding enables you to get the address or name of the object located at the coordinates specified by the user.

To create a reverse search session, use the SearchManager.submit(Point, Float, SearchOptions, SearchListener) method with the following arguments:

  • point: The point whose coordinates are used in the search.
  • zoom: The current zoom level of the map. It's used to discard objects that are too small at low zoom levels.

Some geo objects on MapKit maps provide a string URI. URI search enables you to search for this type of object. You can retrieve the URI from the geo object's URI metadata.

There are two types of methods for creating a URI search session:

  1. SearchManager.resolveURI: Used to search for geo objects by their URI retrieved from the URI metadata.

  2. SearchManager.searchByURI: Enables you to find multiple objects by URI. This can be used in Geosuggest searches.

Search parameters

All search query types can take a SearchOptions argument to define the search parameters.

Search parameters include:

  • searchTypes: Type of objects to search for: toponyms, companies, or both.
  • resultPageSize: The number of results per search page.
  • userPosition: Used to calculate the distance between the user and the objects returned by the search.
  • geometry: Returns the geometry of the found object (used when searching for toponyms).
  • disableSpellingCorrection: Turns on the correction of errors in the search query text.
  • filters: Sets filtering parameters for the search query.

Warning

Depending on the search query type, some search parameters may be ignored.

To find out which search parameters are supported for a specific search query type, see the documentation on the SearchManager class search methods.

Search session

The MapKit SDK implements search queries as an asynchronous operation that may require a network request (for example, when performing an online search). All methods for creating search queries contained in the SearchManager class return a Session object that manages the state of the search query.

Example of creating a search session to find restaurants on the map:

val session = searchManager.submit(
    "Restaurant",
    VisibleRegionUtils.toPolygon(map.mapRegion),
    SearchOptions().apply {
        searchTypes = SearchType.BIZ.value
    },
    searchListener
)

Warning

The Session object must be stored on the client app side. Otherwise, the search query may be automatically canceled.

The Session class supports a large number of operations for managing search queries, such as canceling the current query, retrieving the next results page, and enabling the sorting of results for distances to a specific geometry. With the recurring query feature, you can change some parameters of the original query and then execute the query again.

Example of using a Session object to create a recurring query that takes different search geometries:

private var searchSession: Session?

fun resubmitAfterMove() {
    val geometry = VisibleRegionUtils.toPolygon(map.visibleRegion)
    searchSession?.setSearchArea(geometry)
    searchSession?.resubmit(searchSessionListener)
}

You can use this method in cases such as when the camera position changes after the user swipes the map.

Search results

To retrieve the results of a search query, use a subscription to the SearchListener interface. This subscription is passed as an argument when calling search query creation methods with the SearchManager class.

SearchListener supports two types of handler methods:

  1. SearchListener.onSearchResponse: Notifies of successful search query completion. This handler provides a Response object with information about the results of the request.

  2. SearchListener.onSearchError: Called when a query completes with an error.

If the request is successful, you can retrieve a Response object with information about:

Let's take a closer look at the information included in the data on successful query completion.

Geo object collection

You can use the Response.getCollection method to get a collection of the found objects. With the GeoObjectCollection.getChildren method, you can get a list of found geo objects.

override fun onSearchResponse(response: Response) {
    val geoObjects = response.collection.children.mapNotNull { it.obj }
    // Process geoObjects collection.
}

Geo objects

The GeoObject class is a MapKit SDK entity that provides information about map objects. A geo object can be an organization, a building, or a geographic object like a country, city, or sea.

There are two types of geo objects:

  1. Organizations: Restaurants, beauty salons, government buildings, schools, hospitals, stores, hotels, and other businesses.
  2. Toponyms: Buildings, cities, countries, and various geographic features.

In the context of the search API, geo objects are used as search results. The most commonly used geo object search parameters are:

  • name: Object name.
  • geometry: Contains the coordinates of an organization or the geometry of a toponym.
  • metadataContainer: Used to augment the base geo object with additional metadata.

Different types of geo objects have different types of metadata.

UriObjectMetadata

Using the UriObjectMetadata type, you can get the unique ID of a geo object.

val uri = geoObject.metadataContainer.getItem<UriObjectMetadata>()?.uris?.firstOrNull()

URIs can be used to organize your app's bookmarking feature. When the user adds a favorite location, the app saves the string ID of the associated geo object. When the user wants to return to a saved location, you can perform a URI search to retrieve the geo object and display it on the map.

BusinessObjectMetadata

The BusinessObjectMetadata class includes a wide range of methods that provide different types of information about the organization. BusinessObjectMetadata can only be retrieved from geo objects that are organizations.

val metadata = geoObject.metadataContainer.getItem<BusinessObjectMetadata>()
if (metadata != null) {
    // Geo object is a business organization.
} else {
    // Not an organization.
}

The key data of the BusinessObjectMetadata class include:

  • name: Organization name.
  • address: Organization address.
  • phones: List of the organization's phone numbers.
  • workingHours: Business hours of the organization.
  • features: A list of the organization's features, such as the availability of Wi-Fi or card payment options.

ToponymObjectMetadata

You can use the ToponymObjectMetadata class to get additional information about a toponym, such as its address or name. ToponymObjectMetadata can only be retrieved from geo objects that are toponyms.

Query metadata

Query metadata is represented by the SearchMetadata class, which contains additional information about the search query.

General information includes:

  • found: Approximate number of found objects.
  • displayType: Defines the display type. If the result isn't part of a group, the value is single. In this case, re-executing the query when moving the map is most likely unnecessary. If the result may be part of a group, the value is multiple. In this case, re-executing the query may be necessary when moving the map.
  • boundingBox: The bounding box of the map objects returned by search. You can move the viewport to this geometry to display the search results on the map.
  • sort: The type of sorting applied to the objects in the output. For example, you can sort them by distance from the user.
  • toponym: The result of reverse geocoding, if it was applied.
  • requestText: The query text entered by the user as part of their search.
  • correctedRequestText: requestText with automatic correction applied.
  • requestBoundingBox: The map's bounding box passed when creating the request.

In addition to general information, query metadata contains additional information that depends on the search query type and whether the search was performed for organizations or toponyms:

  • toponym: Contains the geo object with the toponym returned by the search.
  • toponymResultMetadata: Additional information about the toponym search query.
  • businessResultMetadata: Additional information about the organization search query.

Let's take a closer look at the differences between toponymResultMetadata and businessResultMetadata.

ToponymResultMetadata

The metadata of toponym search results is represented by the ToponymResultMetadata class, which provides the following information:

  • Number of toponyms found.
  • Search mode and accuracy.
  • Coordinates used for reverse geocoding.

BusinessResultMetadata

The BusinessResultMetadata class provides information on the presence of:

  • Search categories in search results.
  • Search chains (the list isn't empty if a chain organization was found for the query).
  • Search filters.

Source code

As an example of using the search API functionality, see the map-search app in our GitHub repository.