This is the documentation of version 0.58.1. Go to the latest version, 1.0.0-rc.5.

Discover places (fuzzy/geometry/along-route)

The TomTom Maps SDK provides three powerful search services that help you find places, addresses, and points of interest with different search strategies optimized for various use cases. Each search type is designed to handle specific user interaction patterns and application requirements.

Available search types

Fuzzy search

Comprehensive search that handles typos, variations in queries, and natural language input. Fuzzy search is robust and forgiving, making it ideal for situations where users might not know exact spellings or when dealing with international locations.

import { discoverPlaces } from '@tomtom-org/maps-sdk/services';

const results = await discoverPlaces({
    query: 'coffe shop near dam square',  // Handles typos and variations
    geoBias: { position: [4.9041, 52.3676] },
});

Advanced Capabilities:

Ideal Applications:

Geometry search

Find places within specific geographic boundaries or custom areas. Geometry search enables location discovery within precisely defined regions, making it perfect for area-specific applications and location-based services.

import { discoverPlaces } from '@tomtom-org/maps-sdk/services';

// Search within a circle
const results = await discoverPlaces({
    query: 'restaurants',
    geometries: [{
        type: 'Circle',
        coordinates: [4.9041, 52.3676], // [longitude, latitude]
        radius: 5000                     // meters
    }]
});

// Search within a GeoJSON polygon
const results = await discoverPlaces({
    query: 'museums',
    geometries: [{
        type: 'Polygon',
        coordinates: [[[4.7, 52.2], [5.1, 52.2], [5.1, 52.5], [4.7, 52.5], [4.7, 52.2]]]
    }]
});

The discoverPlaces() function automatically dispatches to geometry search when geometries is provided, and to fuzzy search otherwise.

Geometric Search Options:

Perfect For:

Along-route search

Discover places of interest along a planned route, filtered to a maximum detour time. Along-route search is ideal for trip planning scenarios where users want to find fuel stops, restaurants, or EV charging stations without significantly deviating from their journey.

import { discoverPlaces } from '@tomtom-org/maps-sdk/services';

// Pass a GeoJSON LineString directly
const results = await discoverPlaces({
    route: {
        type: 'LineString',
        coordinates: [
            [4.9, 52.37],  // Amsterdam [longitude, latitude]
            [4.95, 52.28],
            [5.0, 52.15],
            [5.1, 52.09],  // Utrecht
        ]
    },
    maxDetourTimeSeconds: 600,
    poiCategories: ['CHARGING_LOCATION'],
    limit: 10,
});

// Or pass a Route Feature returned by calculateRoute
import { calculateRoute } from '@tomtom-org/maps-sdk/services';

const routes = await calculateRoute({ locations: [amsterdamWaypoint, utrechtWaypoint] });
const results = await discoverPlaces({
    route: routes.features[0],
    maxDetourTimeSeconds: 600,
    query: 'cafe',
});

The discoverPlaces() function dispatches to along-route search when a route is provided.

Key Features:

Ideal Applications:

Search as you type

For a search box, use getSearchSuggestions(): one call returns places together with brand and category suggestions.

Parameter reference

Common parameters

These parameters apply to fuzzy search, geometry search, and along-route search:

Parameter Type Description
query string (optional) Search query text. Omit when searching purely by poiCategories, poiBrands, fuelTypes, or geometry.
limit number Maximum results to return (1–100, default: 10).
countries string[] Restrict results to specific countries using ISO 3166-1 alpha-2 or alpha-3 codes (e.g. ['NL', 'DE']).
poiCategories POICategory[] Filter results by POI category. Use the getPOICategories service to discover available values. See POI Categories.
poiBrands string[] Filter by brand name (case-sensitive). Example: ['Starbucks', 'Costa Coffee'].
indexes SearchIndexType[] Which indexes to search. Options: 'Geo', 'PAD', 'Addr', 'Str', 'XStr', 'POI'. Defaults to all.
openingHours OpeningHoursMode Include opening hours in results (e.g. 'nextSevenDays').
timeZone TimeZoneRequest Include timezone info. Use 'iana' to receive IANA timezone IDs (e.g. 'Europe/Amsterdam').
relatedPois RelatedPoisRequest Include related POIs in results. Options: 'off' (default), 'child', 'parent', 'all'.
connectors ConnectorType[] Filter EV charging stations by connector type (e.g. ['IEC62196Type2CCS', 'Chademo']).
fuelTypes Fuel[] Filter fuel stations by fuel type (e.g. ['Petrol', 'Diesel', 'E85']).
minPowerKW number Minimum EV charging power in kilowatts.
maxPowerKW number Maximum EV charging power in kilowatts.
view View Geopolitical view for disputed territories. Options: 'Unified', 'AR', 'IN', 'PK', 'IL', 'MA', 'RU', 'TR', 'CN', 'TW', 'RS'. All eleven are accepted by the backend and change how disputed territories are attributed.
mapcodes MapcodeType[] Request mapcode formats in results: 'Local', 'International', 'Alternative'.
extendedPostalCodesFor SearchIndexType[] Include extended postal codes for specific indexes (default: all except 'Geo').
geographyTypes GeographyType[] Filter results to specific geography types (e.g. ['Municipality', 'Neighbourhood']).

Fuzzy search parameters

Geographic bias

Search and geocoding take a single geoBias option, which is either a point or a rectangle — the two cannot be combined, so the compiler rejects passing both:

// Around a point: biases ranking, and confines results when radiusMeters is given
geoBias: { position: [4.9041, 52.3676], radiusMeters: 2000 }

// Inside a rectangle: [minLng, minLat, maxLng, maxLat], or any GeoJSON a bbox derives from
geoBias: { boundingBox: map.getBBox() }

Omit geoBias entirely to search without a geographic bias.

In addition to all common parameters, fuzzy search supports:

Parameter Type Description
geoBias GeoBias Where to look — { position, radiusMeters? } or { boundingBox }, never both. See Geographic bias.
typeahead boolean Treat the query as partial, for search-as-you-type (default: false).
offset number Pagination offset, zero-based (default: 0).
minFuzzyLevel number Minimum fuzziness level (1–4, default: 1). Lower values require closer matches.
maxFuzzyLevel number Maximum fuzziness level (1–4, default: 2). Higher values tolerate more typos.

Geometry search parameters

In addition to all common parameters, geometry search requires:

Parameter Type Description
geometries SearchGeometryInput[] Required. One or more geometries to search within. Supports Circle, Polygon, and MultiPolygon.

Note: Geometry search does not support geoBias. The geometry shapes define the search area.

Along-route search parameters

Along-route search requires route and maxDetourTimeSeconds. All common parameters also apply. geoBias is not available — the route geometry defines where to search. Parameters from fuzzy/geometry search such as geometries and offset also do not apply.

Parameter Type Description
route LineString | Position[] | Route Required. The route to search along. Accepts a GeoJSON LineString, an array of [longitude, latitude] positions, or a Route Feature returned by calculateRoute.
maxDetourTimeSeconds number Required. Maximum allowed detour time in seconds (positive integer).
sortBy 'detourTime' | 'detourOffset' Sort results by minimum detour time or by position along the route.

POI categories

Use poiCategories to filter results to specific types of places. Each value must be a POICategory enum constant. Use the getPOICategories service to search and browse available categories by name or synonym, then pass the resulting code values directly here.

import { discoverPlaces, getPOICategoryCodes } from '@tomtom-org/maps-sdk/services';

// Filter to a known category
const italian = await discoverPlaces({
    geoBias: { position: [4.9041, 52.3676], radiusMeters: 1000 },
    poiCategories: ['ITALIAN_RESTAURANT']
});

// Discover categories first, then search
const restaurantCodes = await getPOICategoryCodes({ filters: ['restaurant'] });
const restaurants = await discoverPlaces({
    geoBias: { position: [4.9041, 52.3676], radiusMeters: 1000 },
    poiCategories: restaurantCodes
});

// EV charging with connector and power filtering
const evChargers = await discoverPlaces({
    geoBias: { position: [4.9041, 52.3676], radiusMeters: 5000 },
    poiCategories: ['CHARGING_LOCATION'],
    connectors: ['IEC62196Type2CCS', 'Tesla'],
    minPowerKW: 50
});

Example category values: ITALIAN_RESTAURANT, FUEL_STATION, HOTEL, PHARMACY, MUSEUM, PARKING_GARAGE, CHARGING_LOCATION, MALL. See the POICategory type for the full list, or use the getPOICategories service to search and explore them at runtime.

Working with search results

Search results follow a GeoJSON FeatureCollection structure. Each feature is a GeoJSON Feature<Point> with place data in properties:

const results = await discoverPlaces({
    query: 'coffee',
    geoBias: { position: [4.9041, 52.3676] },
});

results.features.forEach(place => {
    console.log(place.properties.poi?.name);              // Business name (POI results)
    console.log(place.properties.address.freeformAddress);// Formatted address
    console.log(place.geometry.coordinates);              // [longitude, latitude]
    console.log(place.properties.poi?.categories);        // POICategory[] (e.g. ['CAFE'])
    console.log(place.properties.poi?.localizedCategories); // string[] (e.g. ['café'])
    console.log(place.properties.score);                  // Relevance score
    console.log(place.properties.distance);               // Distance in meters (if position was given)
});

To retrieve only the first result, use discoverOnePlace() — it throws if no results are found:

import { discoverOnePlace } from '@tomtom-org/maps-sdk/services';

const place = await discoverOnePlace('Eiffel Tower');
console.log(place.properties.poi?.name); // 'Eiffel Tower'

// The params form takes everything `discoverPlaces` does except `limit`
const nearby = await discoverOnePlace({ query: 'coffee', geoBias: { position: [2.2945, 48.8584] } });

Fields that may be absent

A few result and summary fields are not guaranteed. The type is the contract: where a property is optional, handle its absence rather than assuming a value.

Field What it carries
places.properties.totalResults The total number of matches, beyond the page returned
places.properties.fuzzyLevel How loosely the query was matched
places.properties.geoBias The position results were biased towards
places.properties.queryIntent (fuzzy search) Detection of coordinates, what3words codes and "near X" phrasings
place.properties.score A relevance score, for thresholding and merging results
places.bbox A bounding box, on results that cover an area

The pattern to follow — guard, then use:

const results = await discoverPlaces({ query: 'pizza', limit: 10 });
const { offset, numResults, totalResults } = results.properties;

if (totalResults !== undefined && offset + numResults < totalResults) {
    // more pages available; fetch with offset: offset + numResults
}

Treating fuzzyLevel as 0 when it is missing is the one to avoid: absent means "not reported", not "matched exactly".

Examples

Find bus stops in an area (Node.js)

Use geoBias: { boundingBox } to search for all bus stops within a rectangular geographic area. This example searches the Amsterdam city area:

import { discoverPlaces } from '@tomtom-org/maps-sdk/services';

const results = await discoverPlaces({
    poiCategories: ['BUS_STOP'],
    geoBias: { boundingBox: [4.72, 52.27, 5.07, 52.43] }, // [minLng, minLat, maxLng, maxLat]
    limit: 100
});

results.features.forEach(stop => {
    const [lng, lat] = stop.geometry.coordinates;
    console.log(`${stop.properties.poi?.name} — ${lng}, ${lat}`);
});

Integration with map visualization

Search results can be directly integrated with the TomTom Maps SDK for immediate visual representation:

import { TomTomMap, PlacesModule } from '@tomtom-org/maps-sdk/map';

const map = new TomTomMap({ mapLibre: { container: 'map' } });
const placesModule = await PlacesModule.create(map);

const results = await discoverPlaces({
    query: 'museums',
    geoBias: { position: [4.9041, 52.3676] },
});

// Display search results as markers on the map
await placesModule.show(results);

Performance optimization

For optimal performance in production applications, consider these best practices:

Search Strategy Selection:

Result Limiting:

For complete search implementation examples and advanced usage patterns, go to the examples gallery.

Related guides and examples

Map integration

Related examples

Related services