@wemap/routers 11.0.0-alpha.8 → 11.0.1

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.
Files changed (38) hide show
  1. package/dist/index.js +533 -291
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +536 -295
  4. package/dist/index.mjs.map +1 -1
  5. package/helpers/InstructionManager.ts +4 -4
  6. package/index.ts +7 -9
  7. package/package.json +9 -7
  8. package/src/ItineraryInfoManager.spec.ts +14 -14
  9. package/src/ItineraryInfoManager.ts +13 -13
  10. package/src/model/Itinerary.spec.ts +12 -6
  11. package/src/model/Itinerary.ts +70 -69
  12. package/src/model/Leg.spec.ts +4 -4
  13. package/src/model/Leg.ts +78 -33
  14. package/src/model/Step.spec.ts +99 -0
  15. package/src/model/Step.ts +78 -11
  16. package/src/model/generateSteps.ts +20 -12
  17. package/src/remote/RemoteRouterManager.ts +17 -15
  18. package/src/remote/cityway/CitywayRemoteRouter.ts +16 -11
  19. package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.ts +1 -3
  20. package/src/remote/idfm/IdfmRemoteRouter.ts +31 -31
  21. package/src/remote/osrm/OsrmRemoteRouter.ts +5 -8
  22. package/src/remote/otp/OtpRemoteRouter.ts +9 -12
  23. package/src/remote/wemap-multi/WemapMultiRemoteRouter.ts +1 -3
  24. package/src/remote/wemap-multi/WemapMultiRemoteRouterPayload.ts +3 -3
  25. package/src/wemap-multi/CustomNetworkMap.ts +56 -32
  26. package/src/wemap-multi/WemapMultiRouter.ts +71 -24
  27. package/src/wemap-multi/WemapMultiRouterOptions.ts +5 -1
  28. package/src/wemap-osm/OsmGraph.spec.ts +99 -0
  29. package/src/wemap-osm/OsmGraph.ts +188 -0
  30. package/src/wemap-osm/{WemapOsmRouter.spec.ts → OsmRouter.spec.ts} +94 -35
  31. package/src/wemap-osm/OsmRouter.ts +210 -0
  32. package/vite.config.ts +1 -1
  33. package/src/model/ItineraryInfo.ts +0 -19
  34. package/src/model/StepInfo.spec.ts +0 -78
  35. package/src/model/StepInfo.ts +0 -78
  36. package/src/wemap-osm/WemapOsmRouter.ts +0 -82
  37. package/src/wemap-osm/WemapOsmRouterOptions.ts +0 -23
  38. package/src/wemap-osm/WemapOsmRouterUtils.ts +0 -21
package/dist/index.js CHANGED
@@ -8,13 +8,14 @@ var __publicField = (obj, key, value) => {
8
8
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
9
9
  const geo = require("@wemap/geo");
10
10
  const maths = require("@wemap/maths");
11
+ const salesman = require("@wemap/salesman.js");
11
12
  const osm = require("@wemap/osm");
12
13
  const Logger = require("@wemap/logger");
13
14
  const Polyline = require("@mapbox/polyline");
14
15
  const pointInPolygon = require("@turf/boolean-point-in-polygon");
15
16
  const convexHullFn = require("@turf/convex");
16
- const helpers = require("@turf/helpers");
17
17
  const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
18
+ const salesman__default = /* @__PURE__ */ _interopDefaultLegacy(salesman);
18
19
  const Logger__default = /* @__PURE__ */ _interopDefaultLegacy(Logger);
19
20
  const Polyline__default = /* @__PURE__ */ _interopDefaultLegacy(Polyline);
20
21
  const pointInPolygon__default = /* @__PURE__ */ _interopDefaultLegacy(pointInPolygon);
@@ -22,53 +23,6 @@ const convexHullFn__default = /* @__PURE__ */ _interopDefaultLegacy(convexHullFn
22
23
  function getDurationFromLength(length, speed = 5) {
23
24
  return length / (speed * 1e3 / 3600);
24
25
  }
25
- function areLevelChangeEquals(l1, l2) {
26
- return l1 === l2 || l1.difference === l2.difference && l1.direction === l2.direction && l1.type === l2.type;
27
- }
28
- class StepInfo {
29
- constructor({
30
- coords,
31
- distance,
32
- name,
33
- levelChange,
34
- extras,
35
- duration
36
- }) {
37
- __publicField(this, "coords");
38
- __publicField(this, "name");
39
- __publicField(this, "distance");
40
- __publicField(this, "duration");
41
- __publicField(this, "levelChange");
42
- __publicField(this, "extras");
43
- this.coords = coords;
44
- this.name = name || null;
45
- this.distance = typeof distance === "number" ? distance : null;
46
- this.duration = typeof duration === "number" ? duration : null;
47
- this.levelChange = levelChange || null;
48
- this.extras = extras || null;
49
- }
50
- static equals(obj1, obj2) {
51
- return obj1.coords.equals(obj2.coords) && obj1.distance === obj2.distance && obj1.duration === obj2.duration && obj1.name === obj2.name && (obj1.levelChange === obj2.levelChange || obj1.levelChange && obj2.levelChange && areLevelChangeEquals(obj1.levelChange, obj2.levelChange));
52
- }
53
- equals(obj) {
54
- return StepInfo.equals(this, obj);
55
- }
56
- toJson() {
57
- return {
58
- coords: this.coords.toCompressedJson(),
59
- ...this.distance !== null && { distance: this.distance },
60
- ...this.duration !== null && { duration: this.duration },
61
- ...this.name !== null && { name: this.name },
62
- ...this.levelChange !== null && { levelChange: this.levelChange },
63
- ...this.extras && Object.keys(this.extras).length !== 0 && { extras: this.extras }
64
- };
65
- }
66
- static fromJson(json) {
67
- return new StepInfo(Object.assign({}, json, {
68
- coords: geo.Coordinates.fromCompressedJson(json.coords)
69
- }));
70
- }
71
- }
72
26
  const SKIP_STEP_ANGLE_MAX = maths.deg2rad(20);
73
27
  function generateSteps(leg, rules) {
74
28
  const steps = [];
@@ -85,26 +39,30 @@ function generateSteps(leg, rules) {
85
39
  let splitByAngle = Math.abs(maths.diffAngle(Math.PI, angle)) >= SKIP_STEP_ANGLE_MAX;
86
40
  const splitByLevel = geo.Level.isRange(edgeLevel) && !geo.Level.isRange(currentCoords.level);
87
41
  splitByAngle = splitByAngle && !(currentCoords.level && geo.Level.isRange(currentCoords.level));
88
- const customRules = rules == null ? void 0 : rules(currentCoords, nextCoords);
42
+ const previousStep = steps.length ? steps[steps.length - 1] : null;
43
+ const customRules = rules == null ? void 0 : rules(currentCoords, nextCoords, previousStep);
89
44
  const splitStepCondition = splitByAngle || splitByLevel || (customRules == null ? void 0 : customRules.createNewStep);
90
45
  if (isFirstStep || splitStepCondition) {
91
46
  let levelChange;
92
- if (splitByLevel) {
93
- const difference = geo.Level.diff(currentCoords.level, nextCoords.level);
94
- const direction = difference > 0 ? "up" : "down";
47
+ if (splitByLevel || (customRules == null ? void 0 : customRules.levelChangeType)) {
48
+ const difference = geo.Level.diff(currentCoords.level, nextCoords.level) || 0;
49
+ let direction = difference > 0 ? "up" : "down";
50
+ if (difference === 0 && (customRules == null ? void 0 : customRules.levelChangeDirection)) {
51
+ direction = customRules.levelChangeDirection;
52
+ }
95
53
  levelChange = { difference, direction, type: customRules == null ? void 0 : customRules.levelChangeType };
96
54
  }
97
55
  if (currentStep && currentStep.duration === 0) {
98
- currentStep.duration = null;
56
+ delete currentStep.duration;
99
57
  }
100
- currentStep = new StepInfo({
58
+ currentStep = {
101
59
  coords: currentCoords,
102
60
  name: customRules == null ? void 0 : customRules.stepName,
103
61
  extras: customRules == null ? void 0 : customRules.stepExtras,
104
62
  levelChange,
105
63
  distance: 0,
106
64
  duration: 0
107
- });
65
+ };
108
66
  steps.push(currentStep);
109
67
  }
110
68
  currentStep.distance += currentCoords.distanceTo(nextCoords);
@@ -115,7 +73,7 @@ function generateSteps(leg, rules) {
115
73
  }
116
74
  const lastCoords = coordsArray[coordsArray.length - 1];
117
75
  if (!geo.Coordinates.equals(lastCoords, to.coords)) {
118
- steps.push(new StepInfo({ coords: lastCoords }));
76
+ steps.push({ coords: lastCoords });
119
77
  }
120
78
  return steps;
121
79
  }
@@ -131,6 +89,36 @@ function isRoutingModePublicTransport(routingMode) {
131
89
  "TRAM"
132
90
  ].includes(routingMode);
133
91
  }
92
+ function stepToJson(step) {
93
+ return {
94
+ ...step.firstStep && { firstStep: true },
95
+ ...step.lastStep && { lastStep: true },
96
+ number: step.number,
97
+ coords: step.coords.toCompressedJson(),
98
+ ...step.name !== null && { name: step.name },
99
+ angle: Number(step.angle.toFixed(2)),
100
+ previousBearing: Number(step.previousBearing.toFixed(2)),
101
+ nextBearing: Number(step.nextBearing.toFixed(2)),
102
+ distance: Number(step.distance.toFixed(1)),
103
+ duration: Number(step.duration.toFixed(1)),
104
+ ...step.levelChange !== null && { levelChange: step.levelChange },
105
+ ...step.extras && Object.keys(step.extras).length !== 0 && { extras: step.extras }
106
+ };
107
+ }
108
+ function jsonToStep(json) {
109
+ return Object.assign({}, json, {
110
+ coords: geo.Coordinates.fromCompressedJson(json.coords),
111
+ firstStep: Boolean(json.firstStep),
112
+ lastStep: Boolean(json.lastStep),
113
+ name: json.name || null,
114
+ levelChange: json.levelChange || null,
115
+ extras: json.extras || null
116
+ });
117
+ }
118
+ function stepEquals(step1, step2) {
119
+ var _a, _b, _c, _d, _e, _f;
120
+ 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;
121
+ }
134
122
  class Leg {
135
123
  constructor({
136
124
  from,
@@ -151,7 +139,7 @@ class Leg {
151
139
  __publicField(this, "duration");
152
140
  __publicField(this, "startTime");
153
141
  __publicField(this, "endTime");
154
- __publicField(this, "stepsInfo");
142
+ __publicField(this, "steps");
155
143
  __publicField(this, "transportInfo");
156
144
  this.from = {
157
145
  name: from.name || null,
@@ -168,17 +156,22 @@ class Leg {
168
156
  this.startTime = typeof startTime === "number" ? startTime : null;
169
157
  this.endTime = typeof endTime === "number" ? endTime : null;
170
158
  this.transportInfo = transportInfo || null;
171
- this.stepsInfo = "stepsInfo" in otherParams ? otherParams.stepsInfo : generateSteps(this, otherParams.stepsGenerationRules);
159
+ if ("steps" in otherParams) {
160
+ this.steps = otherParams.steps;
161
+ return;
162
+ }
163
+ const minStepsInfo = "minStepsInfo" in otherParams ? otherParams.minStepsInfo : generateSteps(this, otherParams.stepsGenerationRules);
164
+ this.steps = Leg.generateStepsFromMinStepInfo(from.coords, to.coords, coords, minStepsInfo);
172
165
  }
173
166
  isPublicTransport() {
174
167
  return isRoutingModePublicTransport(this.mode);
175
168
  }
176
- toNetwork() {
177
- return geo.Network.fromCoordinates([this.coords]);
169
+ toGraph() {
170
+ return geo.GeoGraph.fromCoordinates([this.coords]);
178
171
  }
179
172
  static equals(obj1, obj2) {
180
173
  var _a, _b;
181
- const intermediate = obj1.mode === obj2.mode && obj1.duration === obj2.duration && obj1.startTime === obj2.startTime && obj1.endTime === obj2.endTime && obj1.from.name === obj2.from.name && obj1.from.coords.equals(obj2.from.coords) && obj1.to.name === obj2.to.name && obj1.to.coords.equals(obj2.to.coords) && obj1.coords.length === obj2.coords.length && (obj1.stepsInfo === obj2.stepsInfo || ((_a = obj1.stepsInfo) == null ? void 0 : _a.length) === ((_b = obj2.stepsInfo) == null ? void 0 : _b.length));
174
+ const intermediate = obj1.mode === obj2.mode && Math.abs(obj1.duration - obj2.duration) <= 0.05 && obj1.startTime === obj2.startTime && obj1.endTime === obj2.endTime && obj1.from.name === obj2.from.name && obj1.from.coords.equals(obj2.from.coords) && obj1.to.name === obj2.to.name && obj1.to.coords.equals(obj2.to.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));
182
175
  if (!intermediate) {
183
176
  return false;
184
177
  }
@@ -188,11 +181,9 @@ class Leg {
188
181
  return false;
189
182
  }
190
183
  }
191
- if (obj1.stepsInfo && obj2.stepsInfo) {
192
- for (i = 0; i < obj1.stepsInfo.length; i++) {
193
- if (!obj1.stepsInfo[i].equals(obj2.stepsInfo[i])) {
194
- return false;
195
- }
184
+ for (i = 0; i < obj1.steps.length; i++) {
185
+ if (!stepEquals(obj1.steps[i], obj2.steps[i])) {
186
+ return false;
196
187
  }
197
188
  }
198
189
  if (obj1.transportInfo !== obj2.transportInfo) {
@@ -219,9 +210,9 @@ class Leg {
219
210
  coords: this.to.coords.toCompressedJson(),
220
211
  ...this.to.name && { name: this.to.name }
221
212
  },
222
- duration: this.duration,
213
+ duration: Number(this.duration.toFixed(1)),
223
214
  coords: this.coords.map((coords) => coords.toCompressedJson()),
224
- steps: this.stepsInfo.map((stepInfo) => stepInfo.toJson()),
215
+ steps: this.steps.map(stepToJson),
225
216
  ...this.startTime !== null && { startTime: this.startTime },
226
217
  ...this.endTime !== null && { endTime: this.endTime },
227
218
  ...this.transportInfo !== null && { transportInfo: this.transportInfo }
@@ -239,8 +230,7 @@ class Leg {
239
230
  name: json.to.name || null
240
231
  },
241
232
  coords: json.coords.map(geo.Coordinates.fromCompressedJson),
242
- stepsInfo: ((_a = json.steps) == null ? void 0 : _a.map(StepInfo.fromJson)) || null,
243
- stepsGenerationRules: void 0
233
+ steps: ((_a = json.steps) == null ? void 0 : _a.map(jsonToStep)) || null
244
234
  }));
245
235
  return leg;
246
236
  }
@@ -248,7 +238,7 @@ class Leg {
248
238
  return new Leg({
249
239
  from: { coords: graphItinerary.start },
250
240
  to: { coords: graphItinerary.end },
251
- coords: graphItinerary.nodes.map((node) => node.coords),
241
+ coords: graphItinerary.vertices.map((vertex) => vertex.coords),
252
242
  duration: graphItinerary.edgesWeights.reduce((acc, weight) => acc + weight, 0),
253
243
  mode,
254
244
  stepsGenerationRules
@@ -260,12 +250,45 @@ class Leg {
260
250
  for (const coords of this.coords) {
261
251
  coords.level = geo.Level.multiplyBy(coords.level, levelFactor);
262
252
  }
263
- this.stepsInfo.forEach((step) => {
253
+ this.steps.forEach((step) => {
264
254
  step.coords.level = geo.Level.multiplyBy(step.coords.level, levelFactor);
265
255
  });
266
256
  }
267
- getSteps(itinerarySteps) {
268
- return this.stepsInfo.map((stepInfo) => itinerarySteps.find((_step) => _step.coords.equals(stepInfo.coords)));
257
+ static generateStepsFromMinStepInfo(from, to, legCoords, stepsInfo) {
258
+ return stepsInfo.map((stepInfo, stepId) => {
259
+ const coordsId = legCoords.findIndex((coords) => coords.equals(stepInfo.coords));
260
+ if (coordsId === -1) {
261
+ throw new Error("Cannot find step coordinates in itinerary coordinates.");
262
+ }
263
+ const coordsBeforeStep = coordsId === 0 ? from : legCoords[coordsId - 1];
264
+ const coordsAfterStep = coordsId === legCoords.length - 1 ? to : legCoords[coordsId + 1];
265
+ const previousBearing = coordsBeforeStep.bearingTo(stepInfo.coords);
266
+ const nextBearing = stepInfo.coords.bearingTo(coordsAfterStep);
267
+ let distance = 0;
268
+ const coordsToStopCalculation = stepId !== stepsInfo.length - 1 ? stepsInfo[stepId + 1].coords : legCoords[legCoords.length - 1];
269
+ let currentCoordsId = coordsId;
270
+ while (!legCoords[currentCoordsId].equals(coordsToStopCalculation)) {
271
+ distance += legCoords[currentCoordsId].distanceTo(legCoords[currentCoordsId + 1]);
272
+ currentCoordsId++;
273
+ }
274
+ if (currentCoordsId === legCoords.length - 1) {
275
+ distance += legCoords[currentCoordsId].distanceTo(to);
276
+ }
277
+ return {
278
+ coords: stepInfo.coords,
279
+ name: stepInfo.name || null,
280
+ number: stepId + 1,
281
+ previousBearing,
282
+ nextBearing,
283
+ angle: maths.diffAngle(previousBearing, nextBearing + Math.PI),
284
+ firstStep: stepId === 0,
285
+ lastStep: stepId === stepsInfo.length - 1,
286
+ distance,
287
+ duration: stepInfo.duration || getDurationFromLength(distance),
288
+ levelChange: stepInfo.levelChange || null,
289
+ extras: stepInfo.extras || null
290
+ };
291
+ });
269
292
  }
270
293
  }
271
294
  class Itinerary {
@@ -285,7 +308,6 @@ class Itinerary {
285
308
  __publicField(this, "startTime");
286
309
  __publicField(this, "endTime");
287
310
  __publicField(this, "_coords", null);
288
- __publicField(this, "_steps", null);
289
311
  __publicField(this, "_distance", null);
290
312
  this.from = from;
291
313
  this.to = to;
@@ -293,6 +315,7 @@ class Itinerary {
293
315
  this.duration = typeof duration === "number" ? duration : this.legs.reduce((dur, leg) => dur + leg.duration, 0);
294
316
  this.startTime = typeof startTime === "number" ? startTime : null;
295
317
  this.endTime = typeof endTime === "number" ? endTime : null;
318
+ this.updateStepsFromLegs();
296
319
  }
297
320
  set coords(_) {
298
321
  throw new Error("Itinerary.coords cannot be set. They are calculated from Itinerary.legs.");
@@ -307,45 +330,7 @@ class Itinerary {
307
330
  throw new Error("Itinerary.step cannot be set. They are calculated from Itinerary.legs.");
308
331
  }
309
332
  get steps() {
310
- if (this._steps) {
311
- return this._steps;
312
- }
313
- const itineraryCoords = this.coords.filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));
314
- const stepsInfo = this.legs.map((leg) => leg.stepsInfo).flat();
315
- const steps = stepsInfo.map((stepInfo, stepId) => {
316
- const coordsId = itineraryCoords.findIndex((coords) => coords.equals(stepInfo.coords));
317
- if (coordsId === -1) {
318
- throw new Error("Cannot find step coordinates in itinerary coordinates.");
319
- }
320
- const coordsBeforeStep = coordsId === 0 ? this.from : itineraryCoords[coordsId - 1];
321
- const coordsAfterStep = coordsId === itineraryCoords.length - 1 ? this.to : itineraryCoords[coordsId + 1];
322
- const previousBearing = coordsBeforeStep.bearingTo(stepInfo.coords);
323
- const nextBearing = stepInfo.coords.bearingTo(coordsAfterStep);
324
- let distance = 0;
325
- const coordsToStopCalculation = stepId !== stepsInfo.length - 1 ? stepsInfo[stepId + 1].coords : itineraryCoords[itineraryCoords.length - 1];
326
- let currentCoordsId = coordsId;
327
- while (!itineraryCoords[currentCoordsId].equals(coordsToStopCalculation)) {
328
- distance += itineraryCoords[currentCoordsId].distanceTo(itineraryCoords[currentCoordsId + 1]);
329
- currentCoordsId++;
330
- }
331
- if (currentCoordsId === itineraryCoords.length - 1) {
332
- distance += itineraryCoords[currentCoordsId].distanceTo(this.to);
333
- }
334
- return {
335
- ...stepInfo,
336
- number: stepId + 1,
337
- previousBearing,
338
- nextBearing,
339
- angle: maths.diffAngle(previousBearing, nextBearing + Math.PI),
340
- firstStep: stepId === 0,
341
- lastStep: stepId === stepsInfo.length - 1,
342
- distance,
343
- duration: stepInfo.duration || getDurationFromLength(distance),
344
- previousStep: null,
345
- nextStep: null
346
- };
347
- });
348
- return steps;
333
+ return this.legs.map((leg) => leg.steps).flat();
349
334
  }
350
335
  set mode(_) {
351
336
  throw new Error("Itinerary.mode cannot be set. They are calculated from Itinerary.legs.");
@@ -381,8 +366,8 @@ class Itinerary {
381
366
  }
382
367
  return this._distance;
383
368
  }
384
- toNetwork() {
385
- return geo.Network.fromCoordinates([this.coords]);
369
+ toGraph() {
370
+ return geo.GeoGraph.fromCoordinates([this.coords]);
386
371
  }
387
372
  static fromItineraries(...itineraries) {
388
373
  let duration = 0;
@@ -416,7 +401,7 @@ class Itinerary {
416
401
  return new Itinerary({ from, to, legs: [leg] });
417
402
  }
418
403
  static equals(obj1, obj2) {
419
- const intermediate = obj1.from.equals(obj2.from) && obj1.to.equals(obj2.to) && obj1.distance === obj2.distance && obj1.duration === obj2.duration && obj1.startTime === obj2.startTime && obj1.endTime === obj2.endTime && obj1.legs.length === obj2.legs.length;
404
+ const intermediate = obj1.from.equals(obj2.from) && obj1.to.equals(obj2.to) && 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;
420
405
  if (!intermediate) {
421
406
  return false;
422
407
  }
@@ -434,7 +419,7 @@ class Itinerary {
434
419
  return {
435
420
  from: this.from.toCompressedJson(),
436
421
  to: this.to.toCompressedJson(),
437
- duration: this.duration,
422
+ duration: Number(this.duration.toFixed(1)),
438
423
  mode: this.mode,
439
424
  legs: this.legs.map((leg) => leg.toJson()),
440
425
  ...this.startTime !== null && { startTime: this.startTime },
@@ -474,8 +459,8 @@ class Itinerary {
474
459
  for (const coords of leg.coords) {
475
460
  coords.level = coords.level || 0;
476
461
  }
477
- if (leg.stepsInfo) {
478
- for (const step of leg.stepsInfo) {
462
+ if (leg.steps) {
463
+ for (const step of leg.steps) {
479
464
  step.coords.level = step.coords.level || 0;
480
465
  }
481
466
  }
@@ -496,6 +481,36 @@ class Itinerary {
496
481
  }
497
482
  };
498
483
  }
484
+ updateStepsFromLegs() {
485
+ const itineraryCoords = this.coords.filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));
486
+ const steps = this.legs.map((leg) => leg.steps).flat();
487
+ steps.map((step, stepId) => {
488
+ const coordsId = itineraryCoords.findIndex((coords) => coords.equals(step.coords));
489
+ if (coordsId === -1) {
490
+ throw new Error("Cannot find step coordinates in itinerary coordinates.");
491
+ }
492
+ const coordsBeforeStep = coordsId === 0 ? this.from : itineraryCoords[coordsId - 1];
493
+ const coordsAfterStep = coordsId === itineraryCoords.length - 1 ? this.to : itineraryCoords[coordsId + 1];
494
+ step.previousBearing = coordsBeforeStep.bearingTo(step.coords);
495
+ step.nextBearing = step.coords.bearingTo(coordsAfterStep);
496
+ step.angle = maths.diffAngle(step.previousBearing, step.nextBearing + Math.PI);
497
+ const stepDistanceBefore = step.distance;
498
+ step.distance = 0;
499
+ const coordsToStopCalculation = stepId !== steps.length - 1 ? steps[stepId + 1].coords : itineraryCoords[itineraryCoords.length - 1];
500
+ let currentCoordsId = coordsId;
501
+ while (!itineraryCoords[currentCoordsId].equals(coordsToStopCalculation)) {
502
+ step.distance += itineraryCoords[currentCoordsId].distanceTo(itineraryCoords[currentCoordsId + 1]);
503
+ currentCoordsId++;
504
+ }
505
+ if (currentCoordsId === itineraryCoords.length - 1) {
506
+ step.distance += itineraryCoords[currentCoordsId].distanceTo(this.to);
507
+ }
508
+ step.number = stepId + 1;
509
+ step.firstStep = stepId === 0;
510
+ step.lastStep = stepId === steps.length - 1;
511
+ step.duration += getDurationFromLength(step.distance - stepDistanceBefore);
512
+ });
513
+ }
499
514
  }
500
515
  class RouterResponse {
501
516
  constructor({
@@ -558,71 +573,267 @@ class RouterResponse {
558
573
  }
559
574
  }
560
575
  }
561
- const _WemapOsmRouterOptions = class extends osm.OsmGraphRouterOptions {
562
- constructor() {
563
- super(...arguments);
564
- __publicField(this, "weightEdgeFn", (edge) => edge.builtFrom instanceof osm.OsmNode && edge.builtFrom.isElevator ? 30 : getDurationFromLength(edge.length));
565
- }
566
- static get WITHOUT_STAIRS() {
567
- const options = new _WemapOsmRouterOptions();
568
- options.acceptEdgeFn = (edge) => {
569
- var _a;
570
- return ((_a = edge.builtFrom) == null ? void 0 : _a.tags.highway) !== "steps";
576
+ const HIGHWAYS_PEDESTRIANS = ["footway", "steps", "pedestrian", "living_street", "path", "track", "sidewalk", "elevator"];
577
+ const DEFAULT_WAY_SELECTOR = (way) => {
578
+ const isElevatorArea = way.tags.highway === "elevator" && way.isArea;
579
+ return HIGHWAYS_PEDESTRIANS.includes(way.tags.highway) && !isElevatorArea && !["no", "private"].includes(way.tags.access) || way.tags.footway === "sidewalk" || way.tags.public_transport === "platform" || way.tags.railway === "platform";
580
+ };
581
+ const _OsmGraph = class extends geo.GeoGraph {
582
+ getVertexByCoords(coords) {
583
+ return geo.GeoGraph.getVertexByCoords(this.vertices, coords);
584
+ }
585
+ getVertexByName(name) {
586
+ return super.getVertexByName(name);
587
+ }
588
+ getEdgeByName(name) {
589
+ return super.getEdgeByName(name);
590
+ }
591
+ static fromOsmModel(osmModel, waySelectionFilter = DEFAULT_WAY_SELECTOR) {
592
+ const nodes = [];
593
+ const edges = [];
594
+ const nodesCreated = {};
595
+ const elevatorNodes = [];
596
+ const getOrCreateNode = (osmNode) => {
597
+ let node = nodesCreated[osmNode.id];
598
+ if (!node) {
599
+ node = new geo.GeoGraphVertex(osmNode.coords, { data: osmNode, name: osmNode.tags.name });
600
+ nodesCreated[osmNode.id] = node;
601
+ nodes.push(node);
602
+ if (osmNode.tags.highway === "elevator") {
603
+ elevatorNodes.push(node);
604
+ }
605
+ }
606
+ return node;
607
+ };
608
+ osmModel.ways.forEach((way) => {
609
+ if (!waySelectionFilter(way)) {
610
+ return;
611
+ }
612
+ let firstNode = getOrCreateNode(way.nodes[0]);
613
+ for (let i = 1; i < way.nodes.length; i++) {
614
+ const secondNode = getOrCreateNode(way.nodes[i]);
615
+ const edge = new geo.GeoGraphEdge(
616
+ firstNode,
617
+ secondNode,
618
+ { data: way, name: way.tags.name, level: way.level }
619
+ );
620
+ _OsmGraph.manageOneWay(edge, way);
621
+ edges.push(edge);
622
+ firstNode = secondNode;
623
+ }
624
+ });
625
+ osmModel.ways.filter((way) => way.isElevator).forEach((way) => {
626
+ way.nodes.forEach((node) => {
627
+ const connectedWays = node.ways.filter((otherWay) => otherWay != way);
628
+ if (connectedWays.length) {
629
+ const graphVertex = getOrCreateNode(node);
630
+ graphVertex.data.tags.highway = "elevator";
631
+ elevatorNodes.push(graphVertex);
632
+ }
633
+ });
634
+ });
635
+ elevatorNodes.forEach((node) => {
636
+ _OsmGraph.createNodesAndEdgesFromElevator(nodes, edges, node);
637
+ });
638
+ return new _OsmGraph(nodes, edges, true);
639
+ }
640
+ static manageOneWay(edge, way) {
641
+ const { highway, oneway, conveying } = way.tags;
642
+ edge.isOneway = Boolean(oneway === "yes" || oneway === "true" || oneway === "1" || conveying && highway && ["forward", "backward"].includes(conveying));
643
+ if (edge.isOneway && conveying === "backward") {
644
+ const tmpNode = edge.vertex1;
645
+ edge.vertex1 = edge.vertex2;
646
+ edge.vertex2 = tmpNode;
647
+ }
648
+ }
649
+ static createNodesAndEdgesFromElevator(nodes, edges, elevatorNode) {
650
+ const createdNodes = [];
651
+ const getOrCreateLevelVertex = (level) => {
652
+ let levelVertex = createdNodes.find(({ coords }) => geo.Level.equals(level, coords.level));
653
+ if (!levelVertex) {
654
+ levelVertex = new geo.GeoGraphVertex(elevatorNode.coords.clone(), {
655
+ data: elevatorNode.data,
656
+ name: `${elevatorNode.name} (elevator lvl: ${level})`
657
+ });
658
+ levelVertex.coords.level = level;
659
+ createdNodes.push(levelVertex);
660
+ nodes.push(levelVertex);
661
+ }
662
+ return levelVertex;
571
663
  };
572
- return options;
664
+ elevatorNode.edges.forEach((edge) => {
665
+ if (geo.Level.isRange(edge.level)) {
666
+ throw new Error("Cannot handle this elevator edge due to ambiguity");
667
+ }
668
+ const levelVertex = getOrCreateLevelVertex(edge.level);
669
+ if (edge.vertex1 === elevatorNode) {
670
+ edge.vertex1 = levelVertex;
671
+ } else {
672
+ edge.vertex2 = levelVertex;
673
+ }
674
+ levelVertex.edges.push(edge);
675
+ });
676
+ for (let i = 0; i < createdNodes.length; i++) {
677
+ for (let j = i + 1; j < createdNodes.length; j++) {
678
+ const createdNode1 = createdNodes[i];
679
+ const createdNode2 = createdNodes[j];
680
+ if (createdNode1.coords.level === null || createdNode2.coords.level === null) {
681
+ continue;
682
+ }
683
+ const minLevel = Math.min(createdNode1.coords.level, createdNode2.coords.level);
684
+ const maxLevel = Math.max(createdNode1.coords.level, createdNode2.coords.level);
685
+ const newEdge = new geo.GeoGraphEdge(
686
+ createdNode1,
687
+ createdNode2,
688
+ { data: elevatorNode.data, name: elevatorNode.name, level: [minLevel, maxLevel] }
689
+ );
690
+ edges.push(newEdge);
691
+ }
692
+ }
693
+ const elevatorNodeIndex = nodes.indexOf(elevatorNode);
694
+ if (elevatorNodeIndex > -1) {
695
+ nodes.splice(elevatorNodeIndex, 1);
696
+ }
573
697
  }
574
698
  };
575
- let WemapOsmRouterOptions = _WemapOsmRouterOptions;
576
- __publicField(WemapOsmRouterOptions, "DEFAULT", new _WemapOsmRouterOptions());
577
- const buildStepsRules = (graphItinerary) => (currentCoords, nextCoords) => {
578
- var _a, _b, _c, _d, _e, _f;
699
+ let OsmGraph = _OsmGraph;
700
+ __publicField(OsmGraph, "HIGHWAYS_PEDESTRIANS", HIGHWAYS_PEDESTRIANS);
701
+ __publicField(OsmGraph, "DEFAULT_WAY_SELECTOR", DEFAULT_WAY_SELECTOR);
702
+ const DEFAULT_OPTIONS = Object.assign({}, geo.GeoGraphRouter.DEFAULT_OPTIONS, {
703
+ weightEdgeFn: (edge) => edge.data instanceof osm.OsmNode && edge.data.isElevator ? 90 : getDurationFromLength(edge.length)
704
+ });
705
+ const WITHOUT_STAIRS_OPTIONS = Object.assign({}, DEFAULT_OPTIONS, {
706
+ acceptEdgeFn: (edge) => edge.data.tags.highway !== "steps"
707
+ });
708
+ const buildStepsRules = (graphItinerary) => (currentCoords, nextCoords, previousStep) => {
709
+ var _a, _b, _c, _d, _e;
579
710
  const edges = graphItinerary.edges;
580
- const nodes = graphItinerary.nodes;
581
- const node = geo.GraphUtils.getNodeByCoords(nodes, currentCoords);
582
- const nextNode = geo.GraphUtils.getNodeByCoords(nodes, nextCoords);
583
- if (!node || !nextNode)
711
+ const vertices = graphItinerary.vertices;
712
+ const vertex = geo.GeoGraph.getVertexByCoords(vertices, currentCoords);
713
+ const nextVertex = geo.GeoGraph.getVertexByCoords(vertices, nextCoords);
714
+ if (!vertex || !nextVertex)
584
715
  return {};
585
- const edge = geo.GraphUtils.getEdgeByNodes(edges, node, nextNode);
716
+ const edge = geo.GeoGraphEdge.getEdgeByVertices(edges, vertex, nextVertex);
586
717
  if (!edge)
587
718
  return {};
588
719
  const edgeId = edges.findIndex((_edge) => _edge === edge);
589
- const isSubwayEntrance = node ? ((_a = node.builtFrom) == null ? void 0 : _a.tags.railway) === "subway_entrance" : false;
590
- const isGate = node ? ((_b = node.builtFrom) == null ? void 0 : _b.tags.barrier) === "gate" || ((_c = node.builtFrom) == null ? void 0 : _c.tags.aeroway) === "gate" : false;
720
+ const isSubwayEntrance = vertex ? ((_a = vertex.data) == null ? void 0 : _a.tags.railway) === "subway_entrance" : false;
721
+ const isGate = vertex ? ((_b = vertex.data) == null ? void 0 : _b.tags.barrier) === "gate" || ((_c = vertex.data) == null ? void 0 : _c.tags.aeroway) === "gate" : false;
591
722
  let levelChangeType = null;
592
- if ((_d = edge.builtFrom) == null ? void 0 : _d.isElevator) {
723
+ if (edge.data.isElevator) {
593
724
  levelChangeType = "elevator";
594
- } else if (edge.builtFrom instanceof osm.OsmNode || edge.builtFrom instanceof osm.OsmWay && edge.builtFrom.isConveying) {
725
+ } else if (edge.data.isConveying) {
595
726
  levelChangeType = "conveyor";
596
- } else if (edge.builtFrom instanceof osm.OsmWay && edge.builtFrom.areStairs) {
727
+ } else if (edge.data instanceof osm.OsmWay && edge.data.areStairs) {
597
728
  levelChangeType = "stairs";
598
729
  }
730
+ const edgeTags = edge.data.tags || {};
731
+ let levelChangeDirection = null;
732
+ if (edge.data instanceof osm.OsmWay && edge.data.areStairs && ["up", "down"].includes(edgeTags.incline) && !(previousStep == null ? void 0 : previousStep.levelChange)) {
733
+ levelChangeDirection = edgeTags.incline;
734
+ for (const n of edge.data.nodes) {
735
+ if (n !== vertex.data)
736
+ continue;
737
+ }
738
+ const isReversed = edge.data.nodes.reduce((acc, n, idx, arr) => {
739
+ if (n !== vertex.data)
740
+ return acc;
741
+ acc = !(idx + 1 < arr.length && arr[idx + 1] === nextVertex.data);
742
+ return acc;
743
+ }, null);
744
+ if (isReversed) {
745
+ levelChangeDirection = levelChangeDirection === "up" ? "down" : "up";
746
+ }
747
+ }
748
+ const createNewStep = isSubwayEntrance || levelChangeDirection;
599
749
  return {
600
- createNewStep: isSubwayEntrance,
601
- stepName: (_e = edge.builtFrom) == null ? void 0 : _e.tags.name,
750
+ createNewStep,
751
+ stepName: (_d = edge.data) == null ? void 0 : _d.tags.name,
602
752
  duration: graphItinerary.edgesWeights[edgeId],
603
753
  stepExtras: {
604
754
  ...isSubwayEntrance && { isSubwayEntrance: true },
605
- ...isSubwayEntrance && ((_f = node.builtFrom) == null ? void 0 : _f.tags.ref) && { subwayEntranceRef: node.builtFrom.tags.ref },
755
+ ...isSubwayEntrance && ((_e = vertex.data) == null ? void 0 : _e.tags.ref) && { subwayEntranceRef: vertex.data.tags.ref },
606
756
  ...isGate && { isGate: true }
607
757
  },
608
- ...levelChangeType && { levelChangeType }
758
+ ...levelChangeType && { levelChangeType },
759
+ ...levelChangeDirection && { levelChangeDirection }
609
760
  };
610
761
  };
611
- class WemapOsmRouter extends osm.OsmGraphRouter {
612
- constructor(network) {
613
- super(network);
762
+ class WemapOsmRouter extends geo.GeoGraphRouter {
763
+ constructor(graph) {
764
+ super(graph);
614
765
  }
615
766
  static get rname() {
616
- return "wemap";
767
+ return "wemap-osm";
617
768
  }
618
- getShortestPath(start, end, options = new WemapOsmRouterOptions()) {
769
+ getShortestPath(start, end, options = DEFAULT_OPTIONS) {
619
770
  return super.getShortestPath(start, end, options);
620
771
  }
621
- getItinerary(start, end, options = new WemapOsmRouterOptions()) {
772
+ getItinerary(start, end, options = DEFAULT_OPTIONS) {
622
773
  const graphItinerary = this.getShortestPath(start, end, options);
623
774
  return Itinerary.fromGraphItinerary(graphItinerary, "WALK", buildStepsRules(graphItinerary));
624
775
  }
776
+ static getTurnInfoFromAngle(_angle) {
777
+ let direction, directionExtra;
778
+ const directionAngle = maths.rad2deg(maths.diffAngle(_angle, Math.PI));
779
+ const directionAngleAbs = Math.abs(directionAngle);
780
+ if (directionAngleAbs <= 20) {
781
+ direction = "straight";
782
+ } else {
783
+ direction = directionAngle > 0 ? "left" : "right";
784
+ if (directionAngleAbs < 55) {
785
+ directionExtra = "slight";
786
+ } else if (directionAngleAbs > 120) {
787
+ directionExtra = "sharp";
788
+ }
789
+ }
790
+ return { direction, directionExtra };
791
+ }
792
+ getShortestTrip(waypoints, options = DEFAULT_OPTIONS) {
793
+ const points = waypoints.map((waypoint) => {
794
+ const point = new salesman__default.default.Point(0, 0);
795
+ point.coords = waypoint;
796
+ return point;
797
+ });
798
+ const cache = [];
799
+ const solution = salesman__default.default.solve(points, 0.9, void 0, (p, q) => {
800
+ const osmItinerary = this.getShortestPath(
801
+ p.coords,
802
+ q.coords,
803
+ options
804
+ );
805
+ cache.push(osmItinerary);
806
+ return osmItinerary.edgesWeights.reduce((acc, weight) => acc + weight, 0);
807
+ });
808
+ const orderedPoints = solution.map((i) => points[i]);
809
+ const orderedItineraries = [];
810
+ for (let i = 0; i < orderedPoints.length - 1; i++) {
811
+ const p = orderedPoints[i];
812
+ const q = orderedPoints[i + 1];
813
+ let cachedItinerary = cache.find((itinerary) => itinerary.start === p.coords && itinerary.end === q.coords || itinerary.end === p.coords && itinerary.start === q.coords);
814
+ if (cachedItinerary.end === p.coords) {
815
+ cachedItinerary = geo.GeoGraphItinerary.fromGraphVertices(
816
+ cachedItinerary.end,
817
+ cachedItinerary.start,
818
+ cachedItinerary.vertices.reverse(),
819
+ cachedItinerary.edgesWeights
820
+ );
821
+ }
822
+ orderedItineraries.push(cachedItinerary);
823
+ }
824
+ return orderedItineraries;
825
+ }
826
+ getTripItinerary(waypoints, options = DEFAULT_OPTIONS) {
827
+ const shortestTrip = this.getShortestTrip(waypoints, options);
828
+ return new Itinerary({
829
+ from: shortestTrip[0].start,
830
+ to: shortestTrip[shortestTrip.length - 1].end,
831
+ legs: shortestTrip.map((graphItinerary) => Leg.fromGraphItinerary(graphItinerary))
832
+ });
833
+ }
625
834
  }
835
+ __publicField(WemapOsmRouter, "DEFAULT_OPTIONS", DEFAULT_OPTIONS);
836
+ __publicField(WemapOsmRouter, "WITHOUT_STAIRS_OPTIONS", WITHOUT_STAIRS_OPTIONS);
626
837
  class RemoteRouter {
627
838
  }
628
839
  class RemoteRouterServerUnreachable extends Error {
@@ -774,7 +985,7 @@ class CitywayRemoteRouter extends RemoteRouter {
774
985
  const legCoords = [];
775
986
  let legFrom, legTo;
776
987
  let transportInfo;
777
- let stepsInfo;
988
+ let minStepsInfo;
778
989
  if (legMode === "UNKNOWN") {
779
990
  continue itineraryLoop;
780
991
  }
@@ -787,7 +998,7 @@ class CitywayRemoteRouter extends RemoteRouter {
787
998
  name: jsonLeg.Arrival.Site.Name,
788
999
  coords: jsonToCoordinates$2(jsonLeg.Arrival.Site.Position)
789
1000
  };
790
- stepsInfo = [];
1001
+ minStepsInfo = [];
791
1002
  for (const jsonPathLink of jsonLeg.pathLinks.PathLink) {
792
1003
  let stepCoords;
793
1004
  if (jsonPathLink.Geometry && jsonPathLink.Geometry !== "Null") {
@@ -800,11 +1011,16 @@ class CitywayRemoteRouter extends RemoteRouter {
800
1011
  legCoords.push(coords);
801
1012
  }
802
1013
  });
803
- stepsInfo.push(new StepInfo({
1014
+ minStepsInfo.push({
804
1015
  coords: stepCoords[0],
805
1016
  distance: jsonPathLink.Distance,
806
1017
  name: jsonPathLink.Departure.Site.Name
807
- }));
1018
+ });
1019
+ }
1020
+ if (jsonSection === trip.sections.Section[trip.sections.Section.length - 1]) {
1021
+ minStepsInfo.push({
1022
+ coords: legCoords[legCoords.length - 1]
1023
+ });
808
1024
  }
809
1025
  } else if (isRoutingModePublicTransport(legMode)) {
810
1026
  legFrom = {
@@ -833,11 +1049,11 @@ class CitywayRemoteRouter extends RemoteRouter {
833
1049
  }
834
1050
  });
835
1051
  }
836
- stepsInfo = [new StepInfo({
1052
+ minStepsInfo = [{
837
1053
  coords: legCoords[0],
838
1054
  name: jsonLeg.Line.Name,
839
1055
  distance: jsonLeg.Distance
840
- })];
1056
+ }];
841
1057
  } else {
842
1058
  Logger__default.default.warn(`[CitywayParser] Unknown leg mode: ${jsonLeg.TransportMode}`);
843
1059
  continue;
@@ -851,7 +1067,7 @@ class CitywayRemoteRouter extends RemoteRouter {
851
1067
  from: legFrom,
852
1068
  to: legTo,
853
1069
  transportInfo,
854
- stepsInfo
1070
+ minStepsInfo
855
1071
  });
856
1072
  legs.push(leg);
857
1073
  }
@@ -1093,16 +1309,15 @@ class IdfmRemoteRouter extends RemoteRouter {
1093
1309
  newCoords = last(result);
1094
1310
  coords[_idCoordsInLeg] = newCoords;
1095
1311
  }
1096
- outputSteps.push(new StepInfo({
1312
+ outputSteps.push({
1097
1313
  ...step,
1098
1314
  coords: newCoords
1099
- }));
1315
+ });
1100
1316
  previousStep = step;
1101
1317
  }
1102
1318
  return outputSteps;
1103
1319
  }
1104
1320
  createRouterResponseFromJson(json, from, to) {
1105
- var _a;
1106
1321
  const routerResponse = new RouterResponse({ routerName: this.rname, from, to });
1107
1322
  if (!json || !json.journeys) {
1108
1323
  return routerResponse;
@@ -1123,7 +1338,9 @@ class IdfmRemoteRouter extends RemoteRouter {
1123
1338
  }
1124
1339
  return acc;
1125
1340
  }, []);
1126
- let stepsInfo;
1341
+ let minStepsInfo;
1342
+ let transportInfo;
1343
+ let mode = routingModeCorrespondance.get(jsonSection.mode);
1127
1344
  if (jsonSection.path) {
1128
1345
  const idfmIntermediateSteps = [];
1129
1346
  for (const jsonPathLink of jsonSection.path) {
@@ -1132,10 +1349,25 @@ class IdfmRemoteRouter extends RemoteRouter {
1132
1349
  distance: jsonPathLink.length
1133
1350
  });
1134
1351
  }
1135
- stepsInfo = this.findStepsCoord(legCoords, idfmIntermediateSteps);
1352
+ minStepsInfo = this.findStepsCoord(legCoords, idfmIntermediateSteps);
1353
+ }
1354
+ if (jsonSection.type === "public_transport") {
1355
+ transportInfo = {
1356
+ name: jsonSection.display_informations.code,
1357
+ routeColor: jsonSection.display_informations.color,
1358
+ routeTextColor: jsonSection.display_informations.text_color,
1359
+ directionName: jsonSection.display_informations.direction
1360
+ };
1361
+ mode = routingModeCorrespondance.get(jsonSection.display_informations.physical_mode);
1362
+ const legStep = {
1363
+ coords: legCoords[0],
1364
+ name: transportInfo.directionName,
1365
+ distance: jsonSection.geojson.properties[0].length
1366
+ };
1367
+ minStepsInfo = [legStep];
1136
1368
  }
1137
1369
  const leg = new Leg({
1138
- mode: routingModeCorrespondance.get(jsonSection.mode),
1370
+ mode,
1139
1371
  duration: jsonSection.duration,
1140
1372
  startTime: dateStringToTimestamp(jsonSection.departure_date_time, timeZone),
1141
1373
  endTime: dateStringToTimestamp(jsonSection.arrival_date_time, timeZone),
@@ -1148,23 +1380,9 @@ class IdfmRemoteRouter extends RemoteRouter {
1148
1380
  coords: toSection
1149
1381
  },
1150
1382
  coords: legCoords,
1151
- stepsInfo
1383
+ transportInfo,
1384
+ minStepsInfo
1152
1385
  });
1153
- if (jsonSection.type === "public_transport") {
1154
- leg.transportInfo = {
1155
- name: jsonSection.display_informations.code,
1156
- routeColor: jsonSection.display_informations.color,
1157
- routeTextColor: jsonSection.display_informations.text_color,
1158
- directionName: jsonSection.display_informations.direction
1159
- };
1160
- leg.mode = routingModeCorrespondance.get(jsonSection.display_informations.physical_mode);
1161
- const legStep = new StepInfo({
1162
- coords: leg.coords[0],
1163
- name: (_a = leg.transportInfo) == null ? void 0 : _a.directionName,
1164
- distance: jsonSection.geojson.properties[0].length
1165
- });
1166
- leg.stepsInfo = [legStep];
1167
- }
1168
1386
  legs.push(leg);
1169
1387
  }
1170
1388
  const itinerary = new Itinerary({
@@ -1329,19 +1547,19 @@ class OsrmRemoteRouter extends RemoteRouter {
1329
1547
  const legs = jsonItinerary.legs.map((jsonLeg) => {
1330
1548
  var _a;
1331
1549
  const legCoords = jsonLeg.steps.map((step) => step.geometry.coordinates.map(this.jsonToCoordinates)).flat().filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));
1332
- const stepsInfo = (_a = jsonLeg.steps) == null ? void 0 : _a.map(({ maneuver, name, distance, duration }) => {
1550
+ const minStepsInfo = (_a = jsonLeg.steps) == null ? void 0 : _a.map(({ maneuver, name, distance, duration }) => {
1333
1551
  const stepCoords = this.jsonToCoordinates(maneuver.location);
1334
1552
  const distances = legCoords.map((coords) => coords.distanceTo(stepCoords));
1335
1553
  const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));
1336
1554
  if (idStepCoordsInLeg < 0) {
1337
1555
  throw new Error("Osrm Parser: Cannot find step coords in leg coordinates");
1338
1556
  }
1339
- return new StepInfo({
1557
+ return {
1340
1558
  coords: stepCoords,
1341
1559
  name,
1342
1560
  distance,
1343
1561
  duration
1344
- });
1562
+ };
1345
1563
  });
1346
1564
  return new Leg({
1347
1565
  mode,
@@ -1353,7 +1571,7 @@ class OsrmRemoteRouter extends RemoteRouter {
1353
1571
  to: {
1354
1572
  coords: legCoords[legCoords.length - 1]
1355
1573
  },
1356
- stepsInfo
1574
+ minStepsInfo
1357
1575
  });
1358
1576
  });
1359
1577
  return new Itinerary({
@@ -1422,7 +1640,7 @@ class OtpRemoteRouter extends RemoteRouter {
1422
1640
  for (const jsonLeg of jsonItinerary.legs) {
1423
1641
  const legCoords = Polyline__default.default.decode(jsonLeg.legGeometry.points).map(([lat, lon]) => new geo.Coordinates(lat, lon));
1424
1642
  let transportInfo;
1425
- let stepsInfo;
1643
+ let minStepsInfo;
1426
1644
  if (isLegPT(jsonLeg)) {
1427
1645
  transportInfo = {
1428
1646
  name: jsonLeg.routeShortName,
@@ -1430,21 +1648,21 @@ class OtpRemoteRouter extends RemoteRouter {
1430
1648
  routeTextColor: jsonLeg.routeTextColor,
1431
1649
  directionName: jsonLeg.headsign
1432
1650
  };
1433
- stepsInfo = [new StepInfo({
1651
+ minStepsInfo = [{
1434
1652
  coords: legCoords[0],
1435
1653
  name: jsonLeg.headsign
1436
- })];
1654
+ }];
1437
1655
  } else {
1438
- stepsInfo = jsonLeg.steps.map((jsonStep) => {
1656
+ minStepsInfo = jsonLeg.steps.map((jsonStep) => {
1439
1657
  const distances = legCoords.map((coords) => coords.distanceTo(jsonToCoordinates(jsonStep)));
1440
1658
  const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));
1441
1659
  if (idStepCoordsInLeg < 0) {
1442
1660
  throw new Error("OTP Parser: Cannot find closest step");
1443
1661
  }
1444
- return new StepInfo({
1662
+ return {
1445
1663
  coords: legCoords[idStepCoordsInLeg],
1446
1664
  name: jsonStep.streetName
1447
- });
1665
+ };
1448
1666
  });
1449
1667
  }
1450
1668
  const leg = new Leg({
@@ -1462,7 +1680,7 @@ class OtpRemoteRouter extends RemoteRouter {
1462
1680
  },
1463
1681
  coords: legCoords,
1464
1682
  transportInfo,
1465
- stepsInfo
1683
+ minStepsInfo
1466
1684
  });
1467
1685
  legs.push(leg);
1468
1686
  }
@@ -1503,7 +1721,7 @@ class WemapMultiRemoteRouterPayload {
1503
1721
  }
1504
1722
  class WemapMultiRemoteRouter extends RemoteRouter {
1505
1723
  get rname() {
1506
- return "wemap-meta";
1724
+ return "wemap-multi";
1507
1725
  }
1508
1726
  async getItineraries(endpointUrl, mode, waypoints, options) {
1509
1727
  const payload = new WemapMultiRemoteRouterPayload(
@@ -1528,19 +1746,17 @@ class WemapMultiRemoteRouter extends RemoteRouter {
1528
1746
  }
1529
1747
  }
1530
1748
  const WemapMultiRemoteRouter$1 = new WemapMultiRemoteRouter();
1749
+ const remoteRouters = [
1750
+ CitywayRemoteRouter$1,
1751
+ DeutscheBahnRemoteRouter$1,
1752
+ IdfmRemoteRouter$1,
1753
+ OsrmRemoteRouter$1,
1754
+ OtpRemoteRouter$1,
1755
+ WemapMultiRemoteRouter$1
1756
+ ];
1531
1757
  class RemoteRouterManager {
1532
- constructor() {
1533
- __publicField(this, "remoteRouters", [
1534
- CitywayRemoteRouter$1,
1535
- DeutscheBahnRemoteRouter$1,
1536
- IdfmRemoteRouter$1,
1537
- OsrmRemoteRouter$1,
1538
- OtpRemoteRouter$1,
1539
- WemapMultiRemoteRouter$1
1540
- ]);
1541
- }
1542
1758
  getRouterByName(name) {
1543
- return this.remoteRouters.find((remoteRouter) => remoteRouter.rname === name);
1759
+ return remoteRouters.find((remoteRouter) => remoteRouter.rname === name);
1544
1760
  }
1545
1761
  async getItineraries(name, endpointUrl, mode, waypoints, options) {
1546
1762
  const router = this.getRouterByName(name);
@@ -1549,9 +1765,9 @@ class RemoteRouterManager {
1549
1765
  }
1550
1766
  return router.getItineraries(endpointUrl, mode, waypoints, options);
1551
1767
  }
1552
- async getItinerariesWithFallback(remoteRouters, mode, waypoints, options) {
1768
+ async getItinerariesWithFallback(remoteRouters2, mode, waypoints, options) {
1553
1769
  let routerResponse;
1554
- for (const { name, endpointUrl } of remoteRouters) {
1770
+ for (const { name, endpointUrl } of remoteRouters2) {
1555
1771
  routerResponse = await this.getItineraries(name, endpointUrl, mode, waypoints, options);
1556
1772
  if (routerResponse.itineraries.length) {
1557
1773
  return routerResponse;
@@ -1559,7 +1775,7 @@ class RemoteRouterManager {
1559
1775
  }
1560
1776
  if (!routerResponse) {
1561
1777
  routerResponse = new RouterResponse({
1562
- routerName: remoteRouters.map((rr) => rr.name),
1778
+ routerName: remoteRouters2.map((rr) => rr.name),
1563
1779
  from: waypoints[0],
1564
1780
  to: waypoints[waypoints.length]
1565
1781
  });
@@ -1574,7 +1790,7 @@ class WemapMultiRouter {
1574
1790
  __publicField(this, "maps", []);
1575
1791
  }
1576
1792
  get rname() {
1577
- return "wemap-meta";
1793
+ return "wemap-multi";
1578
1794
  }
1579
1795
  addIOMap(customNetworkMap) {
1580
1796
  this.maps.push(customNetworkMap);
@@ -1582,21 +1798,9 @@ class WemapMultiRouter {
1582
1798
  removeIOMap(customNetworkMap) {
1583
1799
  this.maps = this.maps.filter((map) => map !== customNetworkMap);
1584
1800
  }
1585
- async getItineraries(mode, waypoints, options) {
1586
- var _a;
1587
- if (waypoints.length > 2) {
1588
- Logger__default.default.warn(`WemapMultiRouter uses only the first 2 waypoints (asked ${waypoints.length})`);
1589
- }
1590
- const start = waypoints[0];
1591
- const end = waypoints[1];
1592
- const routerResponse = new RouterResponse({
1593
- routerName: this.rname,
1594
- from: start,
1595
- to: end
1596
- });
1597
- const remoteRouters = ((_a = options.remoteRouters) == null ? void 0 : _a.filter(({ name }) => name !== WemapMultiRemoteRouter$1.rname)) || [];
1801
+ getIoMapsFromOptions(options) {
1598
1802
  let ioMapsToTest = this.maps;
1599
- const { targetMaps } = options;
1803
+ const targetMaps = options == null ? void 0 : options.targetMaps;
1600
1804
  if (targetMaps) {
1601
1805
  ioMapsToTest = this.maps.filter((map) => map.name && targetMaps.includes(map.name));
1602
1806
  if (ioMapsToTest.length !== targetMaps.length) {
@@ -1607,9 +1811,55 @@ class WemapMultiRouter {
1607
1811
  });
1608
1812
  }
1609
1813
  }
1814
+ return ioMapsToTest;
1815
+ }
1816
+ convertOptionsToWemapOsmOptions(options) {
1817
+ return !options || !("useStairs" in options) || options.useStairs ? WemapOsmRouter.DEFAULT_OPTIONS : WemapOsmRouter.WITHOUT_STAIRS_OPTIONS;
1818
+ }
1819
+ async getTrip(mode, waypoints, options = null) {
1820
+ const ioMapsToTest = this.getIoMapsFromOptions(options);
1821
+ if (waypoints.length < 2) {
1822
+ throw Error(`Cannot retrieve a trip itinerary. Two points or more are necessary`);
1823
+ }
1824
+ if (mode !== "WALK") {
1825
+ throw Error(`Cannot calculate trip itinerary for mode "${mode}". Only "WALK" is implemented.`);
1826
+ }
1827
+ const mapOfWaypoints = waypoints.reduce((map, waypoint) => {
1828
+ const mapOfThisWaypoint = ioMapsToTest.find((map2) => map2.isPointInside(waypoint));
1829
+ if (!mapOfThisWaypoint) {
1830
+ throw Error(`Cannot find a network for this trip waypoint (${waypoint.toString()}). Outdoor trips are not implemented.`);
1831
+ }
1832
+ if (map && mapOfThisWaypoint !== map) {
1833
+ throw Error(`Cannot handle this trip, because two waypoints are on different maps (${mapOfThisWaypoint} and ${mapOfWaypoints}). Multi-map trips are not implemented.`);
1834
+ }
1835
+ return mapOfThisWaypoint;
1836
+ }, null);
1837
+ const wemapOsmRouterOptions = this.convertOptionsToWemapOsmOptions(options);
1838
+ const tripItinerary = mapOfWaypoints.getTripInsideMap(waypoints, wemapOsmRouterOptions);
1839
+ return new RouterResponse({
1840
+ routerName: this.rname,
1841
+ from: tripItinerary.from,
1842
+ to: tripItinerary.to,
1843
+ itineraries: [tripItinerary]
1844
+ });
1845
+ }
1846
+ async getItineraries(mode, waypoints, options = null) {
1847
+ var _a;
1848
+ if (waypoints.length > 2) {
1849
+ Logger__default.default.warn(`WemapMultiRouter uses only the first 2 waypoints (asked ${waypoints.length})`);
1850
+ }
1851
+ const start = waypoints[0];
1852
+ const end = waypoints[1];
1853
+ const routerResponse = new RouterResponse({
1854
+ routerName: this.rname,
1855
+ from: start,
1856
+ to: end
1857
+ });
1858
+ const remoteRouters2 = ((_a = options == null ? void 0 : options.remoteRouters) == null ? void 0 : _a.filter(({ name }) => name !== WemapMultiRemoteRouter$1.rname)) || [];
1859
+ const ioMapsToTest = this.getIoMapsFromOptions(options);
1610
1860
  if (!ioMapsToTest.length) {
1611
1861
  try {
1612
- return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters, mode, waypoints);
1862
+ return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters2, mode, waypoints);
1613
1863
  } catch (e) {
1614
1864
  if (!isRoutingError(e)) {
1615
1865
  throw e;
@@ -1620,7 +1870,7 @@ class WemapMultiRouter {
1620
1870
  }
1621
1871
  let ioMapItinerary;
1622
1872
  const mapWithStart = ioMapsToTest.find((map) => map.isPointInside(start));
1623
- const wemapOsmRouterOptions = !("useStairs" in options) && options.useStairs ? WemapOsmRouterOptions.DEFAULT : WemapOsmRouterOptions.WITHOUT_STAIRS;
1873
+ const wemapOsmRouterOptions = this.convertOptionsToWemapOsmOptions(options);
1624
1874
  if (mapWithStart && mapWithStart.isPointInside(end)) {
1625
1875
  try {
1626
1876
  ioMapItinerary = mapWithStart.getItineraryInsideMap(start, end, wemapOsmRouterOptions);
@@ -1639,7 +1889,7 @@ class WemapMultiRouter {
1639
1889
  let remoteRouterResponse;
1640
1890
  if (!mapWithStart && !mapWithEnd) {
1641
1891
  try {
1642
- return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters, mode, waypoints);
1892
+ return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters2, mode, waypoints);
1643
1893
  } catch (e) {
1644
1894
  if (!isRoutingError(e)) {
1645
1895
  throw e;
@@ -1657,7 +1907,7 @@ class WemapMultiRouter {
1657
1907
  try {
1658
1908
  ioMapItinerary = mapWithStart.getBestItineraryFromStartToEntryPoints(start, end, wemapOsmRouterOptions);
1659
1909
  remoteRouterResponse = await RemoteRouterManager$1.getItinerariesWithFallback(
1660
- remoteRouters,
1910
+ remoteRouters2,
1661
1911
  mode,
1662
1912
  [ioMapItinerary.to, end]
1663
1913
  );
@@ -1668,7 +1918,7 @@ class WemapMultiRouter {
1668
1918
  if (!isRoutingError(e)) {
1669
1919
  throw e;
1670
1920
  }
1671
- routerResponse.error = `Tried to calculate an itinerary from "start" to "entrypoints" using wemap router on local map "${mapWithStart.name}" and an itinerary from "entrypoints" to "end" using remote routers (${remoteRouters.map((r) => r.name).join(", ")}), but failed. Details: ${e.message}.`;
1921
+ routerResponse.error = `Tried to calculate an itinerary from "start" to "entrypoints" using wemap router on local map "${mapWithStart.name}" and an itinerary from "entrypoints" to "end" using remote routers (${remoteRouters2.map((r) => r.name).join(", ")}), but failed. Details: ${e.message}.`;
1672
1922
  return routerResponse;
1673
1923
  }
1674
1924
  routerResponse.itineraries = remoteRouterResponse.itineraries.map(
@@ -1686,7 +1936,7 @@ class WemapMultiRouter {
1686
1936
  try {
1687
1937
  ioMapItinerary = mapWithEnd.getBestItineraryFromEntryPointsToEnd(start, end, wemapOsmRouterOptions);
1688
1938
  remoteRouterResponse = await RemoteRouterManager$1.getItinerariesWithFallback(
1689
- remoteRouters,
1939
+ remoteRouters2,
1690
1940
  mode,
1691
1941
  [start, ioMapItinerary.from]
1692
1942
  );
@@ -1697,7 +1947,7 @@ class WemapMultiRouter {
1697
1947
  if (!isRoutingError(e)) {
1698
1948
  throw e;
1699
1949
  }
1700
- routerResponse.error = `Tried to calculate an itinerary from "start" to "entrypoints" using remote routers (${remoteRouters.map((r) => r.name).join(", ")}) and an itinerary from "entrypoints" to "end" using wemap router on local map "${mapWithEnd.name}", but failed. Details: ${e.message}.`;
1950
+ routerResponse.error = `Tried to calculate an itinerary from "start" to "entrypoints" using remote routers (${remoteRouters2.map((r) => r.name).join(", ")}) and an itinerary from "entrypoints" to "end" using wemap router on local map "${mapWithEnd.name}", but failed. Details: ${e.message}.`;
1701
1951
  return routerResponse;
1702
1952
  }
1703
1953
  routerResponse.itineraries = remoteRouterResponse.itineraries.map(
@@ -1724,7 +1974,7 @@ class WemapMultiRouter {
1724
1974
  ioMapItinerary1 = mapWithStart.getBestItineraryFromStartToEntryPoints(start, end, wemapOsmRouterOptions);
1725
1975
  ioMapItinerary2 = mapWithEnd.getBestItineraryFromEntryPointsToEnd(start, end, wemapOsmRouterOptions);
1726
1976
  remoteRouterResponse = await RemoteRouterManager$1.getItinerariesWithFallback(
1727
- remoteRouters,
1977
+ remoteRouters2,
1728
1978
  mode,
1729
1979
  [ioMapItinerary1.to, ioMapItinerary2.from]
1730
1980
  );
@@ -1735,7 +1985,7 @@ class WemapMultiRouter {
1735
1985
  if (!isRoutingError(e)) {
1736
1986
  throw e;
1737
1987
  }
1738
- routerResponse.error = `Tried to calculate an itinerary from "start" to "entrypoints1" using wemap router on local map "${mapWithStart.name}", an itinerary from "entrypoints1" to "entrypoints2" using remote routers (${remoteRouters.map((r) => r.name).join(", ")}) and an itinerary from "entrypoints2" to "end" using wemap router on local map "${mapWithEnd.name}", but failed. Details: ${e.message}.`;
1988
+ routerResponse.error = `Tried to calculate an itinerary from "start" to "entrypoints1" using wemap router on local map "${mapWithStart.name}", an itinerary from "entrypoints1" to "entrypoints2" using remote routers (${remoteRouters2.map((r) => r.name).join(", ")}) and an itinerary from "entrypoints2" to "end" using wemap router on local map "${mapWithEnd.name}", but failed. Details: ${e.message}.`;
1739
1989
  return routerResponse;
1740
1990
  }
1741
1991
  routerResponse.itineraries = remoteRouterResponse.itineraries.map(
@@ -1752,46 +2002,63 @@ class WemapMultiRouter {
1752
2002
  }
1753
2003
  }
1754
2004
  class CustomNetworkMap {
1755
- constructor(network, entryPoints, bounds = null, name = null) {
2005
+ constructor(graph, entryPoints, bounds = null, name = null) {
1756
2006
  __publicField(this, "name");
1757
- __publicField(this, "network");
2007
+ __publicField(this, "graph");
1758
2008
  __publicField(this, "router");
1759
2009
  __publicField(this, "bounds");
1760
2010
  __publicField(this, "entryPoints");
1761
2011
  __publicField(this, "disabledWays", /* @__PURE__ */ new Set());
1762
2012
  this.name = name;
1763
- this.network = network;
1764
- this.router = new WemapOsmRouter(network);
2013
+ this.graph = graph;
2014
+ this.router = new WemapOsmRouter(graph);
1765
2015
  entryPoints.forEach((entryPoint) => {
1766
- if (!network.nodes.includes(entryPoint)) {
2016
+ if (!graph.vertices.includes(entryPoint)) {
1767
2017
  throw new Error(`Cannot find entry point ${entryPoint.coords.toString()} in network "${name}"`);
1768
2018
  }
1769
2019
  });
1770
2020
  this.entryPoints = entryPoints;
1771
2021
  if (bounds) {
1772
- this.bounds = helpers.polygon([bounds.map((coords) => [coords.lng, coords.lat])]);
2022
+ this.bounds = bounds;
1773
2023
  } else {
1774
- const polygon = [network.nodes.map((node) => [node.coords.lng, node.coords.lat])];
2024
+ const polygon = [graph.vertices.map((vertex) => [vertex.coords.lng, vertex.coords.lat])];
1775
2025
  const convexHull = convexHullFn__default.default({ type: "polygon", coordinates: polygon });
1776
2026
  if (!convexHull) {
1777
2027
  throw new Error(`Cannot calculate convexHull of network "${name}"`);
1778
2028
  }
1779
- this.bounds = convexHull;
2029
+ this.bounds = {
2030
+ type: "MultiPolygon",
2031
+ coordinates: [convexHull.geometry.coordinates]
2032
+ };
1780
2033
  }
1781
2034
  }
1782
2035
  static fromOsmXml(osmXmlString, name = null) {
1783
2036
  const osmModel = osm.OsmParser.parseOsmXmlString(osmXmlString);
1784
- const network = osm.OsmNetworkUtils.createNetworkFromOsmModel(osmModel);
1785
- const entryPoints = osmModel.nodes.filter(({ tags }) => tags && tags["wemap:routing-io"]).map((osmNode) => network.getNodeByCoords(osmNode.coords));
2037
+ const graph = OsmGraph.fromOsmModel(osmModel);
2038
+ const entryPoints = graph.vertices.filter(({ data: { tags } }) => tags && tags["wemap:routing-io"]);
1786
2039
  if (entryPoints.some((el) => el === null) || new Set(entryPoints).size !== entryPoints.length) {
1787
2040
  throw new Error("Cannot parse wemap:routing-io correctly");
1788
2041
  }
1789
- const wayBounds = osmModel.ways.find(({ tags }) => tags["wemap:routing-bounds"]);
1790
- if (!wayBounds) {
2042
+ const bounds = {
2043
+ type: "MultiPolygon",
2044
+ coordinates: []
2045
+ };
2046
+ osmModel.ways.filter(({ tags }) => tags["wemap:routing-bounds"]).forEach((way) => {
2047
+ bounds.coordinates.push([
2048
+ way.nodes.reduce((acc, node) => {
2049
+ acc.push([node.coords.lng, node.coords.lat]);
2050
+ return acc;
2051
+ }, [])
2052
+ ]);
2053
+ });
2054
+ osmModel.relations.filter((rel) => rel.tags["wemap:routing-bounds"] && rel.isMultipolygon()).forEach((rel) => {
2055
+ const polygon = rel.getGeoJsonPolygon();
2056
+ polygon && bounds.coordinates.push(polygon.coordinates);
2057
+ });
2058
+ if (!bounds.coordinates.length) {
1791
2059
  throw new Error('Search bounds is undefined. Please use OSM tag : "wemap:routing-bounds=yes"');
1792
2060
  }
1793
- const bounds = wayBounds.nodes.map((node) => node.coords);
1794
- return new CustomNetworkMap(network, entryPoints, bounds, name);
2061
+ return new CustomNetworkMap(graph, entryPoints, bounds, name);
1795
2062
  }
1796
2063
  isPointInside(coordinates) {
1797
2064
  return pointInPolygon__default.default([coordinates.lng, coordinates.lat], this.bounds);
@@ -1833,45 +2100,22 @@ class CustomNetworkMap {
1833
2100
  getItineraryInsideMap(start, end, options) {
1834
2101
  return this.router.getItinerary(start, end, options);
1835
2102
  }
2103
+ getTripInsideMap(waypoints, options) {
2104
+ return this.router.getTripItinerary(waypoints, options);
2105
+ }
1836
2106
  enableWay(osmId) {
1837
- this.network.edges.filter((edge) => {
1838
- var _a;
1839
- return ((_a = edge.builtFrom) == null ? void 0 : _a.id) === osmId;
1840
- }).forEach((e) => this.router.disabledEdges.delete(e));
2107
+ this.graph.edges.filter((edge) => edge.data.id === osmId).forEach((e) => this.router.disabledEdges.delete(e));
1841
2108
  this.disabledWays.delete(osmId);
1842
2109
  }
1843
2110
  disableWay(osmId) {
1844
- this.network.edges.filter((edge) => {
1845
- var _a;
1846
- return ((_a = edge.builtFrom) == null ? void 0 : _a.id) === osmId;
1847
- }).forEach((e) => this.router.disabledEdges.add(e));
2111
+ this.graph.edges.filter((edge) => edge.data.id === osmId).forEach((e) => this.router.disabledEdges.add(e));
1848
2112
  this.disabledWays.add(osmId);
1849
2113
  }
1850
2114
  }
1851
- function getTurnInfoFromAngle(_angle) {
1852
- let direction, directionExtra;
1853
- const directionAngle = maths.rad2deg(maths.diffAngle(_angle, Math.PI));
1854
- const directionAngleAbs = Math.abs(directionAngle);
1855
- if (directionAngleAbs <= 20) {
1856
- direction = "straight";
1857
- } else {
1858
- direction = directionAngle > 0 ? "left" : "right";
1859
- if (directionAngleAbs < 55) {
1860
- directionExtra = "slight";
1861
- } else if (directionAngleAbs > 120) {
1862
- directionExtra = "sharp";
1863
- }
1864
- }
1865
- return { direction, directionExtra };
1866
- }
1867
- const WemapOsmRouterUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1868
- __proto__: null,
1869
- getTurnInfoFromAngle
1870
- }, Symbol.toStringTag, { value: "Module" }));
1871
2115
  class ItineraryInfoManager {
1872
2116
  constructor(itinerary = null) {
1873
2117
  __publicField(this, "_itinerary", null);
1874
- __publicField(this, "_mapMatching", null);
2118
+ __publicField(this, "_geoGraphProjectionHandler", null);
1875
2119
  __publicField(this, "_steps", []);
1876
2120
  __publicField(this, "_coordsNextStep", []);
1877
2121
  __publicField(this, "_coordsPreviousStep", []);
@@ -1889,8 +2133,8 @@ class ItineraryInfoManager {
1889
2133
  }
1890
2134
  this._itinerary = itinerary;
1891
2135
  this._steps = itinerary.steps;
1892
- const network = itinerary.toNetwork();
1893
- this._mapMatching = new geo.MapMatching(network);
2136
+ const graph = itinerary.toGraph();
2137
+ this._geoGraphProjectionHandler = new geo.GeoGraphProjectionHandler(graph);
1894
2138
  this._coordsNextStep = new Array(itinerary.coords.length);
1895
2139
  this._coordsPreviousStep = new Array(itinerary.coords.length);
1896
2140
  this._coordsDistanceTraveled = new Array(itinerary.coords.length);
@@ -1915,15 +2159,15 @@ class ItineraryInfoManager {
1915
2159
  });
1916
2160
  }
1917
2161
  getInfo(position) {
1918
- if (!this._itinerary || !this._mapMatching) {
2162
+ if (!this._itinerary || !this._geoGraphProjectionHandler) {
1919
2163
  return null;
1920
2164
  }
1921
- const projection = this._mapMatching.getProjection(position);
2165
+ const projection = this._geoGraphProjectionHandler.getProjection(position);
1922
2166
  if (!projection) {
1923
2167
  return null;
1924
2168
  }
1925
2169
  let itineraryInfo = null;
1926
- if (projection.nearestElement instanceof geo.GraphNode) {
2170
+ if (projection.nearestElement instanceof geo.GeoGraphVertex) {
1927
2171
  const idx = this._itinerary.coords.findIndex(
1928
2172
  (coords) => projection.nearestElement.coords === coords
1929
2173
  );
@@ -1942,14 +2186,14 @@ class ItineraryInfoManager {
1942
2186
  traveledPercentage: traveledDistance / this._itinerary.distance,
1943
2187
  remainingPercentage: remainingDistance / this._itinerary.distance
1944
2188
  };
1945
- } else if (projection.nearestElement instanceof geo.GraphEdge) {
1946
- let firstNode = projection.nearestElement.node1.coords;
2189
+ } else if (projection.nearestElement instanceof geo.GeoGraphEdge) {
2190
+ let firstNode = projection.nearestElement.vertex1.coords;
1947
2191
  let idx = this._itinerary.coords.findIndex((coords) => firstNode === coords);
1948
2192
  if (idx === -1) {
1949
2193
  throw new Error("ItineraryInfoManager: could not find projection in itinerary (Edge)");
1950
2194
  }
1951
- if (idx === this._itinerary.coords.length - 1 || this._itinerary.coords[idx + 1] !== projection.nearestElement.node2.coords) {
1952
- firstNode = projection.nearestElement.node2.coords;
2195
+ if (idx === this._itinerary.coords.length - 1 || this._itinerary.coords[idx + 1] !== projection.nearestElement.vertex2.coords) {
2196
+ firstNode = projection.nearestElement.vertex2.coords;
1953
2197
  idx--;
1954
2198
  }
1955
2199
  const traveledDistance = this._coordsDistanceTraveled[idx] + projection.coords.distanceTo(firstNode);
@@ -1969,23 +2213,21 @@ class ItineraryInfoManager {
1969
2213
  }
1970
2214
  }
1971
2215
  exports.CitywayRemoteRouter = CitywayRemoteRouter$1;
2216
+ exports.CustomNetworkMap = CustomNetworkMap;
1972
2217
  exports.DeutscheBahnRemoteRouter = DeutscheBahnRemoteRouter$1;
1973
2218
  exports.IdfmRemoteRouter = IdfmRemoteRouter$1;
1974
2219
  exports.Itinerary = Itinerary;
1975
2220
  exports.ItineraryInfoManager = ItineraryInfoManager;
1976
2221
  exports.Leg = Leg;
2222
+ exports.OsmGraph = OsmGraph;
2223
+ exports.OsmRouter = WemapOsmRouter;
1977
2224
  exports.OsrmRemoteRouter = OsrmRemoteRouter$1;
1978
2225
  exports.OtpRemoteRouter = OtpRemoteRouter$1;
1979
2226
  exports.RemoteRouterManager = RemoteRouterManager$1;
1980
2227
  exports.RemoteRouterServerUnreachable = RemoteRouterServerUnreachable;
1981
2228
  exports.RouterResponse = RouterResponse;
1982
- exports.StepInfo = StepInfo;
1983
- exports.WemapMetaRouterIOMap = CustomNetworkMap;
1984
2229
  exports.WemapMultiRemoteRouter = WemapMultiRemoteRouter$1;
1985
2230
  exports.WemapMultiRemoteRouterPayload = WemapMultiRemoteRouterPayload;
1986
2231
  exports.WemapMultiRouter = WemapMultiRouter;
1987
- exports.WemapOsmRouter = WemapOsmRouter;
1988
- exports.WemapOsmRouterOptions = WemapOsmRouterOptions;
1989
- exports.WemapOsmRouterUtils = WemapOsmRouterUtils;
1990
2232
  exports.getDurationFromLength = getDurationFromLength;
1991
2233
  //# sourceMappingURL=index.js.map