import type { BBox, Place } from '@tomtom-org/maps-sdk/core';
import { TomTomConfig } from '@tomtom-org/maps-sdk/core';
import type { MapFont, PlaceIconConfig, PlacesTheme } from '@tomtom-org/maps-sdk/map';
import { calculatePaddedBBox, PlacesModule, TomTomMap } from '@tomtom-org/maps-sdk/map';
import { search } from '@tomtom-org/maps-sdk/services';
import type { DataDrivenPropertyValueSpecification } from 'maplibre-gl';
import tomtomLogo from './tomtomLogo.png';
import './style.css';
import { API_KEY } from './config';
import { initTogglePanel } from './togglePanel';
TomTomConfig.instance.put({ apiKey: API_KEY, language: 'en-US' });
(async () => {
const map = new TomTomMap({
mapLibre: {
container: 'sdk-map',
center: [4.90435, 52.36876],
zoom: 10,
},
});
const places = await PlacesModule.get(map);
const fontSelectors: NodeListOf<HTMLInputElement> = document.querySelectorAll('.sdk-example-font-selector');
const contentSelectors: NodeListOf<HTMLInputElement> = document.querySelectorAll('.sdk-example-content-selector');
const labelColorPicker = document.getElementById('sdk-example-labelColorPicker') as HTMLInputElement;
const customIconsConfig: PlaceIconConfig = {
categoryIcons: [
{ id: 'ELECTRIC_VEHICLE_STATION', image: tomtomLogo, pixelRatio: 1 },
{ id: 'CAFE', image: 'https://dummyimage.com/30x20/4137ce/fff', pixelRatio: 1 },
],
};
const multiLineLabel: DataDrivenPropertyValueSpecification<string> = [
'format',
['get', 'title'],
{ 'font-scale': 0.9 },
'\n',
{},
['get', 'phone'],
{ 'font-scale': 0.8, 'text-font': ['literal', ['Noto-Regular']], 'text-color': '#3125d1' },
'\n',
{},
['get', 'staticProp'],
{ 'font-scale': 0.7, 'text-font': ['literal', ['Noto-Bold']], 'text-color': '#ce258d' },
];
const updatePlaces = async () => {
await places.show(
await search({
poiCategories: ['ELECTRIC_VEHICLE_STATION', 'CAFE_PUB'],
boundingBox: calculatePaddedBBox({ map, surroundingElements: ['.sdk-example-panel'] }) as BBox,
limit: 100,
}),
);
};
const listenToUIEvents = () => {
const iconStyleSelector = document.getElementById('sdk-example-icon-style-selector') as HTMLSelectElement;
labelColorPicker.addEventListener('input', () => {
places.applyTextConfig({ ...places.getConfig()?.text, color: labelColorPicker.value });
});
for (const element of fontSelectors) {
element.addEventListener('change', () => {
places.applyTextConfig({
...places.getConfig()?.text,
font: [element.value as MapFont],
});
});
}
for (const element of contentSelectors) {
element.addEventListener('change', () => {
element.value !== 'default' &&
places.applyExtraFeatureProps({
phone: (place: Place) => `Phone: ${place.properties.poi?.phone}`,
staticProp: 'Static text',
});
places.applyTextConfig({
...places.getConfig()?.text,
title: element.value === 'default' ? undefined : multiLineLabel,
});
});
}
iconStyleSelector?.addEventListener('change', (e) => {
places.applyTheme((e.target as HTMLSelectElement).value as PlacesTheme);
});
const customIconsToggle = document.getElementById('sdk-example-custom-icons-toggle') as HTMLInputElement;
customIconsToggle?.addEventListener('change', () => {
places.applyIconConfig(customIconsToggle.checked ? customIconsConfig : {});
});
};
initTogglePanel();
await updatePlaces();
map.mapLibreMap.on('moveend', updatePlaces);
listenToUIEvents();
})();