POI categories
getPOICategories() returns
every POI category the Search API knows, with its names and synonyms in a language. Use it to build a
category picker, or to find categories by name or synonym. A category's code, a POICategory, works in:
- Search filtering, with
discoverPlaces({ filters: { poiCategories } }). - The map's own POI icons, with the
POIsModulefilters.categoriessetting, which takes generic parent codes only (Filtering the map's built-in POI icons).
The Node.js POI categories example finds categories by keyword,
best match first, and feeds their codes to discoverPlaces.
Basic usage
import { getPOICategories } from '@tomtom-org/maps-sdk/services';
const { poiCategories: categories } = await getPOICategories();
categories.forEach((category) => {
console.log(category.name); // e.g. "Sports Center"
console.log(category.code); // e.g. "SPORTS_CENTER"
console.log(category.synonyms); // e.g. ["Sports Centre"]
console.log(category.childCategoryCodes); // e.g. ["FITNESS_CLUB_AND_CENTER", "HORSE_RIDING", ...]
});
Getting codes directly: getPOICategoryCodes
getPOICategoryCodes takes the same parameters and returns only the codes:
import { discoverPlaces, getPOICategoryCodes } from '@tomtom-org/maps-sdk/services';
const all = await getPOICategoryCodes();
// Codes matching a keyword, best match first, e.g. ['RESTAURANT', 'RESTAURANT_AREA']
const restaurantCodes = await getPOICategoryCodes({ filters: ['restaurant'] });
const results = await discoverPlaces({
filters: { poiCategories: restaurantCodes },
geoBias: { position: [4.9041, 52.3676] },
});
Fetching in a specific language
language localizes the names and synonyms, and defaults to the global
language:
const { poiCategories: categories } = await getPOICategories({ language: 'fr-FR' });
console.log(categories[0].name); // e.g. "Centre sportif"
Filtering categories
filters finds categories by keyword. It matches client-side against the cached list, so it sends no
request after the first. Each filter ranks the categories it matches, strongest first:
- A category code, such as
'CAFE', matches that category only. - Any other filter ranks an exact name or synonym first, then a name or synonym that starts with the
filter (
'parking'finds'Parking Garage'), then one with it as a later word, and last one containing it as a substring.
- A filter keeps only matches close to its best one, so
'bar'finds'Bar'but not'Nail Salon'through its synonym'Nail Bar'. - Matching ignores case, accents and punctuation. A substring match ignores spaces too.
'cafe'finds'Café', and'bookstore'finds'Book Shop'through its synonym'Book Store'. A blank filter matches nothing. - Several filters merge round-robin, so each filter's best match comes first, with one entry per code. A category ranked below its matched parent is left out, because the parent already covers it.
const { poiCategories: gymCategories } = await getPOICategories({ filters: ['gym'] });
// Each filter's best match first, one entry per code
const { poiCategories: combined } = await getPOICategories({ filters: ['gym', 'parking'] });
const { poiCategories: restaurants } = await getPOICategories({ language: 'en-GB', filters: ['restaurant'] });
Using categories in search
Pass code values to discoverPlaces(), such as the one picked from a dropdown:
import { discoverPlaces, getPOICategories } from '@tomtom-org/maps-sdk/services';
const { poiCategories: allCategories } = await getPOICategories();
const options = allCategories.map((category) => ({ label: category.name, value: category.code }));
const results = await discoverPlaces({
filters: { poiCategories: ['SPORTS_CENTER'] },
geoBias: { position: [4.9041, 52.3676] },
limit: 20,
});
When the category comes as a word rather than a choice from a list, skip the lookup and pass it as
filters.poiCategoryQuery, which
resolves it with resolvePOICategories:
const gyms = await discoverPlaces({ filters: { poiCategoryQuery: 'gym' }, geoBias: { position: [4.9041, 52.3676] } });
Resolving words for a search: resolvePOICategories
resolvePOICategories turns words, or codes, into the poiCategories of one search, and reports the
words that match nothing. Call it before searching to handle those words yourself. You can search
with the rest, ask the user or fall back to a free-text query.
import { discoverPlaces, resolvePOICategories } from '@tomtom-org/maps-sdk/services';
const { poiCategories, unmatched } = await resolvePOICategories({ filters: ['café', 'PHARMACY', 'xyzzy'] });
// unmatched: ['xyzzy']
if (poiCategories.length) {
const places = await discoverPlaces({ filters: { poiCategories }, geoBias: { position: [4.9041, 52.3676] } });
}
- Each filter matches as in Filtering categories, so a code stays itself.
- It keeps each filter's best three codes, merged round-robin and capped at the 10 a search accepts.
filters.poiCategoryQueryruns this lookup, so both resolve a word the same way.- Codes alone skip the catalogue request and come back as given, never folded into a parent, with duplicates dropped.
resolvePOICategoriesbuilds one search, whilegetPOICategoryCodeslists every close match, for a picker or the map's POI icons.
Filtering the map's built-in POI icons
To choose which of the map's own POI icons show, set the POIsModule filters.categories setting to
generic parent codes or POICategoryGroup values such as 'FOOD_DRINKS_GROUP'. It doesn't support
specific child codes such as 'ITALIAN_RESTAURANT', so use the parent 'RESTAURANT' or a group. The POIs module guide covers the setting and its groups.
import { POIsModule, TomTomMap } from '@tomtom-org/maps-sdk/map';
import { getPOICategoryCodes } from '@tomtom-org/maps-sdk/services';
const map = new TomTomMap({ mapLibre: { container: 'map' } });
const poisModule = await POIsModule.get(map);
const codes = await getPOICategoryCodes({ filters: ['restaurant', 'sports center'] });
poisModule.updateConfig({ filters: { categories: { show: 'only', values: codes } } });
Exploring sub-categories
childCategoryCodes lists a category's sub-categories, for drill-down navigation:
const { poiCategories: categories } = await getPOICategories();
const restaurant = categories.find((category) => category.code === 'RESTAURANT');
console.log(restaurant?.childCategoryCodes); // e.g. ['ITALIAN_RESTAURANT', 'FRENCH_RESTAURANT', ...]
Note that a search by a parent code returns places in these sub-categories too.
Cache management
- The first call in a language fetches the list. Every later call in that language reads the cache, filtered or not, including
resolvePOICategoriesandfilters.poiCategoryQuery. - The cache is in memory for the lifetime of the page or process. There is nothing to clear.
const { poiCategories: english } = await getPOICategories({ language: 'en-GB' });
const { poiCategories: french } = await getPOICategories({ language: 'fr-FR' }); // a second request
Parameter reference
On top of the options every service call takes:
| Parameter | Type | Description |
|---|---|---|
language |
string |
IETF language tag for names and synonyms, e.g. 'en-GB', 'fr-FR'. Defaults to the global language. |
filters |
string[] |
Keywords matched client-side, as in Filtering categories. Omit it to return every category. resolvePOICategories requires it. |
Response reference
Each entry of poiCategories:
| Field | Type | Description |
|---|---|---|
code |
POICategory |
The code filters.poiCategories takes. |
name |
string |
Category name in the requested language. |
childCategoryCodes |
POICategory[] |
Sub-category codes, whether or not they matched filters. |
synonyms |
string[] |
Alternative names in the requested language. |
resolvePOICategories returns { poiCategories, unmatched } instead. It holds the codes for one
search, best first, and the filters that matched nothing, as given.
Related guides
- Discover places — Searching by category code or by category in words
- POIs module — The map's own POI icons, filtered by parent codes or groups
- Search suggestions — A category the user is typing, as a
categorysuggestion