@wemap/routers 12.11.4 → 12.11.5

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/dist/index.mjs CHANGED
@@ -4,16 +4,14 @@ var __publicField = (obj, key, value) => {
4
4
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  return value;
6
6
  };
7
- import { g as getDurationFromLength, E as Edge, G as GraphRoute, V as Vertex, a as Graph, R as RemoteRouter, b as RemoteRoutingError, i as isTransitModePublicTransport, L as Leg, I as Itinerary, S as StepsBuilder, c as areTransitAndTravelModeConsistent, O as OsrmRemoteRouter, W as WemapMultiRoutingError } from "./OsrmRemoteRouter-e0076e4a.js";
8
- import { d, e, f } from "./OsrmRemoteRouter-e0076e4a.js";
7
+ import { Level, Coordinates, BoundingBox, UserPosition, Constants, Utils } from "@wemap/geo";
8
+ import { diffAngleLines, deg2rad, diffAngle, positiveMod, rad2deg } from "@wemap/maths";
9
+ import Logger from "@wemap/logger";
9
10
  import salesman from "@wemap/salesman.js";
10
- import { Level, Coordinates, Utils } from "@wemap/geo";
11
11
  import { OsmNode, OsmParser } from "@wemap/osm";
12
- import Logger from "@wemap/logger";
13
12
  import polyline from "@mapbox/polyline";
14
13
  import pointInPolygon from "@turf/boolean-point-in-polygon";
15
14
  import convexHullFn from "@turf/convex";
16
- import "@wemap/maths";
17
15
  function routerRequestToJson(routerRequest) {
18
16
  const { origin, destination, waypoints, ...rest } = routerRequest;
19
17
  return {
@@ -23,6 +21,921 @@ function routerRequestToJson(routerRequest) {
23
21
  ...rest
24
22
  };
25
23
  }
24
+ const _Edge = class _Edge {
25
+ constructor(vertex1, vertex2, properties = {}, id = _Edge.currentUniqueId++) {
26
+ __publicField(this, "level");
27
+ /** Edge bearing from vertex1 to vertex2 */
28
+ __publicField(this, "bearing");
29
+ __publicField(this, "length");
30
+ this.vertex1 = vertex1;
31
+ this.vertex2 = vertex2;
32
+ this.properties = properties;
33
+ this.id = id;
34
+ this.level = Level.union(vertex1.coords.level, vertex2.coords.level);
35
+ this.length = this.vertex1.distanceTo(this.vertex2);
36
+ this.bearing = this.vertex1.bearingTo(this.vertex2);
37
+ }
38
+ static getEdgeByVertices(edges, vertex1, vertex2) {
39
+ return edges.find(
40
+ (edge) => vertex1 === edge.vertex1 && vertex2 === edge.vertex2 || vertex2 === edge.vertex1 && vertex1 === edge.vertex2
41
+ );
42
+ }
43
+ reverseProperties() {
44
+ const { properties } = this;
45
+ if (properties.incline) {
46
+ properties.incline = properties.incline === "up" ? "down" : "up";
47
+ }
48
+ if (properties.isOneway) {
49
+ properties.isOneway = false;
50
+ }
51
+ }
52
+ };
53
+ __publicField(_Edge, "currentUniqueId", 0);
54
+ let Edge = _Edge;
55
+ class GraphProjection {
56
+ constructor(origin, distanceFromNearestElement, coords, nearestElement) {
57
+ this.origin = origin;
58
+ this.distanceFromNearestElement = distanceFromNearestElement;
59
+ this.coords = coords;
60
+ this.nearestElement = nearestElement;
61
+ }
62
+ }
63
+ class Vertex {
64
+ constructor(coords, properties = {}) {
65
+ __publicField(this, "id", -1);
66
+ this.coords = coords;
67
+ this.properties = properties;
68
+ }
69
+ distanceTo(other) {
70
+ return this.coords.distanceTo(other.coords);
71
+ }
72
+ bearingTo(other) {
73
+ return this.coords.bearingTo(other.coords);
74
+ }
75
+ toJson() {
76
+ return {
77
+ id: this.id,
78
+ coords: this.coords.toCompressedJson(),
79
+ ...Object.keys(this.properties).length > 0 && { properties: this.properties }
80
+ };
81
+ }
82
+ static fromJson(json) {
83
+ const v = new Vertex(
84
+ Coordinates.fromCompressedJson(json.coords),
85
+ json.properties
86
+ );
87
+ v.id = json.id;
88
+ return v;
89
+ }
90
+ }
91
+ class Graph {
92
+ constructor(vertices, edges) {
93
+ /**
94
+ * exitVertices are vertices that have at least one indoor edge and one outdoor edge
95
+ * They are stored because the Level model cannot handle an indoor and outdoor state like [null, 1] or [null, [1,2]]
96
+ * This vertices are used to cover the projection case:
97
+ * - if projection origin is null, an exit vertex can be used
98
+ * - if projection origin is not null, the intersection level with an exit vertex can be used
99
+ */
100
+ __publicField(this, "exitVertices");
101
+ this.vertices = vertices;
102
+ this.edges = edges;
103
+ const nullVertices = edges.filter((e) => e.level === null).map((e) => [e.vertex1, e.vertex2]).flat();
104
+ const levelVertices = edges.filter((e) => e.level !== null).map((e) => [e.vertex1, e.vertex2]).flat();
105
+ this.exitVertices = new Set(nullVertices.filter((v1) => levelVertices.includes(v1)));
106
+ }
107
+ getEdgeByVertices(vertex1, vertex2) {
108
+ return Edge.getEdgeByVertices(this.edges, vertex1, vertex2);
109
+ }
110
+ getVertexByCoords(coords) {
111
+ return Graph.getVertexByCoords(this.vertices, coords);
112
+ }
113
+ static getVertexByCoords(vertices, coords) {
114
+ return vertices.find((vertex) => vertex.coords.equals(coords));
115
+ }
116
+ getVertexByName(name) {
117
+ return this.vertices.find((vertex) => vertex.properties.name === name);
118
+ }
119
+ getEdgeByName(name) {
120
+ return this.edges.find((edge) => edge.properties.name === name);
121
+ }
122
+ getBoundingBox(extendedMeasure) {
123
+ if (!this.vertices.length) {
124
+ return null;
125
+ }
126
+ const boundingBox = BoundingBox.fromCoordinates(this.vertices.map((vertex) => vertex.coords));
127
+ if (extendedMeasure) {
128
+ boundingBox.extendsWithMeasure(extendedMeasure);
129
+ }
130
+ return boundingBox;
131
+ }
132
+ getProjection(origin, options = {}) {
133
+ const useMaxDistance = "maxDistance" in options;
134
+ const maxDistance = options.maxDistance;
135
+ const useMaxBearingAngle = "maxBearingAngle" in options;
136
+ if (useMaxBearingAngle && (!(origin instanceof UserPosition) || origin.bearing === null))
137
+ return null;
138
+ const maxBearingAngle = options.maxBearingAngle;
139
+ const useAcceptEdgeFn = "acceptEdgeFn" in options;
140
+ const useMultiLevelSegments = !("useMultiLevelSegments" in options) || options.useMultiLevelSegments;
141
+ let bestProjection = null;
142
+ const adaptProjectionCoords = (projCoords) => {
143
+ if (!(origin instanceof UserPosition))
144
+ return projCoords;
145
+ const p = origin.clone();
146
+ p.lat = projCoords.lat;
147
+ p.lng = projCoords.lng;
148
+ p.level = projCoords.level;
149
+ p.alt = projCoords.alt;
150
+ p.heightFromFloor = projCoords.heightFromFloor;
151
+ p.heightFromGround = projCoords.heightFromGround;
152
+ return p;
153
+ };
154
+ this.edges.forEach((edge) => {
155
+ if (useAcceptEdgeFn && !options.acceptEdgeFn(edge))
156
+ return;
157
+ if (!useMultiLevelSegments && Level.isRange(edge.level))
158
+ return;
159
+ if (!Level.intersect(edge.level, origin.level))
160
+ return;
161
+ if (useMaxBearingAngle) {
162
+ if (diffAngleLines(edge.bearing, origin.bearing) > maxBearingAngle)
163
+ return;
164
+ }
165
+ const segmentProjection = origin.getSegmentProjection(edge.vertex1.coords, edge.vertex2.coords);
166
+ if (!segmentProjection)
167
+ return;
168
+ const distanceToSegment = segmentProjection.distanceTo(origin);
169
+ if (useMaxDistance && distanceToSegment > maxDistance)
170
+ return;
171
+ if (distanceToSegment < ((bestProjection == null ? void 0 : bestProjection.distanceFromNearestElement) ?? Number.MAX_VALUE)) {
172
+ bestProjection = new GraphProjection(origin, distanceToSegment, adaptProjectionCoords(segmentProjection), edge);
173
+ }
174
+ });
175
+ if (useMaxBearingAngle) {
176
+ return bestProjection;
177
+ }
178
+ this.vertices.forEach((vertex) => {
179
+ let vertexCoords = vertex.coords;
180
+ if (this.exitVertices.has(vertex) && origin.level === null) {
181
+ vertexCoords = vertex.coords.clone();
182
+ vertexCoords.level = null;
183
+ }
184
+ if (!useMultiLevelSegments && Level.isRange(vertexCoords.level))
185
+ return;
186
+ if (!Level.intersect(vertexCoords.level, origin.level))
187
+ return;
188
+ const distanceToVertex = vertexCoords.distanceTo(origin);
189
+ if (distanceToVertex < Constants.EPS_MM) {
190
+ bestProjection = new GraphProjection(origin, 0, adaptProjectionCoords(vertexCoords), vertex);
191
+ return;
192
+ }
193
+ if (useMaxDistance && distanceToVertex > maxDistance)
194
+ return;
195
+ if (distanceToVertex < ((bestProjection == null ? void 0 : bestProjection.distanceFromNearestElement) ?? Number.MAX_VALUE)) {
196
+ bestProjection = new GraphProjection(origin, distanceToVertex, adaptProjectionCoords(vertexCoords), vertex);
197
+ }
198
+ });
199
+ return bestProjection;
200
+ }
201
+ toJson() {
202
+ return {
203
+ vertices: this.vertices.map((vertex) => vertex.toJson()),
204
+ edges: this.edges.map((edge) => ({
205
+ id: edge.id,
206
+ vertex1Idx: this.vertices.indexOf(edge.vertex1),
207
+ vertex2Idx: this.vertices.indexOf(edge.vertex2),
208
+ ...Object.keys(edge.properties).length > 0 && { properties: edge.properties }
209
+ }))
210
+ };
211
+ }
212
+ static fromJson(json) {
213
+ const vertices = json.vertices.map((vertex) => Vertex.fromJson(vertex));
214
+ const edges = json.edges.map((jsonEdge) => new Edge(
215
+ vertices[jsonEdge.vertex1Idx],
216
+ vertices[jsonEdge.vertex2Idx],
217
+ jsonEdge.properties,
218
+ jsonEdge.id
219
+ ));
220
+ return new Graph(vertices, edges);
221
+ }
222
+ /** @deprecated */
223
+ toCompressedJson() {
224
+ return {
225
+ vertices: this.vertices.map((vertex) => vertex.coords.toCompressedJson()),
226
+ verticesIds: this.vertices.map((vertex) => vertex.id),
227
+ edges: this.edges.map((edge) => {
228
+ const vertex1Idx = this.vertices.indexOf(edge.vertex1);
229
+ const vertex2Idx = this.vertices.indexOf(edge.vertex2);
230
+ const edgeExtras = edge.properties;
231
+ if (Object.keys(edgeExtras).length > 0) {
232
+ return [vertex1Idx, vertex2Idx, edgeExtras];
233
+ }
234
+ return [vertex1Idx, vertex2Idx];
235
+ })
236
+ };
237
+ }
238
+ /** @deprecated */
239
+ static fromCompressedJson(json) {
240
+ const vertices = json.vertices.map((vertex) => new Vertex(Coordinates.fromCompressedJson(vertex)));
241
+ const edges = json.edges.map((jsonEdge) => new Edge(
242
+ vertices[jsonEdge[0]],
243
+ vertices[jsonEdge[1]],
244
+ jsonEdge.length > 2 ? jsonEdge[2] : {}
245
+ ));
246
+ return new Graph(vertices, edges);
247
+ }
248
+ static fromCoordinatesSegments(segments) {
249
+ const vertices = [];
250
+ const edges = [];
251
+ const getOrCreateVertex = (coords) => {
252
+ const vertex = vertices.find((otherVertex) => otherVertex.coords.equals(coords));
253
+ if (vertex) {
254
+ return vertex;
255
+ }
256
+ const newVertex = new Vertex(coords);
257
+ vertices.push(newVertex);
258
+ return newVertex;
259
+ };
260
+ for (const segment of segments) {
261
+ let previousVertex = null;
262
+ for (const coords of segment) {
263
+ const currentVertex = getOrCreateVertex(coords);
264
+ if (previousVertex) {
265
+ edges.push(new Edge(currentVertex, previousVertex));
266
+ }
267
+ previousVertex = currentVertex;
268
+ }
269
+ }
270
+ return new Graph(vertices, edges);
271
+ }
272
+ /**
273
+ * Create edges From MultiLevel Itinerary for a given level
274
+ * @param useMultiLevelEdges use segments which intersect both levels (stairs, elevators...)
275
+ */
276
+ getEdgesAtLevel(targetLevel, useMultiLevelEdges = true) {
277
+ return this.edges.filter(
278
+ ({ level }) => useMultiLevelEdges ? Level.intersect(targetLevel, level) : Level.contains(targetLevel, level)
279
+ );
280
+ }
281
+ toDetailedString() {
282
+ let output = `--- Network ---
283
+ Vertices: ${this.vertices.length}
284
+ Edges: ${this.edges.length}
285
+ ---
286
+ Vertices
287
+ `;
288
+ this.vertices.forEach((vertex) => {
289
+ output += vertex.id;
290
+ const vertexProps = vertex.properties;
291
+ if (Object.keys(vertexProps).length !== 0) {
292
+ output += ` ${vertexProps}`;
293
+ }
294
+ });
295
+ output += "---\nEdges\n";
296
+ this.edges.forEach((edge) => {
297
+ output += `${edge.id} - [v1: ${edge.vertex1.id}, v2: ${edge.vertex2.id}]`;
298
+ const edgeProps = edge.properties;
299
+ if (Object.keys(edgeProps).length !== 0) {
300
+ output += ` ${edgeProps}`;
301
+ }
302
+ });
303
+ output += "---";
304
+ return output;
305
+ }
306
+ }
307
+ function getDurationFromLength(length, speed = 5) {
308
+ return length / (speed * 1e3 / 3600);
309
+ }
310
+ function isTransitModePublicTransport(transitMode) {
311
+ return [
312
+ "AIRPLANE",
313
+ "BOAT",
314
+ "BUS",
315
+ "FERRY",
316
+ "FUNICULAR",
317
+ "METRO",
318
+ "MULTI",
319
+ "TRAIN",
320
+ "TRAM"
321
+ ].includes(transitMode);
322
+ }
323
+ function areTransitAndTravelModeConsistent(transitMode, travelMode) {
324
+ return transitMode === travelMode || isTransitModePublicTransport(transitMode) && travelMode === "TRANSIT" || transitMode === "WALK" && travelMode === "TRANSIT";
325
+ }
326
+ function stepToJson(step) {
327
+ return {
328
+ ...step.firstStep && { firstStep: true },
329
+ ...step.lastStep && { lastStep: true },
330
+ number: step.number,
331
+ coords: step.coords.toCompressedJson(),
332
+ ...step.name !== null && { name: step.name },
333
+ angle: Number(step.angle.toFixed(2)),
334
+ previousBearing: Number(step.previousBearing.toFixed(2)),
335
+ nextBearing: Number(step.nextBearing.toFixed(2)),
336
+ distance: Number(step.distance.toFixed(1)),
337
+ duration: Number(step.duration.toFixed(1)),
338
+ ...step.levelChange !== null && { levelChange: step.levelChange },
339
+ ...step.extras && Object.keys(step.extras).length !== 0 && { extras: step.extras }
340
+ };
341
+ }
342
+ function jsonToStep(json) {
343
+ return Object.assign({}, json, {
344
+ coords: Coordinates.fromCompressedJson(json.coords),
345
+ firstStep: Boolean(json.firstStep),
346
+ lastStep: Boolean(json.lastStep),
347
+ name: json.name || null,
348
+ levelChange: json.levelChange || null,
349
+ extras: json.extras || null
350
+ });
351
+ }
352
+ function stepEquals(step1, step2) {
353
+ var _a, _b, _c, _d, _e, _f;
354
+ return step1.coords.equals(step2.coords) && Math.abs(step1.angle - step2.angle) <= 5e-3 && Math.abs(step1.distance - step2.distance) <= 0.05 && Math.abs(step1.duration - step2.duration) <= 0.05 && step1.firstStep === step2.firstStep && step1.lastStep === step2.lastStep && ((_a = step1.levelChange) == null ? void 0 : _a.difference) === ((_b = step2.levelChange) == null ? void 0 : _b.difference) && ((_c = step1.levelChange) == null ? void 0 : _c.direction) === ((_d = step2.levelChange) == null ? void 0 : _d.direction) && ((_e = step1.levelChange) == null ? void 0 : _e.type) === ((_f = step2.levelChange) == null ? void 0 : _f.type) && step1.name === step2.name && Math.abs(step1.nextBearing - step2.nextBearing) <= 5e-3 && step1.number === step2.number && Math.abs(step1.previousBearing - step2.previousBearing) <= 5e-3;
355
+ }
356
+ class GraphRoute extends Graph {
357
+ constructor(start, end, vertices, edges, edgesWeights) {
358
+ super(vertices, edges);
359
+ this.start = start;
360
+ this.end = end;
361
+ this.vertices = vertices;
362
+ this.edges = edges;
363
+ this.edgesWeights = edgesWeights;
364
+ }
365
+ // /!\ Does not clone vertices
366
+ // /!\ Create new Edges but does not deep clone properties
367
+ // /!\ Does not revert edge oneway property
368
+ reverse() {
369
+ const vertices = this.vertices.slice().reverse();
370
+ const edges = this.edges.slice().reverse();
371
+ const edgesWeights = this.edgesWeights.slice().reverse();
372
+ edges.map((oldEdge) => new Edge(oldEdge.vertex2, oldEdge.vertex1, oldEdge.properties));
373
+ return new GraphRoute(this.start, this.end, vertices, edges, edgesWeights);
374
+ }
375
+ static fromCoordinates(start, end, coordinates) {
376
+ const graph = Graph.fromCoordinatesSegments([coordinates]);
377
+ const edgesWeights = graph.edges.map((e) => getDurationFromLength(e.length));
378
+ return new GraphRoute(start, end, graph.vertices, graph.edges, edgesWeights);
379
+ }
380
+ get hasRoute() {
381
+ return Boolean(this.vertices.length);
382
+ }
383
+ }
384
+ const SKIP_STEP_ANGLE_MAX = deg2rad(20);
385
+ class StepsBuilder {
386
+ constructor() {
387
+ __publicField(this, "start", null);
388
+ __publicField(this, "end", null);
389
+ __publicField(this, "pathCoords", null);
390
+ __publicField(this, "stepsInfo", []);
391
+ }
392
+ setStart(start) {
393
+ this.start = start;
394
+ return this;
395
+ }
396
+ setEnd(end) {
397
+ this.end = end;
398
+ return this;
399
+ }
400
+ setPathCoords(pathCoords) {
401
+ this.pathCoords = pathCoords;
402
+ return this;
403
+ }
404
+ setStepsInfo(stepsInfo) {
405
+ this.stepsInfo = stepsInfo;
406
+ return this;
407
+ }
408
+ addStepInfo(stepInfo) {
409
+ this.stepsInfo.push(stepInfo);
410
+ return this;
411
+ }
412
+ setGraphRoute(graphRoute) {
413
+ const stepsInfo = [];
414
+ const { start, end } = graphRoute;
415
+ if (!graphRoute.hasRoute) {
416
+ return this;
417
+ }
418
+ let currentStep = null;
419
+ let previousBearing = start.bearingTo(graphRoute.vertices[0].coords);
420
+ for (let i = 0; i < graphRoute.vertices.length - 1; i++) {
421
+ const isFirstStep = i === 0;
422
+ const vertex = graphRoute.vertices[i];
423
+ const currentCoords = vertex.coords;
424
+ const nextVertex = graphRoute.vertices[i + 1];
425
+ const nextCoords = nextVertex.coords;
426
+ const edge = graphRoute.edges[i];
427
+ const nextBearing = vertex.bearingTo(nextVertex);
428
+ const angle = diffAngle(previousBearing, nextBearing + Math.PI);
429
+ const previousStep = stepsInfo.length ? stepsInfo[stepsInfo.length - 1] : null;
430
+ const { isSubwayEntrance, isGate, subwayEntranceRef } = vertex.properties;
431
+ const { isElevator, areEscalators, areStairs, isMovingWalkway, incline } = edge.properties;
432
+ let levelChangeType = null;
433
+ if (isElevator) {
434
+ levelChangeType = "elevator";
435
+ } else if (areEscalators) {
436
+ levelChangeType = "escalator";
437
+ } else if (areStairs) {
438
+ levelChangeType = "stairs";
439
+ } else if (isMovingWalkway) {
440
+ levelChangeType = "moving walkway";
441
+ } else {
442
+ levelChangeType = "incline plane";
443
+ }
444
+ let forceLevelChange;
445
+ if ((areStairs || isElevator) && incline && !(previousStep == null ? void 0 : previousStep.levelChange)) {
446
+ forceLevelChange = incline;
447
+ }
448
+ const previousEdge = i > 0 ? graphRoute.edges[i - 1] : null;
449
+ const previousEdgeProperties = (previousEdge == null ? void 0 : previousEdge.properties) || {};
450
+ const forceEndOfLevelChange = Boolean(
451
+ previousEdgeProperties.incline && previousEdgeProperties.areStairs && (!incline || !areStairs)
452
+ );
453
+ const isEntrance = vertex.properties.isSubwayEntrance;
454
+ const stepName = edge.properties.name || null;
455
+ const duration = graphRoute.edgesWeights[i];
456
+ const stepExtras = {
457
+ ...isSubwayEntrance && { isSubwayEntrance },
458
+ ...subwayEntranceRef && { subwayEntranceRef },
459
+ ...isGate && { isGate }
460
+ };
461
+ let splitByAngle = Math.abs(diffAngle(Math.PI, angle)) >= SKIP_STEP_ANGLE_MAX;
462
+ const splitByLevel = Level.isRange(edge.level) && !Level.isRange(currentCoords.level) || forceLevelChange;
463
+ splitByAngle = splitByAngle && !(currentCoords.level && Level.isRange(currentCoords.level));
464
+ const splitByEndOfLevelChange = (previousStep == null ? void 0 : previousStep.levelChange) && !Level.isRange(currentCoords.level) || forceEndOfLevelChange;
465
+ const splitStepCondition = splitByAngle || splitByLevel || splitByEndOfLevelChange || isEntrance;
466
+ if (isFirstStep || splitStepCondition) {
467
+ let levelChange;
468
+ if (splitByLevel) {
469
+ const difference = Level.diff(currentCoords.level, nextCoords.level) || 0;
470
+ let direction = difference > 0 ? "up" : "down";
471
+ if (forceLevelChange) {
472
+ direction = forceLevelChange;
473
+ }
474
+ levelChange = {
475
+ difference,
476
+ direction,
477
+ ...levelChangeType && { type: levelChangeType }
478
+ };
479
+ }
480
+ currentStep = {
481
+ coords: currentCoords,
482
+ ...stepName && { name: stepName },
483
+ extras: stepExtras,
484
+ levelChange,
485
+ distance: 0,
486
+ duration: 0
487
+ };
488
+ stepsInfo.push(currentStep);
489
+ }
490
+ currentStep.distance += currentCoords.distanceTo(nextCoords);
491
+ currentStep.duration += duration;
492
+ previousBearing = nextBearing;
493
+ }
494
+ const lastCoords = graphRoute.vertices[graphRoute.vertices.length - 1].coords;
495
+ if (!Coordinates.equals(lastCoords, end)) {
496
+ stepsInfo.push({ coords: lastCoords });
497
+ }
498
+ this.setStart(start);
499
+ this.setEnd(end);
500
+ this.setPathCoords(graphRoute.vertices.map((v) => v.coords));
501
+ this.setStepsInfo(stepsInfo);
502
+ return this;
503
+ }
504
+ build() {
505
+ const { pathCoords, start, end } = this;
506
+ if (!pathCoords) {
507
+ Logger.warn(`StepsBuilder: Missing "pathCoords" property to build steps`);
508
+ return [];
509
+ }
510
+ if (!start) {
511
+ Logger.warn(`StepsBuilder: Missing "from" property to build steps`);
512
+ return [];
513
+ }
514
+ if (!end) {
515
+ Logger.warn(`StepsBuilder: Missing "to" property to build steps`);
516
+ return [];
517
+ }
518
+ if (this.stepsInfo.length === 0) {
519
+ this.setGraphRoute(GraphRoute.fromCoordinates(start, end, pathCoords));
520
+ }
521
+ const { stepsInfo } = this;
522
+ return stepsInfo.map((stepInfo, stepId) => {
523
+ const coordsId = pathCoords.findIndex((coords) => coords.equals(stepInfo.coords));
524
+ if (coordsId === -1) {
525
+ throw new Error("Cannot find step coordinates in itinerary coordinates.");
526
+ }
527
+ const coordsBeforeStep = coordsId === 0 ? start : pathCoords[coordsId - 1];
528
+ const coordsAfterStep = coordsId === pathCoords.length - 1 ? end : pathCoords[coordsId + 1];
529
+ const previousBearing = coordsBeforeStep.bearingTo(stepInfo.coords);
530
+ const nextBearing = stepInfo.coords.bearingTo(coordsAfterStep);
531
+ let distance = 0;
532
+ const isLastStep = stepId === stepsInfo.length - 1;
533
+ const coordsToStopCalculation = isLastStep ? pathCoords[pathCoords.length - 1] : stepsInfo[stepId + 1].coords;
534
+ let currentCoordsId = coordsId;
535
+ while (!pathCoords[currentCoordsId].equals(coordsToStopCalculation)) {
536
+ distance += pathCoords[currentCoordsId].distanceTo(pathCoords[currentCoordsId + 1]);
537
+ currentCoordsId++;
538
+ }
539
+ return {
540
+ coords: stepInfo.coords,
541
+ name: stepInfo.name || null,
542
+ number: stepId + 1,
543
+ previousBearing,
544
+ nextBearing,
545
+ angle: diffAngle(previousBearing, nextBearing + Math.PI),
546
+ firstStep: stepId === 0,
547
+ lastStep: isLastStep,
548
+ distance,
549
+ // stepInfo.distance is overwritten
550
+ duration: stepInfo.duration || getDurationFromLength(distance),
551
+ levelChange: stepInfo.levelChange || null,
552
+ extras: stepInfo.extras || null
553
+ };
554
+ });
555
+ }
556
+ }
557
+ class Leg {
558
+ constructor({
559
+ start,
560
+ end,
561
+ coords,
562
+ transitMode,
563
+ duration,
564
+ startTime,
565
+ endTime,
566
+ transportInfo,
567
+ steps
568
+ }) {
569
+ __publicField(this, "start");
570
+ __publicField(this, "end");
571
+ __publicField(this, "coords");
572
+ __publicField(this, "distance");
573
+ __publicField(this, "transitMode");
574
+ __publicField(this, "duration");
575
+ __publicField(this, "startTime");
576
+ __publicField(this, "endTime");
577
+ __publicField(this, "steps");
578
+ __publicField(this, "transportInfo");
579
+ this.start = {
580
+ name: start.name || null,
581
+ coords: start.coords
582
+ };
583
+ this.end = {
584
+ name: end.name || null,
585
+ coords: end.coords
586
+ };
587
+ this.coords = coords;
588
+ this.transitMode = transitMode;
589
+ this.distance = Utils.calcDistance(coords);
590
+ this.duration = typeof duration === "number" ? duration : getDurationFromLength(this.distance);
591
+ this.startTime = typeof startTime === "number" ? startTime : null;
592
+ this.endTime = typeof endTime === "number" ? endTime : null;
593
+ this.transportInfo = transportInfo || null;
594
+ this.steps = Array.isArray(steps) ? steps : new StepsBuilder().setStart(start.coords).setEnd(end.coords).setPathCoords(coords).build();
595
+ }
596
+ isPublicTransport() {
597
+ return isTransitModePublicTransport(this.transitMode);
598
+ }
599
+ toGraph() {
600
+ return Graph.fromCoordinatesSegments([this.coords]);
601
+ }
602
+ static equals(obj1, obj2) {
603
+ var _a, _b;
604
+ const intermediate = obj1.transitMode === obj2.transitMode && Math.abs(obj1.duration - obj2.duration) <= 0.05 && obj1.startTime === obj2.startTime && obj1.endTime === obj2.endTime && obj1.start.name === obj2.start.name && obj1.start.coords.equals(obj2.start.coords) && obj1.end.name === obj2.end.name && obj1.end.coords.equals(obj2.end.coords) && obj1.coords.length === obj2.coords.length && (obj1.steps === obj2.steps || ((_a = obj1.steps) == null ? void 0 : _a.length) === ((_b = obj2.steps) == null ? void 0 : _b.length));
605
+ if (!intermediate) {
606
+ return false;
607
+ }
608
+ let i;
609
+ for (i = 0; i < obj1.coords.length; i++) {
610
+ if (!obj1.coords[i].equals(obj2.coords[i])) {
611
+ return false;
612
+ }
613
+ }
614
+ for (i = 0; i < obj1.steps.length; i++) {
615
+ if (!stepEquals(obj1.steps[i], obj2.steps[i])) {
616
+ return false;
617
+ }
618
+ }
619
+ if (obj1.transportInfo !== obj2.transportInfo) {
620
+ if (obj1.transportInfo === null || obj2.transportInfo === null) {
621
+ return false;
622
+ }
623
+ if (obj1.transportInfo.name !== obj2.transportInfo.name || obj1.transportInfo.routeColor !== obj2.transportInfo.routeColor || obj1.transportInfo.routeTextColor !== obj2.transportInfo.routeTextColor || obj1.transportInfo.directionName !== obj2.transportInfo.directionName) {
624
+ return false;
625
+ }
626
+ }
627
+ return true;
628
+ }
629
+ equals(obj) {
630
+ return Leg.equals(this, obj);
631
+ }
632
+ toJson() {
633
+ return {
634
+ transitMode: this.transitMode,
635
+ start: {
636
+ coords: this.start.coords.toCompressedJson(),
637
+ ...this.start.name && { name: this.start.name }
638
+ },
639
+ end: {
640
+ coords: this.end.coords.toCompressedJson(),
641
+ ...this.end.name && { name: this.end.name }
642
+ },
643
+ distance: Number(this.distance.toFixed(1)),
644
+ duration: Number(this.duration.toFixed(1)),
645
+ coords: this.coords.map((coords) => coords.toCompressedJson()),
646
+ steps: this.steps.map(stepToJson),
647
+ ...this.startTime !== null && { startTime: this.startTime },
648
+ ...this.endTime !== null && { endTime: this.endTime },
649
+ ...this.transportInfo !== null && { transportInfo: this.transportInfo }
650
+ };
651
+ }
652
+ static fromJson(json) {
653
+ var _a;
654
+ const leg = new Leg(Object.assign({}, json, {
655
+ start: {
656
+ coords: Coordinates.fromCompressedJson(json.start.coords),
657
+ name: json.start.name || null
658
+ },
659
+ end: {
660
+ coords: Coordinates.fromCompressedJson(json.end.coords),
661
+ name: json.end.name || null
662
+ },
663
+ coords: json.coords.map(Coordinates.fromCompressedJson),
664
+ steps: ((_a = json.steps) == null ? void 0 : _a.map(jsonToStep)) || null
665
+ }));
666
+ return leg;
667
+ }
668
+ static fromGraphRoute(graphRoute, transitMode = "WALK") {
669
+ return new Leg({
670
+ start: { coords: graphRoute.start },
671
+ end: { coords: graphRoute.end },
672
+ coords: graphRoute.vertices.map((vertex) => vertex.coords),
673
+ duration: graphRoute.edgesWeights.reduce((acc, weight) => acc + weight, 0),
674
+ transitMode,
675
+ steps: new StepsBuilder().setGraphRoute(graphRoute).build()
676
+ });
677
+ }
678
+ // TODO: Remove when possible...
679
+ // Livemap specific
680
+ multiplyLevel(levelFactor) {
681
+ this.start.coords.level = Level.multiplyBy(this.start.coords.level, levelFactor);
682
+ this.end.coords.level = Level.multiplyBy(this.end.coords.level, levelFactor);
683
+ for (const coords of this.coords) {
684
+ coords.level = Level.multiplyBy(coords.level, levelFactor);
685
+ }
686
+ this.steps.forEach((step) => {
687
+ step.coords.level = Level.multiplyBy(step.coords.level, levelFactor);
688
+ });
689
+ }
690
+ }
691
+ class Itinerary {
692
+ constructor({
693
+ origin,
694
+ destination,
695
+ duration,
696
+ legs,
697
+ startTime,
698
+ endTime
699
+ }) {
700
+ __publicField(this, "origin");
701
+ __publicField(this, "destination");
702
+ __publicField(this, "duration");
703
+ __publicField(this, "legs");
704
+ __publicField(this, "_transitMode", null);
705
+ __publicField(this, "startTime");
706
+ __publicField(this, "endTime");
707
+ __publicField(this, "_coords", null);
708
+ __publicField(this, "_distance", null);
709
+ this.origin = origin;
710
+ this.destination = destination;
711
+ this.legs = legs;
712
+ if (typeof duration === "number") {
713
+ this.duration = duration;
714
+ } else {
715
+ this.duration = this.legs.reduce((dur, leg) => dur + leg.duration, 0);
716
+ }
717
+ this.startTime = typeof startTime === "number" ? startTime : null;
718
+ this.endTime = typeof endTime === "number" ? endTime : null;
719
+ this.updateStepsFromLegs();
720
+ }
721
+ set coords(_) {
722
+ throw new Error("Itinerary.coords cannot be set. They are calculated from Itinerary.legs.");
723
+ }
724
+ get coords() {
725
+ if (!this._coords) {
726
+ this._coords = this.legs.map((leg) => leg.coords).flat().filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));
727
+ }
728
+ return this._coords;
729
+ }
730
+ set steps(_) {
731
+ throw new Error("Itinerary.step cannot be set. They are calculated from Itinerary.legs.");
732
+ }
733
+ get steps() {
734
+ return this.legs.map((leg) => leg.steps).flat();
735
+ }
736
+ set transitMode(_) {
737
+ throw new Error("Itinerary.transitMode cannot be set. They are calculated from Itinerary.legs.");
738
+ }
739
+ // Transit mode will return MULTI if there are several transit modes except WALK
740
+ // Else it will return the only transit mode
741
+ // fallback to WALK if no transit mode
742
+ get transitMode() {
743
+ if (!this._transitMode) {
744
+ const legTransitModes = new Set(this.legs.map((leg) => leg.transitMode));
745
+ legTransitModes.delete("WALK");
746
+ if (legTransitModes.size > 1) {
747
+ this._transitMode = "MULTI";
748
+ return this._transitMode;
749
+ }
750
+ if (legTransitModes.size === 1) {
751
+ this._transitMode = legTransitModes.values().next().value;
752
+ return this._transitMode;
753
+ }
754
+ this._transitMode = "WALK";
755
+ }
756
+ return this._transitMode;
757
+ }
758
+ set distance(_) {
759
+ throw new Error("Itinerary.distance cannot be set. They are calculated from Itinerary.legs.");
760
+ }
761
+ get distance() {
762
+ if (this._distance === null) {
763
+ this._distance = Utils.calcDistance(this.coords);
764
+ }
765
+ return this._distance;
766
+ }
767
+ toGraph() {
768
+ return Graph.fromCoordinatesSegments([this.coords]);
769
+ }
770
+ static fromItineraries(...itineraries) {
771
+ return new Itinerary({
772
+ origin: itineraries[0].origin,
773
+ destination: itineraries[itineraries.length - 1].destination,
774
+ legs: itineraries.map((itinerary) => itinerary.legs).flat()
775
+ });
776
+ }
777
+ /**
778
+ * Convert lat/lng/level? points to Itinerary
779
+ */
780
+ static fromOrderedPointsArray(points, start, end) {
781
+ const pointToCoordinates = (point) => new Coordinates(point[0], point[1], null, point[2]);
782
+ return this.fromOrderedCoordinates(
783
+ points.map(pointToCoordinates),
784
+ pointToCoordinates(start),
785
+ pointToCoordinates(end)
786
+ );
787
+ }
788
+ /**
789
+ * Convert ordered Coordinates to Itinerary
790
+ */
791
+ static fromOrderedCoordinates(coords, origin, destination, transitMode = "WALK") {
792
+ const steps = new StepsBuilder().setPathCoords(coords).setStart(origin).setEnd(destination).build();
793
+ const leg = new Leg({
794
+ start: { coords: origin },
795
+ end: { coords: destination },
796
+ coords,
797
+ transitMode,
798
+ steps
799
+ });
800
+ return new Itinerary({ origin, destination, legs: [leg] });
801
+ }
802
+ static equals(obj1, obj2) {
803
+ const intermediate = obj1.origin.equals(obj2.origin) && obj1.destination.equals(obj2.destination) && Math.abs(obj1.distance - obj2.distance) <= 0.05 && Math.abs(obj1.duration - obj2.duration) <= 0.05 && obj1.startTime === obj2.startTime && obj1.endTime === obj2.endTime && obj1.legs.length === obj2.legs.length;
804
+ if (!intermediate) {
805
+ return false;
806
+ }
807
+ for (let i = 0; i < obj1.legs.length; i++) {
808
+ if (!obj1.legs[i].equals(obj2.legs[i])) {
809
+ return false;
810
+ }
811
+ }
812
+ return true;
813
+ }
814
+ equals(obj) {
815
+ return Itinerary.equals(this, obj);
816
+ }
817
+ toJson() {
818
+ return {
819
+ origin: this.origin.toJson(),
820
+ destination: this.destination.toJson(),
821
+ distance: Number(this.distance.toFixed(1)),
822
+ duration: Number(this.duration.toFixed(1)),
823
+ transitMode: this.transitMode,
824
+ legs: this.legs.map((leg) => leg.toJson()),
825
+ ...this.startTime !== null && { startTime: this.startTime },
826
+ ...this.endTime !== null && { endTime: this.endTime }
827
+ };
828
+ }
829
+ static fromJson(json) {
830
+ return new Itinerary({
831
+ origin: Coordinates.fromJson(json.origin),
832
+ destination: Coordinates.fromJson(json.destination),
833
+ duration: json.duration,
834
+ legs: json.legs.map(Leg.fromJson),
835
+ startTime: json.startTime,
836
+ endTime: json.endTime
837
+ });
838
+ }
839
+ static fromGraphRoute(graphRoute, transitMode = "WALK") {
840
+ const leg = Leg.fromGraphRoute(graphRoute, transitMode);
841
+ return new Itinerary({
842
+ origin: graphRoute.start,
843
+ destination: graphRoute.end,
844
+ legs: [leg]
845
+ });
846
+ }
847
+ // TODO: Remove when possible...
848
+ // Livemap specific
849
+ multiplyLevel(levelFactor) {
850
+ this.origin.level = Level.multiplyBy(this.origin.level, levelFactor);
851
+ this.destination.level = Level.multiplyBy(this.destination.level, levelFactor);
852
+ this.legs.forEach((leg) => leg.multiplyLevel(levelFactor));
853
+ }
854
+ // TODO: Remove when possible...
855
+ // Livemap specific
856
+ forceUnknownLevelTo0() {
857
+ this.origin.level = this.origin.level || 0;
858
+ this.destination.level = this.destination.level || 0;
859
+ for (const leg of this.legs) {
860
+ leg.start.coords.level = leg.start.coords.level || 0;
861
+ leg.end.coords.level = leg.end.coords.level || 0;
862
+ for (const coords of leg.coords) {
863
+ coords.level = coords.level || 0;
864
+ }
865
+ if (leg.steps) {
866
+ for (const step of leg.steps) {
867
+ step.coords.level = step.coords.level || 0;
868
+ }
869
+ }
870
+ }
871
+ if (this._coords) {
872
+ for (const coords of this._coords) {
873
+ coords.level = coords.level || 0;
874
+ }
875
+ }
876
+ }
877
+ toGeoJson() {
878
+ const transformToPoint = (point, name, type) => ({
879
+ type: "Feature",
880
+ properties: { name, level: point.level, ...type && { type } },
881
+ geometry: {
882
+ type: "Point",
883
+ coordinates: [point.lng, point.lat]
884
+ }
885
+ });
886
+ const transformToMultiLineStrings = (segments, level) => ({
887
+ type: "Feature",
888
+ properties: { level, name: level == null ? void 0 : level.toString() },
889
+ geometry: {
890
+ type: "MultiLineString",
891
+ coordinates: segments.map((s) => s.map(({ lat, lng }) => [lng, lat]))
892
+ }
893
+ });
894
+ const levelsOfItinerary = [...new Set(this.coords.map((c) => Level.toString(c.level)))].map(Level.fromString);
895
+ const segmentsSplitted = levelsOfItinerary.map((loi) => [loi, Utils.createSegmentsAtLevel(this.coords, loi, true)]);
896
+ const multiLineStrings = segmentsSplitted.map(([loi, segments]) => transformToMultiLineStrings(segments, loi));
897
+ const legsStarts = this.legs.map((leg, idx) => transformToPoint(leg.start.coords, `Leg ${idx} start`, "leg-start"));
898
+ const legsEnds = this.legs.map((leg, idx) => transformToPoint(leg.end.coords, `Leg ${idx} end`, "leg-end"));
899
+ const steps = this.steps.map((step) => transformToPoint(step.coords, `Step ${step.number}`, "step"));
900
+ return {
901
+ type: "FeatureCollection",
902
+ features: [
903
+ transformToPoint(this.origin, "origin", "origin"),
904
+ transformToPoint(this.destination, "destination", "destination"),
905
+ ...multiLineStrings,
906
+ ...legsStarts,
907
+ ...legsEnds,
908
+ ...steps
909
+ ]
910
+ };
911
+ }
912
+ /**
913
+ * TODO: Remove it in router v3
914
+ * Update steps info thanks to the coordinates of the whole itinerary.
915
+ * This method will update:
916
+ * - all steps number
917
+ * - first/last steps
918
+ * - previousBearing/nextBearing/angle of first and last step of each leg
919
+ */
920
+ updateStepsFromLegs() {
921
+ const itineraryCoords = this.coords.filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));
922
+ const steps = this.legs.map((leg) => leg.steps).flat();
923
+ steps.map((step, stepId) => {
924
+ const coordsId = itineraryCoords.findIndex((coords) => coords.equals(step.coords));
925
+ if (coordsId === -1) {
926
+ throw new Error("Cannot find step coordinates in itinerary coordinates.");
927
+ }
928
+ const coordsBeforeStep = coordsId === 0 ? this.origin : itineraryCoords[coordsId - 1];
929
+ const coordsAfterStep = coordsId === itineraryCoords.length - 1 ? this.destination : itineraryCoords[coordsId + 1];
930
+ step.previousBearing = coordsBeforeStep.bearingTo(step.coords);
931
+ step.nextBearing = step.coords.bearingTo(coordsAfterStep);
932
+ step.angle = diffAngle(step.previousBearing, step.nextBearing + Math.PI);
933
+ step.number = stepId + 1;
934
+ step.firstStep = stepId === 0;
935
+ step.lastStep = stepId === steps.length - 1;
936
+ });
937
+ }
938
+ }
26
939
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
27
940
  var uaParser = { exports: {} };
28
941
  (function(module, exports) {
@@ -1579,20 +2492,20 @@ class GraphRouterEngineResults {
1579
2492
  }
1580
2493
  };
1581
2494
  }),
1582
- ...graph.edges.map((e2) => {
1583
- const level = e2.level;
2495
+ ...graph.edges.map((e) => {
2496
+ const level = e.level;
1584
2497
  return {
1585
2498
  type: "Feature",
1586
2499
  properties: {
1587
- id: e2.id,
2500
+ id: e.id,
1588
2501
  ...level !== null && { level },
1589
- ...e2.properties
2502
+ ...e.properties
1590
2503
  },
1591
2504
  geometry: {
1592
2505
  type: "LineString",
1593
2506
  coordinates: [
1594
- [e2.vertex1.coords.lng, e2.vertex1.coords.lat],
1595
- [e2.vertex2.coords.lng, e2.vertex2.coords.lat]
2507
+ [e.vertex1.coords.lng, e.vertex1.coords.lat],
2508
+ [e.vertex2.coords.lng, e.vertex2.coords.lat]
1596
2509
  ]
1597
2510
  }
1598
2511
  };
@@ -1612,9 +2525,9 @@ class GraphRouterEngine {
1612
2525
  const q = new Set(inputVertices);
1613
2526
  const dist = Array(q.size).fill(Number.MAX_VALUE);
1614
2527
  const prev = new Array(q.size).fill(null);
1615
- const edges = inputEdges.filter((e2) => {
2528
+ const edges = inputEdges.filter((e) => {
1616
2529
  var _a;
1617
- return (((_a = options.acceptEdgeFn) == null ? void 0 : _a.call(options, e2)) ?? true) && !this.disabledEdges.has(e2);
2530
+ return (((_a = options.acceptEdgeFn) == null ? void 0 : _a.call(options, e)) ?? true) && !this.disabledEdges.has(e);
1618
2531
  });
1619
2532
  const weightEdgeFn = options.weightEdgeFn || ((edge) => edge.length);
1620
2533
  const getVertexWithMinDistance = (vertices) => {
@@ -1698,9 +2611,9 @@ class GraphRouterEngine {
1698
2611
  "type": "Feature",
1699
2612
  "geometry": {
1700
2613
  "type": "MultiLineString",
1701
- "coordinates": edges.map((e2) => [
1702
- [e2.vertex1.coords.lng, e2.vertex1.coords.lat],
1703
- [e2.vertex2.coords.lng, e2.vertex2.coords.lat]
2614
+ "coordinates": edges.map((e) => [
2615
+ [e.vertex1.coords.lng, e.vertex1.coords.lat],
2616
+ [e.vertex2.coords.lng, e.vertex2.coords.lat]
1704
2617
  ])
1705
2618
  },
1706
2619
  "properties": {
@@ -2024,7 +2937,7 @@ const _OsmGraphUtils = class _OsmGraphUtils {
2024
2937
  }
2025
2938
  if (verticesOfEachLevel.length === 1 && verticesOfEachLevel[0].coords.level === null) {
2026
2939
  const vertex = verticesOfEachLevel[0];
2027
- const vertexEdges = edges.filter((e2) => e2.vertex1 === vertex || e2.vertex2 === vertex);
2940
+ const vertexEdges = edges.filter((e) => e.vertex1 === vertex || e.vertex2 === vertex);
2028
2941
  if (vertexEdges.length > 1) {
2029
2942
  const elevatorVertices2 = [vertex];
2030
2943
  for (let i = 1; i < vertexEdges.length; i++) {
@@ -2061,6 +2974,64 @@ __publicField(_OsmGraphUtils, "DEFAULT_WAY_SELECTOR", (way) => {
2061
2974
  return way.tags.highway && !_OsmGraphUtils.RESTRICTED_PEDESTRIANS_HIGHWAYS.includes(way.tags.highway) && !isElevatorArea || way.tags.footway === "sidewalk" || way.tags.public_transport === "platform" || way.tags.railway === "platform";
2062
2975
  });
2063
2976
  let OsmGraphUtils = _OsmGraphUtils;
2977
+ class RemoteRouter {
2978
+ }
2979
+ var StatusCode = /* @__PURE__ */ ((StatusCode2) => {
2980
+ StatusCode2[StatusCode2["OK"] = 0] = "OK";
2981
+ StatusCode2[StatusCode2["CANCELLED"] = 1] = "CANCELLED";
2982
+ StatusCode2[StatusCode2["UNKNOWN"] = 2] = "UNKNOWN";
2983
+ StatusCode2[StatusCode2["INVALID_ARGUMENT"] = 3] = "INVALID_ARGUMENT";
2984
+ StatusCode2[StatusCode2["NOT_FOUND"] = 5] = "NOT_FOUND";
2985
+ StatusCode2[StatusCode2["UNIMPLEMENTED"] = 12] = "UNIMPLEMENTED";
2986
+ StatusCode2[StatusCode2["INTERNAL"] = 13] = "INTERNAL";
2987
+ StatusCode2[StatusCode2["UNAVAILABLE"] = 14] = "UNAVAILABLE";
2988
+ StatusCode2[StatusCode2["UNAUTHENTICATED"] = 16] = "UNAUTHENTICATED";
2989
+ return StatusCode2;
2990
+ })(StatusCode || {});
2991
+ class RoutingError extends Error {
2992
+ constructor(code = StatusCode.UNKNOWN, message) {
2993
+ super(message);
2994
+ __publicField(this, "customMapName");
2995
+ this.code = code;
2996
+ }
2997
+ static notFound(details) {
2998
+ return new RoutingError(StatusCode.NOT_FOUND, `Cannot found an itinerary. Details: ${details}`);
2999
+ }
3000
+ }
3001
+ class WemapMultiRoutingError extends RoutingError {
3002
+ constructor(code = StatusCode.UNKNOWN, mapName, message) {
3003
+ super(code, message);
3004
+ this.code = code;
3005
+ this.mapName = mapName;
3006
+ this.mapName = mapName;
3007
+ }
3008
+ static notFound(mapName, details) {
3009
+ return new WemapMultiRoutingError(StatusCode.NOT_FOUND, mapName, `Cannot found an itinerary in map ${mapName}. Details: ${details || "No details"}`);
3010
+ }
3011
+ }
3012
+ class RemoteRoutingError extends RoutingError {
3013
+ constructor(code = StatusCode.UNKNOWN, routerName, message) {
3014
+ super(code, message);
3015
+ this.code = code;
3016
+ this.routerName = routerName;
3017
+ this.routerName = routerName;
3018
+ }
3019
+ static notFound(routerName, details) {
3020
+ return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Cannot found an itinerary with ${routerName}. Details: ${details || "No details"}`);
3021
+ }
3022
+ static missingApiKey(routerName, details) {
3023
+ return new RemoteRoutingError(StatusCode.UNAUTHENTICATED, routerName, `API key is missing for ${routerName}. Details: ${details}`);
3024
+ }
3025
+ static unreachableServer(routerName, url) {
3026
+ return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Remote router server ${routerName} is unreachable. URL: ${url}`);
3027
+ }
3028
+ static responseNotParsing(routerName, url) {
3029
+ return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Remote router server response ${routerName} cannot be parsed. URL: ${url}`);
3030
+ }
3031
+ static travelModeUnimplemented(routerName, travelMode) {
3032
+ return new RemoteRoutingError(StatusCode.UNIMPLEMENTED, routerName, `Travel mode "${travelMode}" is not implemented for ${routerName}`);
3033
+ }
3034
+ }
2064
3035
  function dateWithTimeZone(year, month, day, hour, minute, second, timeZone = "Europe/Paris") {
2065
3036
  const date = new Date(Date.UTC(year, month, day, hour, minute, second));
2066
3037
  const utcDate = new Date(date.toLocaleString("en-US", { timeZone: "UTC" }));
@@ -3178,6 +4149,218 @@ class IdfmRemoteRouter extends RemoteRouter {
3178
4149
  }
3179
4150
  }
3180
4151
  const IdfmRemoteRouter$1 = new IdfmRemoteRouter();
4152
+ const outputModeCorrespondance = /* @__PURE__ */ new Map();
4153
+ outputModeCorrespondance.set("CAR", "CAR");
4154
+ outputModeCorrespondance.set("WALK", "WALK");
4155
+ outputModeCorrespondance.set("BIKE", "BIKE");
4156
+ class OsrmRemoteRouter extends RemoteRouter {
4157
+ constructor() {
4158
+ super(...arguments);
4159
+ __publicField(this, "inputModeCorrespondance", (routerRequest) => {
4160
+ var _a;
4161
+ const { travelMode, travelModePreference: preference } = routerRequest;
4162
+ if (travelMode === "WALK" && ((_a = routerRequest.itineraryModifiers) == null ? void 0 : _a.isWheelchair))
4163
+ return "pmr";
4164
+ if (travelMode === "WALK")
4165
+ return "walking";
4166
+ if (travelMode === "BIKE") {
4167
+ if (preference === "FASTEST")
4168
+ return "bike-fastest";
4169
+ if (preference === "SAFEST")
4170
+ return "bike-safest";
4171
+ if (preference === "TOURISM")
4172
+ return "bike-safest";
4173
+ return "bike-safest";
4174
+ }
4175
+ if (travelMode === "CAR")
4176
+ return "driving";
4177
+ throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);
4178
+ });
4179
+ }
4180
+ get rname() {
4181
+ return "osrm";
4182
+ }
4183
+ async getItineraries(endpointUrl, routerRequest) {
4184
+ const url = this.getURL(endpointUrl, routerRequest);
4185
+ const res = await fetch(url).catch(() => {
4186
+ throw RemoteRoutingError.unreachableServer(this.rname, url);
4187
+ });
4188
+ const jsonResponse = await res.json().catch(() => {
4189
+ throw RemoteRoutingError.responseNotParsing(this.rname, url);
4190
+ });
4191
+ return this.parseResponse(jsonResponse, routerRequest.origin, routerRequest.destination, routerRequest.travelMode);
4192
+ }
4193
+ /**
4194
+ * @throws {TravelModeCorrespondanceNotFound}
4195
+ */
4196
+ getURL(endpointUrl, routerRequest) {
4197
+ const { origin, destination } = routerRequest;
4198
+ const osrmMode = this.inputModeCorrespondance(routerRequest);
4199
+ const waypoints = [origin, ...routerRequest.waypoints || [], destination];
4200
+ let url = endpointUrl + "/route/v1/" + osrmMode + "/";
4201
+ url += waypoints.map((waypoint) => [waypoint.longitude + "," + waypoint.latitude]).join(";");
4202
+ url += "?geometries=geojson&overview=full&steps=true";
4203
+ routerRequest.provideItineraryAlternatives && (url += "&alternatives=true");
4204
+ return url;
4205
+ }
4206
+ coordinatesToJson({ lat, lng, level }) {
4207
+ if (level === null) {
4208
+ return [lng, lat];
4209
+ }
4210
+ if (Level.isRange(level)) {
4211
+ return [lng, lat, level[0]];
4212
+ }
4213
+ return [lng, lat, level];
4214
+ }
4215
+ /**
4216
+ * @param {object} json
4217
+ * @returns {Coordinates}
4218
+ */
4219
+ jsonToCoordinates(json) {
4220
+ const coords = new Coordinates(json[1], json[0]);
4221
+ if (json.length > 2) {
4222
+ coords.level = json[2];
4223
+ }
4224
+ return coords;
4225
+ }
4226
+ getModifierFromAngle(_angle) {
4227
+ const angle = positiveMod(rad2deg(_angle), 360);
4228
+ if (angle > 0 && angle < 60) {
4229
+ return "sharp right";
4230
+ }
4231
+ if (angle >= 60 && angle < 140) {
4232
+ return "right";
4233
+ }
4234
+ if (angle >= 140 && angle < 160) {
4235
+ return "slight right";
4236
+ }
4237
+ if (angle >= 160 && angle <= 200) {
4238
+ return "straight";
4239
+ }
4240
+ if (angle > 200 && angle <= 220) {
4241
+ return "slight left";
4242
+ }
4243
+ if (angle > 220 && angle <= 300) {
4244
+ return "left";
4245
+ }
4246
+ if (angle > 300 && angle < 360) {
4247
+ return "sharp left";
4248
+ }
4249
+ return "u turn";
4250
+ }
4251
+ noRouteFoundJson(message) {
4252
+ return {
4253
+ "code": "NoRoute",
4254
+ message
4255
+ };
4256
+ }
4257
+ /**
4258
+ * @deprecated
4259
+ */
4260
+ itineraryToOsrmJson(itinerary) {
4261
+ const lastLegId = itinerary.legs.length - 1;
4262
+ const itinerarySteps = itinerary.steps;
4263
+ const jsonLegs = itinerary.legs.map(({ distance, duration, coords }, idLeg) => {
4264
+ const legSteps = itinerarySteps.filter(
4265
+ (step) => coords.find((_coords) => _coords.equals(step.coords))
4266
+ );
4267
+ const lastStepId = legSteps.length - 1;
4268
+ return {
4269
+ distance,
4270
+ duration: duration || 0,
4271
+ steps: legSteps.map((step, idStep, arr) => {
4272
+ let type = idStep === 0 && idLeg === 0 ? "depart" : "turn";
4273
+ type = idStep === lastStepId && idLeg === lastLegId ? "arrive" : type;
4274
+ const stepCoordsIdx = coords.findIndex((p) => p.equals(step.coords));
4275
+ const nextStepCoordsIdx = idStep === lastStepId ? stepCoordsIdx : coords.findIndex((p) => p.equals(arr[idStep + 1].coords));
4276
+ const osrmStep = {
4277
+ geometry: {
4278
+ type: "LineString",
4279
+ coordinates: coords.slice(stepCoordsIdx, nextStepCoordsIdx + 1).map(this.coordinatesToJson)
4280
+ },
4281
+ distance: step.distance,
4282
+ duration: step.duration || 0,
4283
+ ...step.name && { name: step.name },
4284
+ maneuver: {
4285
+ bearing_before: rad2deg(step.previousBearing),
4286
+ bearing_after: rad2deg(step.nextBearing),
4287
+ location: this.coordinatesToJson(step.coords),
4288
+ modifier: this.getModifierFromAngle(step.angle),
4289
+ type
4290
+ }
4291
+ };
4292
+ return osrmStep;
4293
+ })
4294
+ };
4295
+ });
4296
+ return {
4297
+ "code": "Ok",
4298
+ "routes": [
4299
+ {
4300
+ "geometry": {
4301
+ "type": "LineString",
4302
+ "coordinates": itinerary.coords.map(this.coordinatesToJson)
4303
+ },
4304
+ "legs": jsonLegs,
4305
+ "distance": itinerary.distance,
4306
+ "duration": itinerary.duration,
4307
+ "weight_name": "routability",
4308
+ "weight": 0
4309
+ }
4310
+ ],
4311
+ "waypoints": []
4312
+ };
4313
+ }
4314
+ parseResponse(json, origin, destination, travelMode) {
4315
+ const transitMode = outputModeCorrespondance.get(travelMode);
4316
+ const { routes: jsonRoutes } = json;
4317
+ if (!jsonRoutes) {
4318
+ throw RemoteRoutingError.notFound(this.rname, json.message);
4319
+ }
4320
+ return jsonRoutes.map((jsonItinerary) => {
4321
+ const legs = jsonItinerary.legs.map((jsonLeg) => {
4322
+ var _a;
4323
+ const legCoords = jsonLeg.steps.map((step) => step.geometry.coordinates.map(this.jsonToCoordinates)).flat().filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));
4324
+ const startCoords = legCoords[0];
4325
+ const endCoords = legCoords[legCoords.length - 1];
4326
+ const stepsBuilder = new StepsBuilder().setPathCoords(legCoords).setStart(startCoords).setEnd(endCoords);
4327
+ (_a = jsonLeg.steps) == null ? void 0 : _a.forEach(({ maneuver, name, distance, duration }) => {
4328
+ const stepCoords = this.jsonToCoordinates(maneuver.location);
4329
+ const distances = legCoords.map((coords) => coords.distanceTo(stepCoords));
4330
+ const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));
4331
+ if (idStepCoordsInLeg < 0) {
4332
+ throw new Error("Osrm Parser: Cannot find step coords in leg coordinates");
4333
+ }
4334
+ stepsBuilder.addStepInfo({
4335
+ coords: legCoords[idStepCoordsInLeg],
4336
+ name,
4337
+ distance,
4338
+ duration
4339
+ });
4340
+ });
4341
+ return new Leg({
4342
+ transitMode,
4343
+ duration: jsonLeg.duration,
4344
+ coords: legCoords,
4345
+ start: {
4346
+ coords: startCoords
4347
+ },
4348
+ end: {
4349
+ coords: endCoords
4350
+ },
4351
+ steps: stepsBuilder.build()
4352
+ });
4353
+ });
4354
+ return new Itinerary({
4355
+ duration: jsonItinerary.duration,
4356
+ origin,
4357
+ destination,
4358
+ legs
4359
+ });
4360
+ });
4361
+ }
4362
+ }
4363
+ const OsrmRemoteRouter$1 = new OsrmRemoteRouter();
3181
4364
  function isLegPT(leg) {
3182
4365
  return leg.mode === "BUS" || leg.mode === "TRAM";
3183
4366
  }
@@ -3333,7 +4516,7 @@ const remoteRouters = [
3333
4516
  NavitiaRemoteRouter$1,
3334
4517
  DeutscheBahnRemoteRouter$1,
3335
4518
  IdfmRemoteRouter$1,
3336
- OsrmRemoteRouter,
4519
+ OsrmRemoteRouter$1,
3337
4520
  OtpRemoteRouter$1,
3338
4521
  WemapMultiRemoteRouter$1
3339
4522
  ];
@@ -3439,11 +4622,11 @@ class WemapMultiRouter {
3439
4622
  };
3440
4623
  try {
3441
4624
  remoteRouterItineraries = await RemoteRouterManager$1.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);
3442
- } catch (e2) {
3443
- if (e2 instanceof RemoteRoutingError) {
3444
- e2.message = customError(e2.message);
4625
+ } catch (e) {
4626
+ if (e instanceof RemoteRoutingError) {
4627
+ e.message = customError(e.message);
3445
4628
  }
3446
- throw e2;
4629
+ throw e;
3447
4630
  }
3448
4631
  ioMapItinerary = Itinerary.fromGraphRoute(ioMapRoute);
3449
4632
  return remoteRouterItineraries.map(
@@ -3472,11 +4655,11 @@ class WemapMultiRouter {
3472
4655
  };
3473
4656
  try {
3474
4657
  remoteRouterItineraries = await RemoteRouterManager$1.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);
3475
- } catch (e2) {
3476
- if (e2 instanceof RemoteRoutingError) {
3477
- e2.message = customError(e2.message);
4658
+ } catch (e) {
4659
+ if (e instanceof RemoteRoutingError) {
4660
+ e.message = customError(e.message);
3478
4661
  }
3479
- throw e2;
4662
+ throw e;
3480
4663
  }
3481
4664
  ioMapItinerary = Itinerary.fromGraphRoute(ioMapRoute);
3482
4665
  return remoteRouterItineraries.map(
@@ -3519,11 +4702,11 @@ class WemapMultiRouter {
3519
4702
  };
3520
4703
  try {
3521
4704
  remoteRouterItineraries = await RemoteRouterManager$1.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);
3522
- } catch (e2) {
3523
- if (e2 instanceof RemoteRoutingError) {
3524
- e2.message = customError(e2.message);
4705
+ } catch (e) {
4706
+ if (e instanceof RemoteRoutingError) {
4707
+ e.message = customError(e.message);
3525
4708
  }
3526
- throw e2;
4709
+ throw e;
3527
4710
  }
3528
4711
  return remoteRouterItineraries.map(
3529
4712
  (remoteRouterItinerary) => Itinerary.fromItineraries(
@@ -3574,8 +4757,8 @@ class CustomGraphMap {
3574
4757
  let osmModel;
3575
4758
  try {
3576
4759
  osmModel = OsmParser.parseOsmXmlString(osmXmlString);
3577
- } catch (e2) {
3578
- errors.couldNotParseFile = e2 instanceof Error ? e2.message : "Unknown error";
4760
+ } catch (e) {
4761
+ errors.couldNotParseFile = e instanceof Error ? e.message : "Unknown error";
3579
4762
  callbackErrors == null ? void 0 : callbackErrors(errors);
3580
4763
  return;
3581
4764
  }
@@ -3693,7 +4876,7 @@ class CustomGraphMapTester {
3693
4876
  static createReport(osmXmlString) {
3694
4877
  var _a;
3695
4878
  let customGraphMapErrors;
3696
- const customGraphMap = CustomGraphMap.fromOsmXml(osmXmlString, null, (e2) => customGraphMapErrors = e2);
4879
+ const customGraphMap = CustomGraphMap.fromOsmXml(osmXmlString, null, (e) => customGraphMapErrors = e);
3697
4880
  const errors = [];
3698
4881
  if ((customGraphMapErrors == null ? void 0 : customGraphMapErrors.couldNotParseFile) || !customGraphMap) {
3699
4882
  errors.push({
@@ -3857,7 +5040,7 @@ export {
3857
5040
  Edge,
3858
5041
  GeoveloRemoteRouter$1 as GeoveloRemoteRouter,
3859
5042
  Graph,
3860
- d as GraphProjection,
5043
+ GraphProjection,
3861
5044
  GraphRoute,
3862
5045
  GraphRouter,
3863
5046
  GraphRouterOptionsBuilder,
@@ -3868,12 +5051,12 @@ export {
3868
5051
  NavitiaRemoteRouter$1 as NavitiaRemoteRouter,
3869
5052
  NoRouteFoundError,
3870
5053
  OsmGraphUtils,
3871
- OsrmRemoteRouter,
5054
+ OsrmRemoteRouter$1 as OsrmRemoteRouter,
3872
5055
  OtpRemoteRouter$1 as OtpRemoteRouter,
3873
5056
  RemoteRouterManager$1 as RemoteRouterManager,
3874
5057
  RemoteRoutingError,
3875
- e as RoutingError,
3876
- f as StatusCode,
5058
+ RoutingError,
5059
+ StatusCode,
3877
5060
  Vertex,
3878
5061
  WemapMultiRemoteRouter$1 as WemapMultiRemoteRouter,
3879
5062
  WemapMultiRouter,