Skip to main content

Getting started with Search

|

The Maps SDK for TypeScript provides flexible and robust search functionality, allowing you to search for locations using text queries and coordinates:

  • Text Search: Perform searches using a text query and geographic coordinates to prioritize results within a specific area.
  • Search Preferences: Customize search behavior using various options, such as allowing fuzzy results, limiting search distance, or specifying the number of results.
  • Category-Based Search: Filter search results by predefined categories, such as gas stations or parking areas.
  • Proximity Search: Retrieve all nearby landmarks without specifying a text query.

The simplest way to search for something is by providing text and specifying coordinates. The coordinates serve as a hint, prioritizing points of interest (POIs) within the indicated area.

import { SearchService, SearchPreferences, Coordinates, GemError, Landmark } from '@magiclane/maps-sdk';

const text = "Paris";
const coords = new Coordinates({ latitude: 45, longitude: 10 });
const preferences = SearchPreferences.create({
maxMatches: 40,
searchAddresses: true,
searchMapPOIs: true
});

const taskHandler = SearchService.search({
textFilter: text,
referenceCoordinates: coords,
preferences: preferences,
onCompleteCallback: (err: GemError, results: Landmark[]) => {
// If there is an error or there aren't any results, the method will return an empty list.
if (err === GemError.success) {
if (results.length === 0) {
console.log("No results");
} else {
console.log(`Number of results: ${results.length}`);
results.forEach(result => {
console.log(`- ${result.name} at ${result.coordinates.latitude}, ${result.coordinates.longitude}`);
});
}
} else {
console.error(`Error: ${err}`);
}
}
});
note

The SearchService.search method returns null only when the geographic search fails to initialize. In such cases, calling SearchService.cancelSearch(taskHandler) is not possible. Error details will be delivered through the onComplete callback of the SearchService.search method.

The err provided by the callback function can have the following values:

ValueSignificance
GemError.successSuccessfully completed
GemError.CancelCancelled by the user
GemError.NoMemorySearch engine couldn't allocate the necessary memory for the operation
GemError.OperationTimeoutSearch was executed on the online service and the operation took too much time to complete (usually more than 1 min, depending on the server overload state)
GemError.NetworkTimeoutCan't establish the connection or the server didn't respond on time
GemError.NetworkFailedSearch was executed on the online service and the operation failed due to bad network connection

Specifying preferences

As seen in the previous example, before searching we need to specify some SearchPreferences. The following characteristics apply to a search:

FieldTypeDefault ValueExplanation
allowFuzzyResultsbooleantrueAllows fuzzy search results, enabling approximate matches for queries.
maxMatchesnumber100Maximum number of search results to return.
searchDistancenumberunlimitedMaximum distance (in meters) from the search coordinates to consider results.

Example with more preferences:

const preferences = SearchPreferences.create({
maxMatches: 20,
searchAddresses: true,
searchMapPOIs: true
});

You can filter search results by specific categories:

import { SearchService, LandmarkCategory, Landmark, GemError } from '@magiclane/maps-sdk';

const coords = new Coordinates({ latitude: 48.858844, longitude: 2.294351 }); // Paris
const preferences = SearchPreferences.create({
maxMatches: 10,
searchAddresses: true,
searchMapPOIs: true
});

const taskHandler = SearchService.search({
textFilter: "", // Empty text for category-only search
referenceCoordinates: coords,
preferences: preferences,
onCompleteCallback: (err: GemError, results: Landmark[]) => {
if (err === GemError.success) {
console.log(`Found ${results.length} results`);
}
}
});

Retrieve all nearby landmarks without specifying a text query:

const coords = new Coordinates({ latitude: 40.748817, longitude: -73.985428 }); // New York
const preferences = SearchPreferences.create({
maxMatches: 50,
searchAddresses: true,
searchMapPOIs: true
});

const taskHandler = SearchService.search({
textFilter: "",
referenceCoordinates: coords,
preferences: preferences,
onCompleteCallback: (err: GemError, results: Landmark[]) => {
if (err === GemError.success) {
console.log(`Found ${results.length} nearby landmarks`);
}
}
});

If you need to cancel an ongoing search operation:

if (taskHandler) {
SearchService.cancelSearch(taskHandler);
console.log('Search cancelled');
}

Using Promises (Alternative Pattern)

You can wrap the search in a Promise for async/await usage:

function searchAsync(
text: string,
coords: Coordinates,
preferences: SearchPreferences
): Promise<Landmark[]> {
return new Promise((resolve, reject) => {
const taskHandler = SearchService.search({
textFilter: text,
referenceCoordinates: coords,
preferences: preferences,
onCompleteCallback: (err: GemError, results: Landmark[]) => {
if (err === GemError.success) {
resolve(results);
} else {
reject(new Error(`Search failed with error: ${err}`));
}
}
});

if (!taskHandler) {
reject(new Error('Failed to initialize search'));
}
});
}

// Usage
try {
const results = await searchAsync("Restaurant", coords, preferences);
console.log(`Found ${results.length} restaurants`);
} catch (error) {
console.error('Search error:', error);
}

Next Steps

Now that you understand basic search functionality, you can explore:

  • Reverse geocoding (converting coordinates to addresses)
  • Forward geocoding (converting addresses to coordinates)
  • Auto-suggestion for search queries
  • Custom landmark search