Skip to main content

Search online and offline

GLSearchRequest has one request shape for both transports. Use startOnline for the Globus service or startOffline for maps already registered with GLMapManager.

Add the GLSearch package product on iOS or globus:glsearch:2.3.0 on Android. Complete SDK activation first. On Android, GLMapManager.Initialize initializes all included modules; no separate Search initialization is needed.

The examples below use an existing map screen. For a search-only application, follow setup without a map view.

Swift​

import GLMap
import GLSearch

let request = GLSearchRequest(
type: .search,
text: "coffee",
center: GLMapGeoPoint(lat: 41.1579, lon: -8.6291),
limit: 50,
locales: ["en", "native"],
categories: nil
)

requestID = request.startOnline { [weak self] results, error in
if let error {
self?.show(error.localizedDescription)
return
}

self?.rows = results?.array() ?? []
self?.tableView.reloadData()
}

Change only the last call for offline search:

requestID = request.startOffline(completion: completion)

Build a table row directly from each result:

let title = result.localizedName(map.localeSettings)?.asString() ?? "Unnamed"
let subtitle = result.searchSecondaryText?.asString()

Both start methods invoke completion on the main queue exactly once. Cancel an obsolete autocomplete request before starting the next one:

if requestID != 0 {
GLSearchRequest.cancel(requestID)
}

Cancellation completes with an ECANCELED error, so handle it separately when it is not user-visible.

Kotlin​

val request = GLSearchRequest(
GLSearchRequestType.Search,
"coffee",
MapGeoPoint(41.1579, -8.6291),
50,
arrayOf("en", "native"),
null,
)

requestID = request.startOnline(object : GLSearchRequest.ResultsCallback {
override fun onResult(objects: GLMapVectorObjectList) {
val nextResults = objects.toArray()
objects.close()
runOnUiThread { replaceResults(nextResults) }
}

override fun onError(error: GLMapError) {
runOnUiThread { showError(error.toString()) }
}
})

Use request.startOffline(callback) for downloaded maps. Android callbacks may arrive on a background thread or synchronously, so explicitly move UI work to the main thread.

toArray() returns independently owned objects. Close the result list immediately, and close every result object when replacing the table contents.

For Android table rows, GLSearch.GetDisplayInfo applies the same shared display rules used online and offline:

GLSearch.GetDisplayInfo(result, renderer.localeSettings)?.use { info ->
title.text = info.title?.string ?: "Unnamed"
subtitle.text = info.secondaryText?.string
}

Routes and areas​

On GOM5 maps, search finds more than points:

  • Routes, such as bus lines and hiking or cycling trails, by name, number, origin, or destination. A route result is a GLMapVectorRelation: its pin is a point on the route, and its bounding box spans the whole route.
  • Named parks, lakes, cemeteries, and national parks, as polygons.
  • Places inside a mall, park, or campus, also by the name of that mall, park, or campus.

Check how to show a result with searchGeometryKind on Apple platforms or GLSearch.GetGeometryKind on Android. Load the line of a route to draw it, or the pieces of an area that are on screen to highlight it:

switch result.searchGeometryKind {
case .relation:
let route = result as? GLMapVectorRelation
let line = route?.loadMergedLines(true, inMap: nil) // forward direction
let stops = route?.loadStops(inMap: nil) // stops and platforms in route order
case .polygon:
let fragments = mapView.state.loadVisiblePolygons(of: result)
default:
break
}
when (GLSearch.GetGeometryKind(result)) {
GLSearch.GeometryKind.RELATION -> {
val route = result as GLMapVectorRelation
val line = GLSearch.LoadMergedRelationLines(route, true, null) // forward direction
val stops = GLSearch.LoadRelationStops(route, null) // stops and platforms in route order
}
GLSearch.GeometryKind.POLYGON -> {
val fragments = renderer.state?.use { state ->
GLSearch.VisiblePolygonFragments(state, result)
}
}
}

The pieces of an area arrive with the map tiles, so load them again from visibleTilesChangedBlock on Apple platforms or setVisibleTilesChangedCallback on Android. On Android, close the loaded line, stops, and fragments when you no longer need them.

Online spelling corrections and viewport context​

The online service can correct common spelling mistakes when ordinary results are weak. Supply a meaningful center: without a center, fuzzy corrections are not performed. visibleArea is an optional viewport hint, not a strict bounding-box filter. A city named in the query may move the search area away from the current viewport.

The bounds use internal map coordinates, not latitude/longitude degrees. For a map screen, obtain the bounds for the view being searched. The helpers below take those bounds as visibleBounds; they only create requests, so start them with the callbacks shown above.

Swift​

func makeViewportSearch(
text: String,
center: GLMapGeoPoint,
visibleBounds: GLMapBBox
) -> GLSearchRequest {
let request = GLSearchRequest(
type: .search,
text: text,
center: center,
limit: 50,
locales: ["en", "native"],
categories: nil
)
request.visibleArea = visibleBounds
return request
}

Kotlin​

fun makeViewportSearch(
text: String,
center: MapGeoPoint,
visibleBounds: GLMapBBox,
): GLSearchRequest = GLSearchRequest(
GLSearchRequestType.Search,
text,
center,
50,
arrayOf("en", "native"),
null, // categories
visibleBounds, // visibleArea
)

For autocomplete, use .autocomplete in Swift or GLSearchRequestType.Autocomplete in Kotlin. Keep cancelling obsolete requests as the query changes.

To omit the viewport hint, leave it unset (or set GLMapBBoxEmpty) on Apple platforms, or use the existing six-argument constructor / pass null on Android. Search-only apps can supply an area chosen by the user without creating a map view.

Offline mobile search does not include fuzzy matching. Calling startOffline still searches downloaded maps, but does not apply the online spelling corrections. For product examples and limitations, see Find the Place, Even When the Spelling Is Wrong.

Reference apps​

The reference apps show a combined map and results table, autocomplete debouncing, cancellation, online/offline switching, markers, and ownership: