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

Place styling

The Places module draws places in its own look, set by the marker type, colour, icon and label settings below. Each plain-valued setting is a knob in placesKnobCatalogue. Two outside settings reach these layers. The map's accent colours markers you give no colour, and the knobs that restyle the style's POIs restyle the marker types that borrow their look.

Marker type

markerType sets the marker every place is drawn with, at creation or at runtime:

const placesModule = await PlacesModule.create(map, { markerType: 'base-map' });
placesModule.updateConfig({ markerType: 'circle-icon' });

// Micro dots only: `base-map` with a hidden `main` layer
const microPlaces = await PlacesModule.create(map, {
    markerType: 'base-map',
    layers: { main: { layout: { visibility: 'none' } } },
});

base-map, circle-icon and pin-clustered borrow the look of the style's POIs. Borrowed looks lists which POI knobs restyle each marker type.

Clusters

With the pin-clustered marker type, cluster sets how places cluster and how the count badge looks. Other marker types ignore it. badge styles the badge of both single-category and mixed-category clusters, and source takes MapLibre's cluster options:

const placesModule = await PlacesModule.create(map, {
    markerType: 'pin-clustered',
    // The per-place value the cluster aggregates
    extraFeatureProps: {
        connectorCount: (place) =>
            place.properties.chargingPark?.connectors.reduce((total, { count }) => total + count, 0) ?? 0,
    },
    cluster: {
        badge: { color: '#3f9cd9', radius: { single: 13, mixed: 18 } },
        source: {
            radius: 100, // default 60
            maxZoom: 14, // default 17
            // Total charging points across each cluster
            properties: { connectors: ['+', ['get', 'connectorCount']] },
        },
    },
    // An aggregated value lands on the cluster feature's properties
    layers: { clusterCount: { layout: { 'text-field': ['get', 'connectors'] } } },
});

Colour

color colours the module's own drawing: the default pin fill, the label of a hovered or clicked place, connection lines and entry points. Connection labels take a darker shade of it on a light map and a lighter one on a dark map. Entry points take the darker one on a light map.

const placesModule = await PlacesModule.create(map, { color: '#2A9D8F' });

Label styling

label sets the content and look of the labels next to the markers:

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

// POI names red, other places blue
const label: PlaceLabelConfig = {
    title: (place) => place.properties.poi?.name ?? place.properties.address.freeformAddress,
    color: ['match', ['get', 'type'], 'POI', '#D32F2F', '#1976D2'],
    haloWidth: 2,
};
const placesModule = await PlacesModule.create(map, { label });

// `label` replaces the whole label: spread the current one to change a single field
placesModule.updateConfig({ label: { ...placesModule.getConfig()?.label, opacity: 0.8 } });

Icon styling

icon.categoryIcons draws a category's places with your own image, under every marker type. Places in other categories keep the marker type's icon.

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

const icon: PlaceIconConfig = {
    categoryIcons: [
        { id: 'RESTAURANT', image: '/icons/food.png', pixelRatio: 2 },
        // A pin whose tip sits 10 pixels below its centre
        { id: 'HOTEL_OR_MOTEL', image: '/icons/hotel.png', pixelRatio: 2, offsetY: -10 },
    ],
};
const placesModule = await PlacesModule.create(map, { markerType: 'pin', icon });

Extra properties

extraFeatureProps adds properties to every place feature, for layers expressions to read with ['get', '<name>'] and for event handlers:

placesModule.updateConfig({
    extraFeatureProps: {
        firstCategory: (place) => place.properties.poi?.categories?.[0],
        brand: (place) => place.properties.poi?.brands?.[0] ?? '',
        source: 'search',
    },
});

An entry is a fixed JSON value or a callback that receives a Place and returns one. If the places you show have a narrower shape, such as search results with their relevance score, name it on the config, or as the type parameter of applyConfig / updateConfig. The callbacks, label.title and icon.mapping are then typed for it:

import type { SearchPlaceProps } from '@tomtom-org/maps-sdk/core';
import type { PlacesModuleConfig } from '@tomtom-org/maps-sdk/map';

const config: PlacesModuleConfig<SearchPlaceProps> = {
    extraFeatureProps: {
        relevance: (place) => place.properties.score,
    },
};

Layer positioning

By default, the markers sit above the map's layers, and the connection lines below its labels. beforeLayerConfig (PlacesBeforeLayerConfig) moves them. It takes either one target for everything the module draws, 'top' or a key of mapStyleLayerIDs, or a record keyed by part, plus all for the parts it leaves out. The parts are named after the event scopes:

// The markers under the map's labels; the connections stay where they are
placesModule.updateConfig({ beforeLayerConfig: { places: 'lowestLabel' } });

Every setting as data

placesKnobCatalogue lists every plain-valued display setting of the module with its kind, its range or options and, if one value holds everywhere, its default. Each id is the setting's path in the config. The catalogue reads with no map loaded, so a UI can build its controls from it:

import { placesKnobCatalogue } from '@tomtom-org/maps-sdk/map';

const badgeKnobs = placesKnobCatalogue.filter(({ id }) => id.startsWith('cluster.badge.'));
// [{ id: 'cluster.badge.color', kind: 'color', description: '…', default: '#000000' }, …,
//  { id: 'cluster.badge.radius.single', kind: 'number', description: '…', range: { min: 4, max: 32, step: 1, bounds: 'hard-min' }, default: 11 }, …]
Knob Kind Default
markerType enum 'pin'
color color the map's accent
visible toggle true
icon.default.style.fillColor color color
icon.default.style.outlineColor color
icon.default.style.outlineOpacity number
label.size number 14 to 16 pixels by zoom
label.color color by the map's light/dark theme
label.haloColor color by the map's light/dark theme
label.haloWidth number 1 to 1.5 pixels by zoom
label.opacity number
label.distance number from the icon's size
label.font enums Noto-Bold, or the style's under base-map
cluster.badge.color color '#000000'
cluster.badge.outlineColor color '#FFFFFF'
cluster.badge.outlineWidth number 1.5
cluster.badge.label.color color '#FFFFFF'
cluster.badge.label.size number 12
cluster.badge.radius.single number 11
cluster.badge.radius.mixed number 15
cluster.badge.offset offset [12, -14]
cluster.source.radius number 60
cluster.source.maxZoom number 17
cluster.source.minPoints number MapLibre's, 2
entryPoints.showFor enum 'selected'
entryPoints.minZoom number 15
connections.color color the module's color, else the map's accent, else by the map's light/dark theme
connections.label.color color a shade of the line's colour for the map's light/dark theme
connections.label.haloColor color by the map's light/dark theme

Related guides and examples

Related guides

Related examples