@any-routing/here-data-provider 0.1.0 → 1.0.0-rc.2

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.
@@ -0,0 +1,425 @@
1
+ import { decode } from '@here/flexpolyline';
2
+ import simplify from 'simplify-js';
3
+ import bbox from '@turf/bbox';
4
+ import { featureCollection, lineString } from '@turf/helpers';
5
+
6
+ import type {
7
+ BaseOptions,
8
+ GeoJsonSplitStrategy,
9
+ HereApiResponse,
10
+ HereRawDynamicSpeedInfo,
11
+ HereRawRoute,
12
+ HereRawSection,
13
+ HereRawSpan,
14
+ HereRawToll,
15
+ HereRouteSummary,
16
+ HereRoutingData,
17
+ RouteExcludeNoticeDefinitions,
18
+ TurnByTurnAction,
19
+ } from './here-provider.types';
20
+
21
+ import { selectRouteByStrategy } from './utils/select-route-strategy';
22
+ import { Requester, UnauthorizedError, type WaypointPosition } from '@any-routing/core';
23
+ import type { BBox, Feature, FeatureCollection, LineString } from 'geojson';
24
+
25
+ export type ExecutorRequestOptions = { url: string } & BaseOptions;
26
+
27
+ /** Properties attached to each rendered segment of a route's shape. */
28
+ type ShapeFeatureProperties = {
29
+ waypoint: number;
30
+ routeId: number;
31
+ jamFactor?: number;
32
+ isMarginalChunk?: boolean;
33
+ selected?: boolean;
34
+ };
35
+
36
+ type SectionAccumulator = {
37
+ distance: number;
38
+ cost: number;
39
+ waypoints: WaypointPosition[];
40
+ path: number[][];
41
+ durationTime: number;
42
+ turnByTurnActions: TurnByTurnAction[];
43
+ shape: FeatureCollection<LineString, ShapeFeatureProperties>;
44
+ shapePath: number[][];
45
+ waypointIndex: number;
46
+ };
47
+
48
+ export class HereExecutor {
49
+ private readonly requester = new Requester();
50
+
51
+ async request(opts: ExecutorRequestOptions): Promise<HereRoutingData> {
52
+ try {
53
+ const data = (await this.requester.request(opts.url, {
54
+ method: 'POST',
55
+ headers: {
56
+ Accept: 'application/json',
57
+ 'Content-Type': 'application/json',
58
+ },
59
+ body: JSON.stringify({}),
60
+ ...opts.requestParams,
61
+ })) as HereApiResponse;
62
+
63
+ if (
64
+ !data.routes?.length ||
65
+ (opts.routeExcludeNotice && violatedResponseNotices(data, opts.routeExcludeNotice))
66
+ ) {
67
+ throw new Error('No routes found');
68
+ }
69
+
70
+ const routeSummaries = data.routes.map((route, routeId) =>
71
+ summarizeRoute(route, routeId, opts),
72
+ );
73
+
74
+ const selectedRouteId = selectRouteByStrategy(routeSummaries, opts.selectRouteStrategy);
75
+
76
+ const features = routeSummaries.flatMap((routeSummary, fid) =>
77
+ routeSummary.shape.features.map((feature) => {
78
+ return {
79
+ id: fid,
80
+ ...feature,
81
+ properties: {
82
+ ...feature.properties,
83
+ id: fid,
84
+ routeId: routeSummary.id,
85
+ },
86
+ };
87
+ }),
88
+ );
89
+
90
+ const routesShapeGeojson = featureCollection(features);
91
+
92
+ return {
93
+ routesShapeBounds: bbox(routesShapeGeojson) as BBox,
94
+ rawResponse: data,
95
+ routes: routeSummaries,
96
+ selectedRouteId,
97
+ routesShapeGeojson,
98
+ version: performance.now(),
99
+ latest: !this.requester.hasPendingRequests,
100
+ requestOptions: opts,
101
+ };
102
+ } catch (error: unknown) {
103
+ if (error instanceof Response) {
104
+ const body = await error.json();
105
+
106
+ if (error.status === 401) {
107
+ throw new UnauthorizedError(body);
108
+ }
109
+ }
110
+
111
+ throw error;
112
+ }
113
+ }
114
+
115
+ hasPendingRequests() {
116
+ return this.requester.hasPendingRequests;
117
+ }
118
+
119
+ abortAllRequests() {
120
+ this.requester.abortAllRequests();
121
+ }
122
+ }
123
+
124
+ /** Which split strategies apply for the current request mode, if any. */
125
+ function getSplitStrategies(options: ExecutorRequestOptions): GeoJsonSplitStrategy[] | undefined {
126
+ return options.geoJSONShapeSplitStrategies;
127
+ }
128
+
129
+ function shouldSplitShape(options: ExecutorRequestOptions): boolean {
130
+ const strategies = getSplitStrategies(options);
131
+ return !!strategies && strategies.length > 0;
132
+ }
133
+
134
+ /**
135
+ * Sum of all toll fares for a section.
136
+ *
137
+ * Bug fix (typing): `fare.convertedPrice || fare.price` can legitimately be
138
+ * `undefined` if HERE returns a fare with neither field populated; reading
139
+ * `.value` off that used to be an implicit `any` that would only blow up at
140
+ * runtime. With real types this is now enforced at compile time via `?.` +
141
+ * a `0` fallback instead of throwing on an unexpected payload.
142
+ *
143
+ * Bug fix (logic, unchanged from prior pass): the previous implementation
144
+ * returned the result of `Array#forEach` (always `undefined`) from the
145
+ * outer `reduce` callback instead of returning the running total, so `cost`
146
+ * collapsed to `undefined`/`NaN` for any section that had tolls.
147
+ */
148
+ function computeSectionCost(section: HereRawSection): number {
149
+ return (section.tolls || []).reduce((costAcc: number, toll: HereRawToll) => {
150
+ const tollCost = (toll.fares || []).reduce(
151
+ (fareAcc: number, fare) => fareAcc + ((fare.convertedPrice ?? fare.price)?.value ?? 0),
152
+ 0,
153
+ );
154
+
155
+ return costAcc + tollCost;
156
+ }, 0);
157
+ }
158
+
159
+ /**
160
+ * Waypoints introduced by a section: the departure location (if it was an
161
+ * explicit, geocoded location) and, only for the section that ends the
162
+ * route, the arrival location.
163
+ *
164
+ * Simplified from the original condition
165
+ * `(sections.length >= 2 && index === last) || sections.length === 1`,
166
+ * which is logically identical to `index === last` (when there is only one
167
+ * section, index 0 already equals `sections.length - 1`).
168
+ */
169
+ function extractSectionWaypoints(
170
+ section: HereRawSection,
171
+ isLastSection: boolean,
172
+ ): WaypointPosition[] {
173
+ const waypoints: WaypointPosition[] = [];
174
+
175
+ // HERE's response typings don't expose `location` on a place even though
176
+ // the API always includes it for geocoded (`originalLocation`) points.
177
+ // `location` is already `{ lat, lng }` (see `HereRawPlace`), matching
178
+ // `WaypointPosition` exactly — no cast needed. The previous `as
179
+ // LngLatPosition` was papering over a shape mismatch: `LngLatPosition` is
180
+ // the tuple format `path`/`shapePath` use for GeoJSON coordinates, not
181
+ // the `{ lat, lng }` object format `RouteSummary.waypoints` expects.
182
+ if (section.departure.place.originalLocation) {
183
+ waypoints.push(section.departure.place.location);
184
+ }
185
+
186
+ if (section.arrival.place.originalLocation && isLastSection) {
187
+ waypoints.push(section.arrival.place.location);
188
+ }
189
+
190
+ return waypoints;
191
+ }
192
+
193
+ /**
194
+ * Approximates HERE's `jamFactor` scale ([0, 10], 0 = free flow, 10 =
195
+ * stationary traffic — see HERE Traffic API's `jamFactor` docs) from a
196
+ * span's `dynamicSpeedInfo`.
197
+ *
198
+ * HERE doesn't publish the exact algorithm behind
199
+ * `DynamicSpeedInfo.calculateJamFactor()` in the SDK, so this is
200
+ * necessarily an approximation, not a reproduction of HERE's formula.
201
+ *
202
+ * Bug fix: the previous version returned `trafficSpeed / baseSpeed`
203
+ * directly, which (a) sits on a [0, 1]-ish scale rather than HERE's
204
+ * documented [0, 10] `jamFactor` range, so any downstream code branching
205
+ * on "> 5 means bad traffic" style thresholds was silently wrong, and (b)
206
+ * divides by zero (→ `Infinity`/`NaN`) whenever `baseSpeed` is `0`, which
207
+ * happens on spans where HERE has no free-flow baseline.
208
+ */
209
+ function estimateJamFactor(info: HereRawDynamicSpeedInfo): number | undefined {
210
+ if (!info.baseSpeed || info.baseSpeed <= 0) {
211
+ return undefined;
212
+ }
213
+
214
+ const speedRatio = Math.min(Math.max(info.trafficSpeed / info.baseSpeed, 0), 1);
215
+
216
+ return +(10 * (1 - speedRatio)).toFixed(2);
217
+ }
218
+
219
+ /**
220
+ * Builds the shape segments for a section, optionally split by the
221
+ * configured strategies (currently only `jamFactor`), merging consecutive
222
+ * spans that share the same jam factor into a single feature.
223
+ */
224
+ function buildSectionShapes(
225
+ section: HereRawSection,
226
+ path: number[][],
227
+ shapePath: number[][],
228
+ routeId: number,
229
+ waypointIndex: number,
230
+ options: ExecutorRequestOptions,
231
+ ): Feature<LineString, ShapeFeatureProperties>[] {
232
+ if (!shouldSplitShape(options)) {
233
+ return [
234
+ lineString(shapePath, { waypoint: waypointIndex, routeId }) as Feature<
235
+ LineString,
236
+ ShapeFeatureProperties
237
+ >,
238
+ ];
239
+ }
240
+
241
+ const spans: HereRawSpan[] = section.spans ?? [];
242
+ const splitByJamFactor = getSplitStrategies(options)?.includes('jamFactor');
243
+
244
+ return spans.reduce(
245
+ (
246
+ shapesAcc: Feature<LineString, ShapeFeatureProperties>[],
247
+ span: HereRawSpan,
248
+ index: number,
249
+ ) => {
250
+ const closeOffset = index < spans.length - 1 ? spans[index + 1].offset : path.length - 1;
251
+ const spanPath = path.slice(span.offset, closeOffset + 1);
252
+ const spanShapePath = options.shapePolylinePrecision
253
+ ? simplifyPath(spanPath, options.shapePolylinePrecision)
254
+ : spanPath;
255
+ const isMarginalChunk = index === 0 || index === spans.length - 1;
256
+ const lastShape = shapesAcc[shapesAcc.length - 1];
257
+
258
+ const jamFactor = span.dynamicSpeedInfo
259
+ ? estimateJamFactor(span.dynamicSpeedInfo)
260
+ : undefined;
261
+
262
+ if (splitByJamFactor && jamFactor !== undefined) {
263
+ const prevJamFactor = lastShape?.properties?.jamFactor;
264
+
265
+ if (lastShape && jamFactor === prevJamFactor) {
266
+ lastShape.geometry.coordinates.push(...spanShapePath.slice(1));
267
+ lastShape.properties.isMarginalChunk = isMarginalChunk;
268
+ } else {
269
+ shapesAcc.push(
270
+ lineString(spanShapePath, {
271
+ waypoint: waypointIndex,
272
+ routeId,
273
+ jamFactor,
274
+ isMarginalChunk,
275
+ }) as Feature<LineString, ShapeFeatureProperties>,
276
+ );
277
+ }
278
+ } else if (lastShape) {
279
+ lastShape.geometry.coordinates.push(...spanShapePath.slice(1));
280
+ } else {
281
+ shapesAcc.push(
282
+ lineString(spanShapePath, {
283
+ waypoint: waypointIndex,
284
+ routeId,
285
+ isMarginalChunk,
286
+ }) as Feature<LineString, ShapeFeatureProperties>,
287
+ );
288
+ }
289
+
290
+ return shapesAcc;
291
+ },
292
+ [],
293
+ );
294
+ }
295
+
296
+ function createInitialSectionAccumulator(): SectionAccumulator {
297
+ return {
298
+ distance: 0,
299
+ cost: 0,
300
+ waypoints: [],
301
+ path: [],
302
+ durationTime: 0,
303
+ turnByTurnActions: [],
304
+ shape: featureCollection([]),
305
+ shapePath: [],
306
+ waypointIndex: 0,
307
+ };
308
+ }
309
+
310
+ const summarizeRoute = (
311
+ route: HereRawRoute,
312
+ routeId: number,
313
+ options: ExecutorRequestOptions,
314
+ ): HereRouteSummary => {
315
+ const { distance, cost, durationTime, waypoints, path, shape, shapePath, turnByTurnActions } =
316
+ route.sections.reduce(
317
+ (acc: SectionAccumulator, section: HereRawSection, index: number): SectionAccumulator => {
318
+ const sectionCost = computeSectionCost(section);
319
+ const sectionDuration = section.summary?.duration ?? 0;
320
+ const sectionDistance = section.summary?.length ?? 0;
321
+ const isLastSection = index === route.sections.length - 1;
322
+ const sectionWaypoints = extractSectionWaypoints(section, isLastSection);
323
+
324
+ const sectionPath = decodePolyline(section.polyline);
325
+ const sectionShapePath = options.shapePolylinePrecision
326
+ ? simplifyPath(sectionPath, options.shapePolylinePrecision)
327
+ : sectionPath;
328
+
329
+ const sectionTurnByTurnActions = (section.turnByTurnActions || []).map(
330
+ (action): TurnByTurnAction => {
331
+ const [lat, lng] = sectionPath[action.offset];
332
+
333
+ return {
334
+ ...action,
335
+ offset: acc.path.length + action.offset,
336
+ position: { lat, lng },
337
+ };
338
+ },
339
+ );
340
+
341
+ const sectionShapes = buildSectionShapes(
342
+ section,
343
+ sectionPath,
344
+ sectionShapePath,
345
+ routeId,
346
+ acc.waypointIndex,
347
+ options,
348
+ );
349
+
350
+ const nextSection = route.sections[index + 1];
351
+ const staysOnSameLeg = section.type === 'vehicle' && nextSection?.type === 'vehicle';
352
+
353
+ return {
354
+ // Bug fix: previously `acc.distance + section.summary?.length ?? 0`,
355
+ // which (due to operator precedence) evaluated as
356
+ // `(acc.distance + section.summary?.length) ?? 0` and reset the
357
+ // whole accumulated distance to 0 whenever a section had no summary.
358
+ distance: acc.distance + sectionDistance,
359
+ durationTime: acc.durationTime + sectionDuration,
360
+ cost: acc.cost + sectionCost,
361
+ waypoints: [...acc.waypoints, ...sectionWaypoints],
362
+ path: [...acc.path, ...sectionPath],
363
+ turnByTurnActions: [...acc.turnByTurnActions, ...sectionTurnByTurnActions],
364
+ shape: featureCollection([...(acc.shape?.features || []), ...sectionShapes]),
365
+ shapePath: [...acc.shapePath, ...sectionShapePath],
366
+ waypointIndex: staysOnSameLeg ? acc.waypointIndex + 1 : acc.waypointIndex,
367
+ };
368
+ },
369
+ createInitialSectionAccumulator(),
370
+ );
371
+
372
+ return {
373
+ durationTime,
374
+ distance,
375
+ cost,
376
+ path,
377
+ arriveTime: new Date(route.sections[route.sections.length - 1].arrival.time ?? 0),
378
+ departureTime: new Date(route.sections[0].departure.time ?? 0),
379
+ id: routeId,
380
+ waypoints,
381
+ label: route.routeLabels ? route.routeLabels.map((l) => l.name.value).join(', ') : undefined,
382
+ shape,
383
+ turnByTurnActions,
384
+ shapePath,
385
+ rawRoute: route,
386
+ };
387
+ };
388
+
389
+ const violatedResponseNotices = (
390
+ data: HereApiResponse,
391
+ routeExcludeNotice: RouteExcludeNoticeDefinitions,
392
+ ): boolean => {
393
+ if (violatedNotices(data.notices || [], routeExcludeNotice)) {
394
+ return true;
395
+ }
396
+
397
+ return (data.routes || []).some((route) =>
398
+ (route.sections || []).some((section) =>
399
+ violatedNotices(section.notices || [], routeExcludeNotice),
400
+ ),
401
+ );
402
+ };
403
+
404
+ const violatedNotices = (
405
+ notices: { code: string; severity: 'critical' | 'info' }[],
406
+ routeExcludeNotice: RouteExcludeNoticeDefinitions,
407
+ ): boolean => {
408
+ return notices.some((notice) => {
409
+ const definition = routeExcludeNotice[notice.severity];
410
+
411
+ return definition && (definition === 'all' || definition.includes(notice.code));
412
+ });
413
+ };
414
+
415
+ function decodePolyline(polyline: string): number[][] {
416
+ return decode(polyline).polyline;
417
+ }
418
+
419
+ function simplifyPath(path: number[][], precision: number): number[][] {
420
+ return simplify(
421
+ path.map(([x, y]) => ({ x, y })),
422
+ precision,
423
+ true,
424
+ ).map((p) => [+p.y.toFixed(6), +p.x.toFixed(6)]);
425
+ }
@@ -1,5 +1,6 @@
1
1
  import { expose } from 'comlink';
2
2
  import { HereExecutor } from './here.executor';
3
+
3
4
  const executor = new HereExecutor();
5
+
4
6
  expose(executor);
5
- //# sourceMappingURL=here.worker.js.map
@@ -0,0 +1,40 @@
1
+ import type { RouteSummary } from '@any-routing/core';
2
+ import { SelectRouteStrategy } from '../here-provider.types';
3
+
4
+ type RouteWithCost = RouteSummary & {
5
+ cost: number;
6
+ };
7
+
8
+ const hasCost = (route: RouteSummary): route is RouteWithCost =>
9
+ route.cost != null;
10
+
11
+ export function selectRouteByStrategy(routeSummaries: RouteSummary[], strategy?: SelectRouteStrategy) {
12
+ if (routeSummaries.length === 0) {
13
+ return null;
14
+ }
15
+
16
+ if (strategy === 'fastest') {
17
+ const fastest = routeSummaries.reduce(function (prev, current) {
18
+ return prev?.arriveTime.valueOf() < current?.arriveTime.valueOf() ? prev : current;
19
+ });
20
+
21
+ return fastest?.id;
22
+ } else if (strategy === 'shortest') {
23
+ const shortest = routeSummaries.reduce(function (prev, current) {
24
+ return prev?.distance < current?.distance ? prev : current;
25
+ });
26
+
27
+ return shortest?.id;
28
+ } else if (strategy === 'cheapest') {
29
+ const routesWithCost = routeSummaries.filter(hasCost);
30
+ const cheapest = routesWithCost.reduce(function (prev, current) {
31
+ return prev?.cost < current?.cost ? prev : current;
32
+ }, routesWithCost[0]);
33
+
34
+ return cheapest?.id;
35
+ } else if (strategy === 'none') {
36
+ return null;
37
+ }
38
+
39
+ return 0;
40
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "module": "es2022",
5
+ "forceConsistentCasingInFileNames": true,
6
+ "strict": true,
7
+ "importHelpers": true,
8
+ "noImplicitOverride": true,
9
+ "noImplicitReturns": true,
10
+ "noFallthroughCasesInSwitch": true,
11
+ "noPropertyAccessFromIndexSignature": true
12
+ },
13
+ "files": [],
14
+ "include": [],
15
+ "references": [
16
+ {
17
+ "path": "./tsconfig.lib.json"
18
+ },
19
+ {
20
+ "path": "./tsconfig.spec.json"
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../dist/out-tsc",
5
+ "declaration": true,
6
+ "types": [
7
+ "node",
8
+ "vite/client"
9
+ ]
10
+ },
11
+ "include": [
12
+ "src/**/*.ts"
13
+ ],
14
+ "exclude": [
15
+ "vite.config.ts",
16
+ "vite.config.mts",
17
+ "vitest.config.ts",
18
+ "vitest.config.mts",
19
+ "src/**/*.test.ts",
20
+ "src/**/*.spec.ts",
21
+ "src/**/*.test.tsx",
22
+ "src/**/*.spec.tsx",
23
+ "src/**/*.test.js",
24
+ "src/**/*.spec.js",
25
+ "src/**/*.test.jsx",
26
+ "src/**/*.spec.jsx"
27
+ ]
28
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../dist/out-tsc",
5
+ "types": [
6
+ "vitest/globals",
7
+ "vitest/importMeta",
8
+ "vite/client",
9
+ "node",
10
+ "vitest"
11
+ ]
12
+ },
13
+ "include": [
14
+ "vite.config.ts",
15
+ "vite.config.mts",
16
+ "vitest.config.ts",
17
+ "vitest.config.mts",
18
+ "src/**/*.test.ts",
19
+ "src/**/*.spec.ts",
20
+ "src/**/*.test.tsx",
21
+ "src/**/*.spec.tsx",
22
+ "src/**/*.test.js",
23
+ "src/**/*.spec.js",
24
+ "src/**/*.test.jsx",
25
+ "src/**/*.spec.jsx",
26
+ "src/**/*.d.ts"
27
+ ]
28
+ }
@@ -0,0 +1,51 @@
1
+ /// <reference types='vitest' />
2
+ import { defineConfig } from 'vite';
3
+ import dts from 'vite-plugin-dts';
4
+ import * as path from 'path';
5
+ import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
6
+ import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin';
7
+
8
+ export default defineConfig(() => ({
9
+ root: import.meta.dirname,
10
+ cacheDir: '../../node_modules/.vite/libs/here-data-provider',
11
+ plugins: [nxViteTsPaths(), nxCopyAssetsPlugin(['*.md']), dts({ entryRoot: 'src', tsconfigPath: path.join(import.meta.dirname, 'tsconfig.lib.json'), pathsToAliases: false })],
12
+ // Uncomment this if you are using workers.
13
+ // worker: {
14
+ // plugins: () => [ nxViteTsPaths() ],
15
+ // },
16
+ // Configuration for building your library.
17
+ // See: https://vite.dev/guide/build.html#library-mode
18
+ build: {
19
+ outDir: '../../dist/libs/here-data-provider',
20
+ emptyOutDir: true,
21
+ reportCompressedSize: true,
22
+ commonjsOptions: {
23
+ transformMixedEsModules: true,
24
+ },
25
+ lib: {
26
+ // Could also be a dictionary or array of multiple entry points.
27
+ entry: 'src/index.ts',
28
+ name: 'here-data-provider',
29
+ fileName: 'index',
30
+ // Change this to the formats you want to support.
31
+ // Don't forget to update your package.json as well.
32
+ formats: ['es' as const]
33
+ },
34
+ rolldownOptions: {
35
+ // External packages that should not be bundled into your library.
36
+ external: []
37
+ },
38
+ },
39
+ test: {
40
+ name: 'here-data-provider',
41
+ watch: false,
42
+ globals: true,
43
+ environment: 'node',
44
+ include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
45
+ reporters: ['default'],
46
+ coverage: {
47
+ reportsDirectory: '../../coverage/libs/here-data-provider',
48
+ provider: 'v8' as const,
49
+ }
50
+ },
51
+ }));
package/src/index.js DELETED
@@ -1,2 +0,0 @@
1
- export * from './lib/here-data-provider';
2
- //# sourceMappingURL=index.js.map
package/src/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/here-data-provider/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC"}
@@ -1,66 +0,0 @@
1
- import { ExecutorRequestOptions } from './here.executor';
2
- import type { AnyRoutingDataProvider, AnyRoutingDataResponse, RequestOptions, RouteSummary, LngLatPosition, Waypoint } from '@any-routing/core';
3
- export type SelectRouteStrategy = 'fastest' | 'shortest' | 'cheapest' | 'none';
4
- export type RouteExcludeNoticeDefinitions = {
5
- [key in 'critical' | 'info']?: string[] | 'all';
6
- };
7
- export type TurnByTurnAction = {
8
- action: 'arrive' | 'turn' | 'depart';
9
- duration: number;
10
- length: number;
11
- position: {
12
- lat: number;
13
- lng: number;
14
- };
15
- offset: number;
16
- };
17
- export type RoutePath = LngLatPosition[];
18
- export interface HereRouteSummary extends RouteSummary {
19
- turnByTurnActions: TurnByTurnAction[];
20
- shapePath: RoutePath;
21
- rawRoute: any;
22
- }
23
- export { ExecutorRequestOptions } from './here.executor';
24
- export interface HereRoutingData extends AnyRoutingDataResponse {
25
- routes: HereRouteSummary[];
26
- requestOptions: ExecutorRequestOptions;
27
- }
28
- export type GeoJsonSplitStrategy = 'jamFactor';
29
- export type Options = {
30
- alternatives?: number;
31
- worker?: boolean;
32
- apiKey: string;
33
- baseUrl?: string;
34
- selectRouteStrategy?: SelectRouteStrategy;
35
- spans?: string[];
36
- return?: string[];
37
- currency?: string;
38
- transportMode?: string;
39
- queryParams?: Record<string, any>;
40
- requestParams?: RequestInit;
41
- routeExcludeNotice?: RouteExcludeNoticeDefinitions;
42
- shapePolylinePrecision?: number;
43
- geoJSONShapeSplitStrategies?: {
44
- drag?: Array<GeoJsonSplitStrategy>;
45
- default?: Array<GeoJsonSplitStrategy>;
46
- };
47
- buildUrl?: (ctx: {
48
- waypoints: Waypoint[];
49
- options: Options & RequestOptions;
50
- }, url: string) => string;
51
- };
52
- export declare class HereProvider implements AnyRoutingDataProvider {
53
- private worker?;
54
- private executorAPI;
55
- private _options;
56
- get options(): Options;
57
- constructor(options: Options);
58
- destroy(): void;
59
- request(waypoints: any, opts: RequestOptions): Promise<HereRoutingData>;
60
- abortAllRequests(): void;
61
- setOption<T extends keyof Options>(optionKey: T, value: Options[T]): void;
62
- hasPendingRequests(): Promise<boolean>;
63
- private buildUrl;
64
- private serializeWaypoints;
65
- private formatWp;
66
- }