@tomtom-org/maps-sdk-plugin-viewport-places 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +4 -4
- package/README.md +14 -3
- package/dist/index.d.ts +14 -16
- package/dist/index.es.js +1 -2
- package/package.json +8 -8
- package/dist/index.es.js.map +0 -1
package/LICENSE.txt
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
TOMTOM MAPS SDK FOR JAVASCRIPT LICENSE AGREEMENT (“AGREEMENT”)
|
|
2
2
|
|
|
3
|
-
Last update:
|
|
3
|
+
Last update: October 2026
|
|
4
4
|
|
|
5
|
-
By downloading or accessing the “TomTom Maps SDK for JavaScript” (the “SDK”), you are entering into a binding agreement with TomTom Global Content B.V. (“TomTom”). The SDK comprises all software, binaries and source code made available by TomTom for it, whether through the TomTom Developer Portal or public code repositories (e.g. GitHub). This Agreement with TomTom consists of the terms and conditions below together with the Data Processing Schedule. You should not use the SDK if you cannot agree to both.
|
|
5
|
+
By downloading or accessing the “TomTom Maps SDK for JavaScript” (the “SDK”), you are entering into a binding agreement with TomTom Global Content B.V. (“TomTom”). The SDK comprises all software, binaries and source code made available by TomTom for it, whether through the TomTom Developer Portal, package registries (e.g. npm) or otherwise. The example applications that TomTom publishes in public code repositories (e.g. GitHub) are not part of the SDK: they are licensed separately, under the license distributed with them. This Agreement with TomTom consists of the terms and conditions below together with the Data Processing Schedule. You should not use the SDK if you cannot agree to both.
|
|
6
6
|
|
|
7
7
|
You may not use the SDK or accept this Agreement if you are barred from receiving it under the laws of the European Union or of any other country, including the country in which you are resident or from which you use the SDK. If you accept this Agreement on behalf of your employer or another entity, you represent and warrant that you have full legal authority to bind that employer or entity. If you do not have that authority, you may not accept this Agreement or use the SDK on their behalf.
|
|
8
8
|
|
|
@@ -14,7 +14,7 @@ You may not use the SDK or accept this Agreement if you are barred from receivin
|
|
|
14
14
|
|
|
15
15
|
3.1. You agree to use the SDK only for purposes permitted by (a) this Agreement and (b) any applicable law, regulation or generally accepted practice or guideline in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United States or other relevant countries).
|
|
16
16
|
|
|
17
|
-
3.2. Other than as permitted by applicable legislation, you are prohibited from copying (except for backup purposes), modifying, adapting, (re)distributing, renting, lending, publicly presenting, decompiling, reverse engineering, disassembling or creating derivative works of the SDK or any part of it. Notwithstanding the foregoing,
|
|
17
|
+
3.2. Other than as permitted by applicable legislation, you are prohibited from copying (except for backup purposes), modifying, adapting, (re)distributing, renting, lending, publicly presenting, decompiling, reverse engineering, disassembling or creating derivative works of the SDK or any part of it. Notwithstanding the foregoing, you may inspect the SDK as distributed to you, including any source code embedded in its source maps, solely for the purpose of debugging your Permitted Application, provided that it is not shared or redistributed. The readability of the SDK’s source code in its distribution does not constitute “Open-Source” licensing and grants you no rights under any Open Source Initiative (OSI) approved license, nor shall it be construed as a grant of rights to modify, fork or redistribute the SDK beyond those expressly granted in Clause 1 and this Clause 3.2.
|
|
18
18
|
|
|
19
19
|
3.3. You may not use the SDK in connection with any illegal, fraudulent, dishonest or unethical activity or behaviour, and in particular not to create or develop, or help others create or develop, a product, service or library that competes, directly or indirectly, with the SDK or the TomTom APIs.
|
|
20
20
|
|
|
@@ -78,7 +78,7 @@ You may not use the SDK or accept this Agreement if you are barred from receivin
|
|
|
78
78
|
|
|
79
79
|
11.4. The TomTom APIs and the SDK are provided as “Commercial Computer Software” or “restricted computer software”. Use, duplication or disclosure by the U.S. Government or a U.S. Government subcontractor is subject to the restrictions set forth in 48 C.F.R. Section 12.212 or 48 C.F.R. 227.2702, as applicable, or successor provisions. In respect of the Map API and Search API, the manufacturer is TomTom Global Content B.V.
|
|
80
80
|
|
|
81
|
-
11.5. By submitting any suggestion, bug fix or code contribution (“Contribution”) to TomTom (e.g. via a GitHub
|
|
81
|
+
11.5. By submitting any suggestion, bug fix or code contribution (“Contribution”) to TomTom (e.g. via a GitHub issue or discussion), you grant TomTom a perpetual, irrevocable, worldwide, royalty-free and non-exclusive license to use, reproduce, modify and distribute the Contribution as part of the SDK. You represent that you have the legal right to grant this license and that the Contribution does not infringe any third-party intellectual property rights.
|
|
82
82
|
|
|
83
83
|
THIRD PARTY SOFTWARE NOTICES
|
|
84
84
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Viewport Places Plugin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Plugin for the [TomTom Maps SDK for JavaScript](https://docs.tomtom.com/maps-sdk-js/introduction/overview) that keeps places in sync with the current map viewport: each search you add gets its own place module, which searches again whenever the map moves.
|
|
4
4
|
|
|
5
5
|
## Docs & examples
|
|
6
6
|
|
|
@@ -9,13 +9,13 @@ Lightweight plugin for the [TomTom Maps SDK for Javascript](https://docs.tomtom.
|
|
|
9
9
|
|
|
10
10
|
## Quickstart
|
|
11
11
|
|
|
12
|
-
Note:
|
|
12
|
+
Note: this plugin declares `@tomtom-org/maps-sdk` as a peer dependency — ensure the SDK is installed in your project.
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
15
|
npm install @tomtom-org/maps-sdk maplibre-gl @tomtom-org/maps-sdk-plugin-viewport-places
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
1. Follow the SDK [Project setup](https://docs.tomtom.com/maps-sdk-js/
|
|
18
|
+
1. Follow the SDK [Project setup](https://docs.tomtom.com/maps-sdk-js/introduction/project-setup) or the Map [quickstart](https://docs.tomtom.com/maps-sdk-js/guides/map/quickstart) to create and initialize a `TomTomMap`.
|
|
19
19
|
|
|
20
20
|
2. Import and use the plugin (plugin-specific steps only):
|
|
21
21
|
|
|
@@ -25,11 +25,22 @@ import { ViewportPlaces } from '@tomtom-org/maps-sdk-plugin-viewport-places';
|
|
|
25
25
|
// assume `map` is your initialized TomTomMap instance
|
|
26
26
|
const viewportPlaces = new ViewportPlaces(map);
|
|
27
27
|
|
|
28
|
+
// a text search
|
|
28
29
|
await viewportPlaces.add({
|
|
29
30
|
id: 'restaurants',
|
|
30
31
|
searchOptions: { query: 'restaurant', limit: 40 },
|
|
31
32
|
minZoom: 12,
|
|
32
33
|
});
|
|
34
|
+
|
|
35
|
+
// a POI category search
|
|
36
|
+
await viewportPlaces.addPOICategories({
|
|
37
|
+
id: 'parking',
|
|
38
|
+
categories: ['PARKING_GARAGE', 'CHARGING_LOCATION'],
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// change or drop a place module by its id
|
|
42
|
+
await viewportPlaces.update({ id: 'restaurants', searchOptions: { query: 'pizza' } });
|
|
43
|
+
viewportPlaces.remove('parking');
|
|
33
44
|
```
|
|
34
45
|
|
|
35
46
|
Place modules are rendered bottom-up in the order they are added: the first added module appears at the bottom and later modules are stacked on top.
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { PlacesModule, PlacesModuleConfig, TomTomMap } from "@tomtom-org/maps-sd
|
|
|
3
3
|
import { FuzzySearchParams } from "@tomtom-org/maps-sdk/services";
|
|
4
4
|
//#region src/viewportPlaces.d.ts
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* The common options for adding a viewport places module.
|
|
7
7
|
*
|
|
8
8
|
* @group Viewport Places
|
|
9
9
|
*/
|
|
@@ -12,8 +12,8 @@ export type ViewportPlacesAddCommonOptions = {
|
|
|
12
12
|
* Optional unique identifier for the viewport places module.
|
|
13
13
|
*
|
|
14
14
|
* @remarks
|
|
15
|
-
* * If
|
|
16
|
-
* *
|
|
15
|
+
* * If you don't provide it, a random ID is generated.
|
|
16
|
+
* * To update or remove this place module later, provide a fixed ID.
|
|
17
17
|
*/
|
|
18
18
|
id?: string;
|
|
19
19
|
/**
|
|
@@ -26,7 +26,7 @@ export type ViewportPlacesAddCommonOptions = {
|
|
|
26
26
|
maxZoom?: number;
|
|
27
27
|
};
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* The full options for adding a viewport places module.
|
|
30
30
|
*
|
|
31
31
|
* @group Viewport Places
|
|
32
32
|
*/
|
|
@@ -35,8 +35,8 @@ export type ViewportPlacesAddOptions = ViewportPlacesAddCommonOptions & {
|
|
|
35
35
|
* The search parameters to query places for this place module.
|
|
36
36
|
*
|
|
37
37
|
* @remarks
|
|
38
|
-
* `geoBias`, `cursor` and `signal` are not accepted here
|
|
39
|
-
* page of the current viewport and owns an `AbortSignal
|
|
38
|
+
* `geoBias`, `cursor` and `signal` are not accepted here. Each module always searches the first
|
|
39
|
+
* page of the current viewport and owns an `AbortSignal`, so a new search cancels the one it
|
|
40
40
|
* supersedes.
|
|
41
41
|
*/
|
|
42
42
|
searchOptions: Omit<FuzzySearchParams, 'geoBias' | 'cursor' | 'signal'>;
|
|
@@ -46,7 +46,7 @@ export type ViewportPlacesAddOptions = ViewportPlacesAddCommonOptions & {
|
|
|
46
46
|
placesModuleConfig?: PlacesModuleConfig;
|
|
47
47
|
};
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
49
|
+
* The options for updating a viewport places module.
|
|
50
50
|
*
|
|
51
51
|
* @group Viewport Places
|
|
52
52
|
*/
|
|
@@ -54,15 +54,15 @@ export type ViewportPlacesOptions = Omit<ViewportPlacesAddOptions, 'id'> & {
|
|
|
54
54
|
/**
|
|
55
55
|
* The unique identifier of the place module to update.
|
|
56
56
|
* @remarks
|
|
57
|
-
* *
|
|
57
|
+
* * It must match an existing place module added with an "add" method.
|
|
58
58
|
*/
|
|
59
59
|
id: string;
|
|
60
60
|
};
|
|
61
61
|
/**
|
|
62
62
|
* A class for managing dynamic searched place modules on a TomTom map.
|
|
63
63
|
*
|
|
64
|
-
* It
|
|
65
|
-
*
|
|
64
|
+
* It uses the SDK search service to keep its place modules current automatically as the
|
|
65
|
+
* map viewport changes.
|
|
66
66
|
*
|
|
67
67
|
* @group Viewport Places
|
|
68
68
|
*/
|
|
@@ -87,14 +87,13 @@ export declare class ViewportPlaces {
|
|
|
87
87
|
*/
|
|
88
88
|
private searchAndDisplay;
|
|
89
89
|
/**
|
|
90
|
-
* Adds a PlacesModule that
|
|
90
|
+
* Adds a PlacesModule that shows places from fuzzy search parameters and updates automatically as the map moves.
|
|
91
91
|
*
|
|
92
92
|
* @remarks
|
|
93
93
|
* * Each call to "add" creates a new place module and places it above previously added modules.
|
|
94
|
-
* * Place modules are rendered bottom-up in the order they are added
|
|
94
|
+
* * Place modules are rendered bottom-up in the order they are added. The first added module is displayed at the bottom, and later modules are stacked on top of earlier ones.
|
|
95
95
|
* * The default places module marker type is 'base-map' unless overridden in the options.
|
|
96
96
|
*
|
|
97
|
-
* @param options - The options for the place module.
|
|
98
97
|
* @returns A promise that resolves to the PlacesModule instance managing the module.
|
|
99
98
|
*/
|
|
100
99
|
add(options: ViewportPlacesAddOptions): Promise<PlacesModule>;
|
|
@@ -104,7 +103,7 @@ export declare class ViewportPlaces {
|
|
|
104
103
|
*
|
|
105
104
|
* @remarks
|
|
106
105
|
* * This is a convenience wrapper over `add` that configures a category-based search for a PlacesModule.
|
|
107
|
-
* * Each call creates a new place module that
|
|
106
|
+
* * Each call creates a new place module that is stacked on top of previously added modules.
|
|
108
107
|
*
|
|
109
108
|
* @param options - The options for the category-based place module.
|
|
110
109
|
* @returns A promise that resolves to the PlacesModule instance managing the module.
|
|
@@ -125,8 +124,7 @@ export declare class ViewportPlaces {
|
|
|
125
124
|
removeAll(): void;
|
|
126
125
|
/**
|
|
127
126
|
* Updates the search and display options for an existing place module identified by its ID.
|
|
128
|
-
*
|
|
129
|
-
* @param newOptions - The new options to apply.
|
|
127
|
+
* It applies the new options immediately and refreshes the place module.
|
|
130
128
|
* @throws Error if the place module with the given ID does not exist.
|
|
131
129
|
*/
|
|
132
130
|
update(newOptions: ViewportPlacesOptions): Promise<void>;
|
package/dist/index.es.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
import{generateId as e}from"@tomtom-org/maps-sdk/core";import{PlacesModule as s}from"@tomtom-org/maps-sdk/map";import{createLatestRequest as o,discoverPlaces as t}from"@tomtom-org/maps-sdk/services";var i=class{map;registeredModules={};mapLibreMap;constructor(e){this.map=e,this.mapLibreMap=e.mapLibreMap}getRegisteredModule(e){const s=this.registeredModules[e];if(!s)throw new Error(`Place module with id ${e} not found`);return s}async searchAndDisplay(e){const s=this.registeredModules[e];if(!s)return;const{placesModule:o,options:i,latestSearch:a}=s,r=this.mapLibreMap.getZoom();if(i.minZoom&&r<i.minZoom||i.maxZoom&&r>i.maxZoom)return a.cancel(),void(await o.clear());const n=await a.run(e=>t({geoBias:{boundingBox:this.map.getBBox()},limit:100,...i.searchOptions,signal:e}));n.current&&await o.show(n.value)}async add(t){const i=t.id??e(),a={...t,placesModuleConfig:{markerType:"base-map",...t.placesModuleConfig}},r=await s.create(this.map,a.placesModuleConfig),n=()=>this.searchAndDisplay(i),p=this.mapLibreMap.on("moveend",n);return this.registeredModules[i]={placesModule:r,subscription:p,options:a,latestSearch:o()},await n(),r}async addPOICategories(e){return this.add({...e,searchOptions:{filters:{poiCategories:e.categories}}})}remove(e){const s=this.getRegisteredModule(e);s.latestSearch.cancel(),s.placesModule.clear(),s.subscription.unsubscribe(),delete this.registeredModules[e]}removeAll(){Object.keys(this.registeredModules).forEach(e=>this.remove(e))}async update(e){const s=this.getRegisteredModule(e.id),o=s.options;s.options={...o,...e,searchOptions:{...o.searchOptions,...e.searchOptions,filters:{...o.searchOptions.filters,...e.searchOptions.filters}},placesModuleConfig:{...o.placesModuleConfig,...e.placesModuleConfig}},s.placesModule.applyConfig(s.options.placesModuleConfig),await this.searchAndDisplay(e.id)}};export{i as ViewportPlaces};
|
|
2
|
-
//# sourceMappingURL=index.es.js.map
|
|
1
|
+
import{generateId as e}from"@tomtom-org/maps-sdk/core";import{PlacesModule as s}from"@tomtom-org/maps-sdk/map";import{createLatestRequest as o,discoverPlaces as t}from"@tomtom-org/maps-sdk/services";var i=class{map;registeredModules={};mapLibreMap;constructor(e){this.map=e,this.mapLibreMap=e.mapLibreMap}getRegisteredModule(e){const s=this.registeredModules[e];if(!s)throw new Error(`Place module with id ${e} not found`);return s}async searchAndDisplay(e){const s=this.registeredModules[e];if(!s)return;const{placesModule:o,options:i,latestSearch:a}=s,r=this.mapLibreMap.getZoom();if(i.minZoom&&r<i.minZoom||i.maxZoom&&r>i.maxZoom)return a.cancel(),void(await o.clear());const n=await a.run(e=>t({geoBias:{boundingBox:this.map.getBBox()},limit:100,...i.searchOptions,signal:e}));n.current&&await o.show(n.value)}async add(t){const i=t.id??e(),a={...t,placesModuleConfig:{markerType:"base-map",...t.placesModuleConfig}},r=await s.create(this.map,a.placesModuleConfig),n=()=>this.searchAndDisplay(i),p=this.mapLibreMap.on("moveend",n);return this.registeredModules[i]={placesModule:r,subscription:p,options:a,latestSearch:o()},await n(),r}async addPOICategories(e){return this.add({...e,searchOptions:{filters:{poiCategories:e.categories}}})}remove(e){const s=this.getRegisteredModule(e);s.latestSearch.cancel(),s.placesModule.clear(),s.subscription.unsubscribe(),delete this.registeredModules[e]}removeAll(){Object.keys(this.registeredModules).forEach(e=>this.remove(e))}async update(e){const s=this.getRegisteredModule(e.id),o=s.options;s.options={...o,...e,searchOptions:{...o.searchOptions,...e.searchOptions,filters:{...o.searchOptions.filters,...e.searchOptions.filters}},placesModuleConfig:{...o.placesModuleConfig,...e.placesModuleConfig}},s.placesModule.applyConfig(s.options.placesModuleConfig),await this.searchAndDisplay(e.id)}};export{i as ViewportPlaces};
|
package/package.json
CHANGED
|
@@ -2,30 +2,30 @@
|
|
|
2
2
|
"name": "@tomtom-org/maps-sdk-plugin-viewport-places",
|
|
3
3
|
"author": "TomTom International B.V.",
|
|
4
4
|
"license": "See in LICENSE.txt",
|
|
5
|
-
"version": "0.5.
|
|
5
|
+
"version": "0.5.3",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"description": "Plugin to leverage search to show places on the current viewport that refresh as the map moves",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
9
|
"peerDependencies": {
|
|
10
|
-
"@tomtom-org/maps-sdk": ">=0.
|
|
10
|
+
"@tomtom-org/maps-sdk": ">=0.64.0 <1.0.0 || >=1.0.0-rc.0 <1.0.0"
|
|
11
11
|
},
|
|
12
12
|
"devDependencies": {
|
|
13
13
|
"@tsconfig/recommended": "^1.0.13",
|
|
14
|
-
"@types/node": "^26.6.
|
|
14
|
+
"@types/node": "^26.6.4",
|
|
15
15
|
"@vitest/coverage-v8": "^4.1.11",
|
|
16
|
-
"rolldown": "^1.2.
|
|
17
|
-
"ts-node": "^10.9.2",
|
|
16
|
+
"rolldown": "^1.2.12",
|
|
18
17
|
"typescript": "^6.0.3",
|
|
19
|
-
"vite": "^8.3.
|
|
18
|
+
"vite": "^8.3.2",
|
|
20
19
|
"vitest": "^4.1.11",
|
|
21
|
-
"@tomtom-org/maps-sdk": "0.
|
|
20
|
+
"@tomtom-org/maps-sdk": "1.0.0-rc.1"
|
|
22
21
|
},
|
|
23
22
|
"files": [
|
|
24
23
|
"dist",
|
|
25
24
|
"package.json",
|
|
26
25
|
"README.md",
|
|
27
26
|
"LICENSE.txt",
|
|
28
|
-
"THIRD_PARTY.txt"
|
|
27
|
+
"THIRD_PARTY.txt",
|
|
28
|
+
"!**/*.map"
|
|
29
29
|
],
|
|
30
30
|
"exports": {
|
|
31
31
|
".": {
|
package/dist/index.es.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","names":["generateId","PlacesModule","createLatestRequest","discoverPlaces","ViewportPlaces","map","registeredModules","mapLibreMap","constructor","this","getRegisteredModule","id","entry","Error","searchAndDisplay","placesModule","options","latestSearch","zoom","getZoom","minZoom","maxZoom","cancel","clear","search","run","signal","geoBias","boundingBox","getBBox","limit","searchOptions","current","show","value","add","effectiveOptions","placesModuleConfig","markerType","create","subscription","on","addPOICategories","filters","poiCategories","categories","remove","unsubscribe","removeAll","Object","keys","forEach","key","update","newOptions","currentOptions","applyConfig"],"sources":["../src/viewportPlaces.ts"],"sourcesContent":["import { generateId, POICategory } from '@tomtom-org/maps-sdk/core';\nimport { PlacesModule, type PlacesModuleConfig, TomTomMap } from '@tomtom-org/maps-sdk/map';\nimport {\n createLatestRequest,\n discoverPlaces,\n type FuzzySearchParams,\n type LatestRequest,\n} from '@tomtom-org/maps-sdk/services';\nimport type { Subscription } from 'maplibre-gl';\n\n/**\n * Common Options when adding a viewport places module.\n *\n * @group Viewport Places\n */\nexport type ViewportPlacesAddCommonOptions = {\n /**\n * Optional unique identifier for the viewport places module.\n *\n * @remarks\n * * If not provided, a random ID will be generated.\n * * If you need to keep updating or removing this place module later, provide a fixed ID.\n */\n id?: string;\n /**\n * Minimum zoom level at which the place module is visible.\n */\n minZoom?: number;\n /**\n * Maximum zoom level at which the place module is visible.\n */\n maxZoom?: number;\n};\n\n/**\n * Full Options when adding a viewport places module.\n *\n * @group Viewport Places\n */\nexport type ViewportPlacesAddOptions = ViewportPlacesAddCommonOptions & {\n /**\n * The search parameters to query places for this place module.\n *\n * @remarks\n * `geoBias`, `cursor` and `signal` are not accepted here: each module always searches the first\n * page of the current viewport and owns an `AbortSignal` so that a new search cancels the one it\n * supersedes.\n */\n searchOptions: Omit<FuzzySearchParams, 'geoBias' | 'cursor' | 'signal'>;\n /**\n * Optional configuration for the places module, such as styling.\n */\n placesModuleConfig?: PlacesModuleConfig;\n};\n\n/**\n * Options when updating a viewport places module.\n *\n * @group Viewport Places\n */\nexport type ViewportPlacesOptions = Omit<ViewportPlacesAddOptions, 'id'> & {\n /**\n * The unique identifier of the place module to update.\n * @remarks\n * * This ID must correspond to an existing place module added via an \"add\" method.\n */\n id: string;\n};\n\n/**\n * A class for managing dynamic searched place modules on a TomTom map.\n *\n * It leverages the SDK search service to maintain place modules that automatically\n * update and stay current as the map viewport changes.\n *\n * @group Viewport Places\n */\nexport class ViewportPlaces {\n /**\n * Internal map of registered place modules, keyed by their `id`.\n * @private\n */\n private registeredModules: Record<\n string,\n {\n options: ViewportPlacesAddOptions;\n placesModule: PlacesModule;\n subscription: Subscription;\n /** Retires this module's in-flight search when a newer viewport supersedes it. */\n latestSearch: LatestRequest;\n }\n > = {};\n private readonly mapLibreMap;\n\n /**\n * Creates an instance of ViewportPlaces bound to a TomTom map.\n * @param map - The TomTom map instance to attach place modules to.\n */\n constructor(private readonly map: TomTomMap) {\n this.mapLibreMap = map.mapLibreMap;\n }\n\n private getRegisteredModule(id: string) {\n const entry = this.registeredModules[id];\n if (!entry) {\n throw new Error(`Place module with id ${id} not found`);\n }\n\n return entry;\n }\n\n /**\n * Performs the update logic for a registered PlacesModule, cancelling whatever search that\n * module still has in flight.\n * @param id - The unique identifier of the registered place module to refresh.\n */\n private async searchAndDisplay(id: string): Promise<void> {\n const entry = this.registeredModules[id];\n if (!entry) return;\n\n const { placesModule, options, latestSearch } = entry;\n\n const zoom = this.mapLibreMap.getZoom();\n if ((options.minZoom && zoom < options.minZoom) || (options.maxZoom && zoom > options.maxZoom)) {\n // A search left running would repopulate what this clears\n latestSearch.cancel();\n await placesModule.clear();\n return;\n }\n\n const search = await latestSearch.run((signal) =>\n discoverPlaces({\n geoBias: { boundingBox: this.map.getBBox() },\n limit: 100,\n ...options.searchOptions,\n signal,\n }),\n );\n if (search.current) await placesModule.show(search.value);\n }\n\n /**\n * Adds a PlacesModule that displays places based on fuzzy search parameters and automatically updates as the map moves.\n *\n * @remarks\n * * Each call to \"add\" creates a new place module and places it above previously added modules.\n * * Place modules are rendered bottom-up in the order they are added: the first added module is displayed at the bottom, and later modules are stacked on top of earlier ones.\n * * The default places module marker type is 'base-map' unless overridden in the options.\n *\n * @param options - The options for the place module.\n * @returns A promise that resolves to the PlacesModule instance managing the module.\n */\n async add(options: ViewportPlacesAddOptions): Promise<PlacesModule> {\n const id = options.id ?? generateId();\n const effectiveOptions = {\n ...options,\n placesModuleConfig: { markerType: 'base-map', ...options.placesModuleConfig } satisfies PlacesModuleConfig,\n };\n\n const placesModule = await PlacesModule.create(this.map, effectiveOptions.placesModuleConfig);\n const searchAndDisplay = () => this.searchAndDisplay(id);\n\n const subscription = this.mapLibreMap.on('moveend', searchAndDisplay);\n this.registeredModules[id] = {\n placesModule,\n subscription,\n options: effectiveOptions,\n latestSearch: createLatestRequest(),\n };\n await searchAndDisplay();\n return placesModule;\n }\n\n /**\n * Adds a PlacesModule for specific POI categories that updates automatically as the map moves.\n * The POIs are shown in the same style as the base map.\n *\n * @remarks\n * * This is a convenience wrapper over `add` that configures a category-based search for a PlacesModule.\n * * Each call creates a new place module that will be stacked on top of previously added modules.\n *\n * @param options - The options for the category-based place module.\n * @returns A promise that resolves to the PlacesModule instance managing the module.\n */\n async addPOICategories(\n options: ViewportPlacesAddCommonOptions & { categories: POICategory[] },\n ): Promise<PlacesModule> {\n return this.add({\n ...options,\n searchOptions: { filters: { poiCategories: options.categories } },\n });\n }\n\n /**\n * Removes a specific place module by its ID, stopping its updates and clearing the displayed places.\n *\n * @param id - The unique identifier of the PlacesModule to remove.\n * @throws Error if the place module with the given ID does not exist.\n */\n remove(id: string): void {\n const entry = this.getRegisteredModule(id);\n entry.latestSearch.cancel();\n entry.placesModule.clear();\n entry.subscription.unsubscribe();\n delete this.registeredModules[id];\n }\n\n /**\n * Removes all registered place modules, stopping their updates and clearing all displayed places.\n */\n removeAll(): void {\n Object.keys(this.registeredModules).forEach((key) => this.remove(key));\n }\n\n /**\n * Updates the search and display options for an existing place module identified by its ID.\n * This will immediately apply the new options and refresh the place module accordingly.\n * @param newOptions - The new options to apply.\n * @throws Error if the place module with the given ID does not exist.\n */\n async update(newOptions: ViewportPlacesOptions): Promise<void> {\n const entry = this.getRegisteredModule(newOptions.id);\n const currentOptions = entry.options;\n\n // Update the options by merging current and new options:\n entry.options = {\n ...currentOptions,\n ...newOptions,\n // search and places display options are merged incrementally, search filters included:\n searchOptions: {\n ...currentOptions.searchOptions,\n ...newOptions.searchOptions,\n filters: { ...currentOptions.searchOptions.filters, ...newOptions.searchOptions.filters },\n },\n placesModuleConfig: { ...currentOptions.placesModuleConfig, ...newOptions.placesModuleConfig },\n };\n // Update the places module configuration and refresh the display:\n entry.placesModule.applyConfig(entry.options.placesModuleConfig);\n await this.searchAndDisplay(newOptions.id);\n }\n}\n"],"mappings":"uMA6EA,IAAaI,EAAb,MAqBiCC,IAhB7BC,kBASI,CAAC,EACLC,YAMA,WAAAC,CAAYH,GAAiBI,KAAAJ,IAAAA,EACzBI,KAAKF,YAAcF,EAAIE,WAC3B,CAEA,mBAAAG,CAA4BC,GACxB,MAAMC,EAAQH,KAAKH,kBAAkBK,GACrC,IAAKC,EACD,MAAM,IAAIC,MAAM,wBAAwBF,eAG5C,OAAOC,CACX,CAOA,sBAAcE,CAAiBH,GAC3B,MAAMC,EAAQH,KAAKH,kBAAkBK,GACrC,IAAKC,EAAO,OAEZ,MAAMG,aAAEA,EAAAC,QAAcA,EAAAC,aAASA,GAAiBL,EAE1CM,EAAOT,KAAKF,YAAYY,UAC9B,GAAKH,EAAQI,SAAWF,EAAOF,EAAQI,SAAaJ,EAAQK,SAAWH,EAAOF,EAAQK,QAIlF,OAFAJ,EAAaK,oBACPP,EAAaQ,SAIvB,MAAMC,QAAeP,EAAaQ,IAAKC,GACnCvB,EAAe,CACXwB,QAAS,CAAEC,YAAanB,KAAKJ,IAAIwB,WACjCC,MAAO,OACJd,EAAQe,cACXL,YAGJF,EAAOQ,eAAejB,EAAakB,KAAKT,EAAOU,MACvD,CAaA,SAAMC,CAAInB,GACN,MAAML,EAAKK,EAAQL,IAAMX,IACnBoC,EAAmB,IAClBpB,EACHqB,mBAAoB,CAAEC,WAAY,cAAetB,EAAQqB,qBAGvDtB,QAAqBd,EAAasC,OAAO9B,KAAKJ,IAAK+B,EAAiBC,oBACpEvB,EAAA,IAAyBL,KAAKK,iBAAiBH,GAE/C6B,EAAe/B,KAAKF,YAAYkC,GAAG,UAAW3B,GAQpD,OAPAL,KAAKH,kBAAkBK,GAAM,CACzBI,eACAyB,eACAxB,QAASoB,EACTnB,aAAcf,WAEZY,IACCC,CACX,CAaA,sBAAM2B,CACF1B,GAEA,OAAOP,KAAK0B,IAAI,IACTnB,EACHe,cAAe,CAAEY,QAAS,CAAEC,cAAe5B,EAAQ6B,cAE3D,CAQA,MAAAC,CAAOnC,GACH,MAAMC,EAAQH,KAAKC,oBAAoBC,GACvCC,EAAMK,aAAaK,SACnBV,EAAMG,aAAaQ,QACnBX,EAAM4B,aAAaO,qBACZtC,KAAKH,kBAAkBK,EAClC,CAKA,SAAAqC,GACIC,OAAOC,KAAKzC,KAAKH,mBAAmB6C,QAASC,GAAQ3C,KAAKqC,OAAOM,GACrE,CAQA,YAAMC,CAAOC,GACT,MAAM1C,EAAQH,KAAKC,oBAAoB4C,EAAW3C,IAC5C4C,EAAiB3C,EAAMI,QAG7BJ,EAAMI,QAAU,IACTuC,KACAD,EAEHvB,cAAe,IACRwB,EAAexB,iBACfuB,EAAWvB,cACdY,QAAS,IAAKY,EAAexB,cAAcY,WAAYW,EAAWvB,cAAcY,UAEpFN,mBAAoB,IAAKkB,EAAelB,sBAAuBiB,EAAWjB,qBAG9EzB,EAAMG,aAAayC,YAAY5C,EAAMI,QAAQqB,0BACvC5B,KAAKK,iBAAiBwC,EAAW3C,GAC3C"}
|