POIs module
The POIs module controls the points of interest the map style draws. To draw search results or your own points, use the Places module.
The module owns whether the style's POI layers are shown, which categories and POIs show and how they look. The look covers icon size, the zoom POIs appear at, label colours, micro markers (Appearance) and any custom icon a category is drawn with. Who owns what compares every module.
Initialization
import { TomTomMap, POIsModule } from '@tomtom-org/maps-sdk/map';
const map = new TomTomMap({ mapLibre: { container: 'map' } });
const poisModule = await POIsModule.get(map);
The POIs belong to the style, so POIsModule.get returns the one instance a map has. A setting
you apply through one handle shows through every other. A configuration passed to a later get
replaces the one it holds, as applyConfig does.
Visibility control
const poisModule = await POIsModule.get(map, { visible: false });
poisModule.setVisible(true);
poisModule.isVisible(); // true
isVisible() returns the visible setting. Until something sets it, it reports whether the style
draws any POI layer.
Every setting as data
poisKnobCatalogue lists the module's settings that a single control can hold, with their kind,
a description and their default, if any. You can read it with no map loaded:
import { poisKnobCatalogue } from '@tomtom-org/maps-sdk/map';
const visible = poisKnobCatalogue.find(({ id }) => id === 'visible');
// { id: 'visible', kind: 'toggle', description: 'The POIs the map style draws.', default: true }
const values = poisKnobCatalogue.find(({ id }) => id === 'filters.categories.values');
// { id: 'filters.categories.values', kind: 'enums', description: '…', options: ['FOOD_DRINKS_GROUP', …, 'RESTAURANT', …] }
| Id | Kind | Default |
|---|---|---|
visible |
toggle | true |
filters.categories.show |
enum: only, all-except |
none |
filters.categories.values |
enums: the category groups, then every category | none |
sizeFactor |
factor 0.5–1.5 | 1 |
minZoom |
number 3–18 | none: the style's own, 6; the micro markers keep their own |
zoomShift |
number −3–3 | 0 |
label.color, label.haloColor |
colour | none: the style's own |
microMarkers.visible |
toggle | none: as the style ships them |
filters.categories.showandfilters.categories.valuesare the category filter, which applies once both are set. The options offilters.categories.valuesare the category groups, then every individual category.- The rest set how POIs look (Appearance).
icon.categoryIconsis not in the catalogue, because it takes images, and neither is the filter by id.setKnob,getKnobandresetKnobset, read and reset a setting by its id (Setting a knob by its id).poisKnobIdslists the ids,POIsKnobIdis their union, andPOIsKnobValueOf<ID>is the plain value one takes. Entries in every module's catalogue share this shape,KnobEntry.
Filtering
filters.categories shows only the categories and category groups it lists, or all-except them:
const poisModule = await POIsModule.get(map, {
filters: { categories: { show: 'only', values: ['RESTAURANT', 'CAFE_PUB'] } },
});
poisModule.updateConfig({
filters: { categories: { show: 'all-except', values: ['PARKING_GROUP', 'OPEN_CAR_PARKING_AREA'] } },
});
// Every category again
poisModule.updateConfig({ filters: undefined });
- Categories and groups can mix in one list. A group stands for each of its categories.
- The map style knows fewer categories than search does, so a category filters by the style category it maps onto.
For example,
'ITALIAN_RESTAURANT'shows or hides every restaurant, and'BAKERY'every shop. showtakes one offilterShowModes('only','all-except'), which@tomtom-org/maps-sdk/mapexports for building a mode picker or a schema.poiCategoryGroupsmaps each group name to its categories.
Filtering by id
filters.ids shows only the POIs it lists, or all-except them, by the id the module's events and getRenderedFeatures() give each POI. To hide a POI whose category you keep, list its id:
const hidden = [];
poisModule.events.on('click', (feature) => {
hidden.push(feature.properties.id);
const { filters } = poisModule.getConfig() ?? {};
poisModule.updateConfig({ filters: { ...filters, ids: { show: 'all-except', values: hidden } } });
});
- A POI must pass both
filters.categoriesandfilters.idsto show. updateConfigreplaces the whole offilters, so spread the filters you keep, as above.filters.idsis not in the catalogue, because its values are the ids of single POIs.
Available category groups
- FOOD_DRINKS_GROUP - Restaurants, cafes, fast food, pubs, wineries
- SHOPPING_GROUP - Stores, malls, markets, supermarkets
- TRANSPORTATION_GROUP - Airports, train stations, bus stops, ferry terminals
- HEALTH_GROUP - Hospitals, clinics, pharmacies, doctors, dentists
- PARKING_GROUP - Parking garages and open parking areas
- HOLIDAY_TOURISM_GROUP - Tourist attractions, museums, beaches, scenic views
- EV_CHARGING_STATIONS_GROUP - Electric vehicle charging stations
- GAS_STATIONS_GROUP - Gas and petrol stations
- ACCOMMODATION_GROUP - Hotels, motels, camping grounds
- ENTERTAINMENT_GROUP - Cinemas, theaters, nightlife, casinos
- SPORTS_LEISURE_GROUP - Stadiums, sports centers, swimming pools, golf courses
- EDUCATION_GROUP - Schools, universities, libraries, cultural centers
- GOVERNMENT_GROUP - Government offices, courthouses, embassies, police, fire stations
Appearance
The size of the POIs, the zoom they appear at, their label colours and the micro markers restyle the style's own POI layers. Each keeps the style's value until you set it:
import { POIsModule, poisKnobCatalogue, setKnob } from '@tomtom-org/maps-sdk/map';
const poisModule = await POIsModule.get(map, {
sizeFactor: 1.2,
minZoom: 12,
label: { color: '#334155', haloColor: '#ffffff' },
microMarkers: { visible: false },
});
setKnob(poisModule, poisKnobCatalogue, 'zoomShift', 1); // later and sparser
sizeFactormultiplies with thelabels.sizeFactorandsymbols.sizeFactorof the Styling Foundations module, which reach the POIs too.zoomShiftcombines with the category filter in either order, because it rewrites the same layer filtersfilters.categoriesnarrows.microMarkers.visiblecan only hide. Micro markers never show while the POIs are hidden, andsetVisible(true)doesn't override afalse.- Places drawn with the
base-mapmarker type borrow this look, andgetStyleColorreads the label colours aspois.label.colorandpois.label.haloColor.
Custom icons per category
icon.categoryIcons draws the POIs of a category with your own image. Every other category keeps
the style's icon. It takes the same entries as the Places module,
so one list restyles the map's POIs and the places you show:
import { PlacesModule, POIsModule } from '@tomtom-org/maps-sdk/map';
const categoryIcons = [
{ id: 'RESTAURANT', image: restaurantSvg },
{ id: 'HOTEL_OR_MOTEL', image: '/icons/hotel-pin.png', offsetY: -17 },
];
const poisModule = await POIsModule.get(map, { icon: { categoryIcons } });
const searchResults = await PlacesModule.create(map, { markerType: 'base-map', icon: { categoryIcons } });
// The style's own icons again
poisModule.updateConfig({ icon: undefined });
- An entry applies to its whole map category. The map knows fewer categories than search does, so
CAFEandCAFE_PUBare both cafés on the map, and the first entry listed wins. A place you show takes the entry for its own category first, so with an entry for each, aCAFEplace draws theCAFEimage while the map's cafés draw the first one listed. - The image is drawn centred on the POI at the style's icon size,
sizeFactorincluded. An image as large as a POI icon keeps the map's density.offsetXandoffsetYmove it in pixels, to stand a pin's tip on its POI. - Entries without an
imagechange no POI, though a place takes one as the ID of a sprite icon the map already has. The micro markers of minor POIs keep the style's dots. - The icons survive a style change, but a switch that resets the map's state drops them.
Events
click, contextmenu, hover and long-hover hand over the POI under the pointer
(event types):
import { getPlaceDetails } from '@tomtom-org/maps-sdk/services';
const stopListening = poisModule.events.on('click', async (feature, lngLat) => {
console.log(feature.properties.name, feature.properties.category, lngLat);
// The POI id is a place id: fetch its opening hours, phone and more
const place = await getPlaceDetails({ entityId: feature.properties.id });
});
poisModule.events.on('hover', (feature) => console.log(feature.properties.name));
stopListening(); // removes this handler alone
poisModule.events.off('hover'); // removes every hover handler
POI feature properties
A POI feature (POIsModuleFeature) carries the style's own values:
id- The POI's id, whichgetPlaceDetailstakes asentityId.name- The name in the country's own language.category- The style's category, in lower case ('restaurant','hotel_or_motel'), not the upper-case category code the filters andcategoryIconstake.group- The style's category group ('eat_and_drink', …).priority- Importance. A lower number is more important.
Querying visible features
getRenderedFeatures() returns the POI features rendered in the viewport:
const { pois } = poisModule.getRenderedFeatures();
pois.forEach((poi) => console.log(poi.properties.name, poi.properties.category));
API reference
POIsModule lists every method, and
POIsModuleConfig every setting.
Related guides and examples
Services integration
- Place details - Full details (opening hours, phone, URL) of a clicked POI
- POI categories - The category codes search and these filters share
Related examples
- POI filters - Interactive POI category filtering, and POIs hidden by id with a click
- Interactive map POIs - Clicks and hovers on the map's own POIs
- POI category icons playground - A circle, square, diamond or pin per category, on the map's POIs and on searched places alike
Related map modules
- Map styling - Label and icon sizes across the whole map, which compose with the POIs' own
sizeFactor, and the map presets that set POI knobs too - Places module - Search results and your own points, drawn as markers
- User interaction events - Event types, cursors and event states across modules