@wemap/routers 11.0.0-alpha.18 → 11.0.0-alpha.19

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 (36) hide show
  1. package/dist/index.js +406 -267
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +408 -270
  4. package/dist/index.mjs.map +1 -1
  5. package/index.ts +6 -8
  6. package/package.json +6 -5
  7. package/src/ItineraryInfoManager.spec.ts +14 -14
  8. package/src/ItineraryInfoManager.ts +13 -13
  9. package/src/model/Itinerary.spec.ts +12 -6
  10. package/src/model/Itinerary.ts +67 -66
  11. package/src/model/Leg.spec.ts +4 -4
  12. package/src/model/Leg.ts +76 -31
  13. package/src/model/Step.spec.ts +99 -0
  14. package/src/model/Step.ts +78 -11
  15. package/src/model/generateSteps.ts +8 -8
  16. package/src/remote/RemoteRouterManager.ts +17 -15
  17. package/src/remote/cityway/CitywayRemoteRouter.ts +9 -11
  18. package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.ts +1 -3
  19. package/src/remote/idfm/IdfmRemoteRouter.ts +31 -31
  20. package/src/remote/osrm/OsrmRemoteRouter.ts +5 -8
  21. package/src/remote/otp/OtpRemoteRouter.ts +9 -12
  22. package/src/remote/wemap-multi/WemapMultiRemoteRouter.ts +1 -3
  23. package/src/wemap-multi/CustomNetworkMap.ts +22 -24
  24. package/src/wemap-multi/WemapMultiRouter.ts +3 -4
  25. package/src/wemap-multi/WemapMultiRouterOptions.ts +3 -1
  26. package/src/wemap-osm/OsmGraph.spec.ts +99 -0
  27. package/src/wemap-osm/OsmGraph.ts +169 -0
  28. package/src/wemap-osm/{WemapOsmRouter.spec.ts → OsmRouter.spec.ts} +61 -40
  29. package/src/wemap-osm/OsmRouter.ts +201 -0
  30. package/vite.config.ts +1 -1
  31. package/src/model/ItineraryInfo.ts +0 -19
  32. package/src/model/StepInfo.spec.ts +0 -78
  33. package/src/model/StepInfo.ts +0 -78
  34. package/src/wemap-osm/WemapOsmRouter.ts +0 -109
  35. package/src/wemap-osm/WemapOsmRouterOptions.ts +0 -23
  36. package/src/wemap-osm/WemapOsmRouterUtils.ts +0 -21
package/dist/index.js CHANGED
@@ -8,12 +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
17
  const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
18
+ const salesman__default = /* @__PURE__ */ _interopDefaultLegacy(salesman);
17
19
  const Logger__default = /* @__PURE__ */ _interopDefaultLegacy(Logger);
18
20
  const Polyline__default = /* @__PURE__ */ _interopDefaultLegacy(Polyline);
19
21
  const pointInPolygon__default = /* @__PURE__ */ _interopDefaultLegacy(pointInPolygon);
@@ -21,53 +23,6 @@ const convexHullFn__default = /* @__PURE__ */ _interopDefaultLegacy(convexHullFn
21
23
  function getDurationFromLength(length, speed = 5) {
22
24
  return length / (speed * 1e3 / 3600);
23
25
  }
24
- function areLevelChangeEquals(l1, l2) {
25
- return l1 === l2 || l1.difference === l2.difference && l1.direction === l2.direction && l1.type === l2.type;
26
- }
27
- class StepInfo {
28
- constructor({
29
- coords,
30
- distance,
31
- name,
32
- levelChange,
33
- extras,
34
- duration
35
- }) {
36
- __publicField(this, "coords");
37
- __publicField(this, "name");
38
- __publicField(this, "distance");
39
- __publicField(this, "duration");
40
- __publicField(this, "levelChange");
41
- __publicField(this, "extras");
42
- this.coords = coords;
43
- this.name = name || null;
44
- this.distance = typeof distance === "number" ? distance : null;
45
- this.duration = typeof duration === "number" ? duration : null;
46
- this.levelChange = levelChange || null;
47
- this.extras = extras || null;
48
- }
49
- static equals(obj1, obj2) {
50
- 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));
51
- }
52
- equals(obj) {
53
- return StepInfo.equals(this, obj);
54
- }
55
- toJson() {
56
- return {
57
- coords: this.coords.toCompressedJson(),
58
- ...this.distance !== null && { distance: this.distance },
59
- ...this.duration !== null && { duration: this.duration },
60
- ...this.name !== null && { name: this.name },
61
- ...this.levelChange !== null && { levelChange: this.levelChange },
62
- ...this.extras && Object.keys(this.extras).length !== 0 && { extras: this.extras }
63
- };
64
- }
65
- static fromJson(json) {
66
- return new StepInfo(Object.assign({}, json, {
67
- coords: geo.Coordinates.fromCompressedJson(json.coords)
68
- }));
69
- }
70
- }
71
26
  const SKIP_STEP_ANGLE_MAX = maths.deg2rad(20);
72
27
  function generateSteps(leg, rules) {
73
28
  const steps = [];
@@ -98,16 +53,16 @@ function generateSteps(leg, rules) {
98
53
  levelChange = { difference, direction, type: customRules == null ? void 0 : customRules.levelChangeType };
99
54
  }
100
55
  if (currentStep && currentStep.duration === 0) {
101
- currentStep.duration = null;
56
+ delete currentStep.duration;
102
57
  }
103
- currentStep = new StepInfo({
58
+ currentStep = {
104
59
  coords: currentCoords,
105
60
  name: customRules == null ? void 0 : customRules.stepName,
106
61
  extras: customRules == null ? void 0 : customRules.stepExtras,
107
62
  levelChange,
108
63
  distance: 0,
109
64
  duration: 0
110
- });
65
+ };
111
66
  steps.push(currentStep);
112
67
  }
113
68
  currentStep.distance += currentCoords.distanceTo(nextCoords);
@@ -118,7 +73,7 @@ function generateSteps(leg, rules) {
118
73
  }
119
74
  const lastCoords = coordsArray[coordsArray.length - 1];
120
75
  if (!geo.Coordinates.equals(lastCoords, to.coords)) {
121
- steps.push(new StepInfo({ coords: lastCoords }));
76
+ steps.push({ coords: lastCoords });
122
77
  }
123
78
  return steps;
124
79
  }
@@ -134,6 +89,36 @@ function isRoutingModePublicTransport(routingMode) {
134
89
  "TRAM"
135
90
  ].includes(routingMode);
136
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: step.angle,
100
+ previousBearing: step.previousBearing,
101
+ nextBearing: step.nextBearing,
102
+ distance: step.distance,
103
+ duration: step.duration,
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) && step1.angle === step2.angle && step1.distance === step2.distance && step1.duration === step2.duration && 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 && step1.nextBearing === step2.nextBearing && step1.number === step2.number && step1.previousBearing === step2.previousBearing;
121
+ }
137
122
  class Leg {
138
123
  constructor({
139
124
  from,
@@ -154,7 +139,7 @@ class Leg {
154
139
  __publicField(this, "duration");
155
140
  __publicField(this, "startTime");
156
141
  __publicField(this, "endTime");
157
- __publicField(this, "stepsInfo");
142
+ __publicField(this, "steps");
158
143
  __publicField(this, "transportInfo");
159
144
  this.from = {
160
145
  name: from.name || null,
@@ -171,17 +156,22 @@ class Leg {
171
156
  this.startTime = typeof startTime === "number" ? startTime : null;
172
157
  this.endTime = typeof endTime === "number" ? endTime : null;
173
158
  this.transportInfo = transportInfo || null;
174
- 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);
175
165
  }
176
166
  isPublicTransport() {
177
167
  return isRoutingModePublicTransport(this.mode);
178
168
  }
179
- toNetwork() {
180
- return geo.Network.fromCoordinates([this.coords]);
169
+ toGraph() {
170
+ return geo.GeoGraph.fromCoordinates([this.coords]);
181
171
  }
182
172
  static equals(obj1, obj2) {
183
173
  var _a, _b;
184
- 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 && 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.steps === obj2.steps || ((_a = obj1.steps) == null ? void 0 : _a.length) === ((_b = obj2.steps) == null ? void 0 : _b.length));
185
175
  if (!intermediate) {
186
176
  return false;
187
177
  }
@@ -191,11 +181,9 @@ class Leg {
191
181
  return false;
192
182
  }
193
183
  }
194
- if (obj1.stepsInfo && obj2.stepsInfo) {
195
- for (i = 0; i < obj1.stepsInfo.length; i++) {
196
- if (!obj1.stepsInfo[i].equals(obj2.stepsInfo[i])) {
197
- return false;
198
- }
184
+ for (i = 0; i < obj1.steps.length; i++) {
185
+ if (!stepEquals(obj1.steps[i], obj2.steps[i])) {
186
+ return false;
199
187
  }
200
188
  }
201
189
  if (obj1.transportInfo !== obj2.transportInfo) {
@@ -224,7 +212,7 @@ class Leg {
224
212
  },
225
213
  duration: this.duration,
226
214
  coords: this.coords.map((coords) => coords.toCompressedJson()),
227
- steps: this.stepsInfo.map((stepInfo) => stepInfo.toJson()),
215
+ steps: this.steps.map(stepToJson),
228
216
  ...this.startTime !== null && { startTime: this.startTime },
229
217
  ...this.endTime !== null && { endTime: this.endTime },
230
218
  ...this.transportInfo !== null && { transportInfo: this.transportInfo }
@@ -242,8 +230,7 @@ class Leg {
242
230
  name: json.to.name || null
243
231
  },
244
232
  coords: json.coords.map(geo.Coordinates.fromCompressedJson),
245
- stepsInfo: ((_a = json.steps) == null ? void 0 : _a.map(StepInfo.fromJson)) || null,
246
- stepsGenerationRules: void 0
233
+ steps: ((_a = json.steps) == null ? void 0 : _a.map(jsonToStep)) || null
247
234
  }));
248
235
  return leg;
249
236
  }
@@ -251,7 +238,7 @@ class Leg {
251
238
  return new Leg({
252
239
  from: { coords: graphItinerary.start },
253
240
  to: { coords: graphItinerary.end },
254
- coords: graphItinerary.nodes.map((node) => node.coords),
241
+ coords: graphItinerary.vertices.map((vertex) => vertex.coords),
255
242
  duration: graphItinerary.edgesWeights.reduce((acc, weight) => acc + weight, 0),
256
243
  mode,
257
244
  stepsGenerationRules
@@ -263,12 +250,45 @@ class Leg {
263
250
  for (const coords of this.coords) {
264
251
  coords.level = geo.Level.multiplyBy(coords.level, levelFactor);
265
252
  }
266
- this.stepsInfo.forEach((step) => {
253
+ this.steps.forEach((step) => {
267
254
  step.coords.level = geo.Level.multiplyBy(step.coords.level, levelFactor);
268
255
  });
269
256
  }
270
- getSteps(itinerarySteps) {
271
- 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
+ });
272
292
  }
273
293
  }
274
294
  class Itinerary {
@@ -288,7 +308,6 @@ class Itinerary {
288
308
  __publicField(this, "startTime");
289
309
  __publicField(this, "endTime");
290
310
  __publicField(this, "_coords", null);
291
- __publicField(this, "_steps", null);
292
311
  __publicField(this, "_distance", null);
293
312
  this.from = from;
294
313
  this.to = to;
@@ -296,6 +315,7 @@ class Itinerary {
296
315
  this.duration = typeof duration === "number" ? duration : this.legs.reduce((dur, leg) => dur + leg.duration, 0);
297
316
  this.startTime = typeof startTime === "number" ? startTime : null;
298
317
  this.endTime = typeof endTime === "number" ? endTime : null;
318
+ this.updateStepsFromLegs();
299
319
  }
300
320
  set coords(_) {
301
321
  throw new Error("Itinerary.coords cannot be set. They are calculated from Itinerary.legs.");
@@ -310,45 +330,7 @@ class Itinerary {
310
330
  throw new Error("Itinerary.step cannot be set. They are calculated from Itinerary.legs.");
311
331
  }
312
332
  get steps() {
313
- if (this._steps) {
314
- return this._steps;
315
- }
316
- const itineraryCoords = this.coords.filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));
317
- const stepsInfo = this.legs.map((leg) => leg.stepsInfo).flat();
318
- const steps = stepsInfo.map((stepInfo, stepId) => {
319
- const coordsId = itineraryCoords.findIndex((coords) => coords.equals(stepInfo.coords));
320
- if (coordsId === -1) {
321
- throw new Error("Cannot find step coordinates in itinerary coordinates.");
322
- }
323
- const coordsBeforeStep = coordsId === 0 ? this.from : itineraryCoords[coordsId - 1];
324
- const coordsAfterStep = coordsId === itineraryCoords.length - 1 ? this.to : itineraryCoords[coordsId + 1];
325
- const previousBearing = coordsBeforeStep.bearingTo(stepInfo.coords);
326
- const nextBearing = stepInfo.coords.bearingTo(coordsAfterStep);
327
- let distance = 0;
328
- const coordsToStopCalculation = stepId !== stepsInfo.length - 1 ? stepsInfo[stepId + 1].coords : itineraryCoords[itineraryCoords.length - 1];
329
- let currentCoordsId = coordsId;
330
- while (!itineraryCoords[currentCoordsId].equals(coordsToStopCalculation)) {
331
- distance += itineraryCoords[currentCoordsId].distanceTo(itineraryCoords[currentCoordsId + 1]);
332
- currentCoordsId++;
333
- }
334
- if (currentCoordsId === itineraryCoords.length - 1) {
335
- distance += itineraryCoords[currentCoordsId].distanceTo(this.to);
336
- }
337
- return {
338
- ...stepInfo,
339
- number: stepId + 1,
340
- previousBearing,
341
- nextBearing,
342
- angle: maths.diffAngle(previousBearing, nextBearing + Math.PI),
343
- firstStep: stepId === 0,
344
- lastStep: stepId === stepsInfo.length - 1,
345
- distance,
346
- duration: stepInfo.duration || getDurationFromLength(distance),
347
- previousStep: null,
348
- nextStep: null
349
- };
350
- });
351
- return steps;
333
+ return this.legs.map((leg) => leg.steps).flat();
352
334
  }
353
335
  set mode(_) {
354
336
  throw new Error("Itinerary.mode cannot be set. They are calculated from Itinerary.legs.");
@@ -384,8 +366,8 @@ class Itinerary {
384
366
  }
385
367
  return this._distance;
386
368
  }
387
- toNetwork() {
388
- return geo.Network.fromCoordinates([this.coords]);
369
+ toGraph() {
370
+ return geo.GeoGraph.fromCoordinates([this.coords]);
389
371
  }
390
372
  static fromItineraries(...itineraries) {
391
373
  let duration = 0;
@@ -477,8 +459,8 @@ class Itinerary {
477
459
  for (const coords of leg.coords) {
478
460
  coords.level = coords.level || 0;
479
461
  }
480
- if (leg.stepsInfo) {
481
- for (const step of leg.stepsInfo) {
462
+ if (leg.steps) {
463
+ for (const step of leg.steps) {
482
464
  step.coords.level = step.coords.level || 0;
483
465
  }
484
466
  }
@@ -499,6 +481,36 @@ class Itinerary {
499
481
  }
500
482
  };
501
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
+ }
502
514
  }
503
515
  class RouterResponse {
504
516
  constructor({
@@ -561,56 +573,158 @@ class RouterResponse {
561
573
  }
562
574
  }
563
575
  }
564
- const _WemapOsmRouterOptions = class extends osm.OsmGraphRouterOptions {
565
- constructor() {
566
- super(...arguments);
567
- __publicField(this, "weightEdgeFn", (edge) => edge.builtFrom instanceof osm.OsmNode && edge.builtFrom.isElevator ? 30 : getDurationFromLength(edge.length));
568
- }
569
- static get WITHOUT_STAIRS() {
570
- const options = new _WemapOsmRouterOptions();
571
- options.acceptEdgeFn = (edge) => {
572
- var _a;
573
- 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
+ return HIGHWAYS_PEDESTRIANS.includes(way.tags.highway) || way.tags.footway === "sidewalk" || way.tags.public_transport === "platform" || way.tags.railway === "platform";
579
+ };
580
+ class OsmGraph extends geo.GeoGraph {
581
+ getVertexByCoords(coords) {
582
+ return geo.GeoGraph.getVertexByCoords(this.vertices, coords);
583
+ }
584
+ getVertexByName(name) {
585
+ return super.getVertexByName(name);
586
+ }
587
+ getEdgeByName(name) {
588
+ return super.getEdgeByName(name);
589
+ }
590
+ static fromOsmModel(osmModel, waySelectionFilter = DEFAULT_WAY_SELECTOR) {
591
+ const nodes = [];
592
+ const edges = [];
593
+ const nodesCreated = {};
594
+ const elevatorNodes = [];
595
+ const getOrCreateNode = (osmNode) => {
596
+ let node = nodesCreated[osmNode.id];
597
+ if (!node) {
598
+ node = new geo.GeoGraphVertex(osmNode.coords, { data: osmNode, name: osmNode.tags.name });
599
+ nodesCreated[osmNode.id] = node;
600
+ nodes.push(node);
601
+ if (osmNode.tags.highway === "elevator") {
602
+ elevatorNodes.push(node);
603
+ }
604
+ }
605
+ return node;
606
+ };
607
+ osmModel.ways.forEach((way) => {
608
+ if (!waySelectionFilter(way)) {
609
+ return;
610
+ }
611
+ let firstNode = getOrCreateNode(way.nodes[0]);
612
+ for (let i = 1; i < way.nodes.length; i++) {
613
+ const secondNode = getOrCreateNode(way.nodes[i]);
614
+ const edge = new geo.GeoGraphEdge(
615
+ firstNode,
616
+ secondNode,
617
+ { data: way, name: way.tags.name, level: way.level }
618
+ );
619
+ OsmGraph.manageOneWay(edge, way);
620
+ edges.push(edge);
621
+ firstNode = secondNode;
622
+ }
623
+ });
624
+ elevatorNodes.forEach((node) => {
625
+ OsmGraph.createNodesAndEdgesFromElevator(nodes, edges, node);
626
+ });
627
+ return new OsmGraph(nodes, edges, true);
628
+ }
629
+ static manageOneWay(edge, way) {
630
+ const { highway, oneway, conveying } = way.tags;
631
+ edge.isOneway = Boolean(oneway === "yes" || oneway === "true" || oneway === "1" || conveying && highway && ["forward", "backward"].includes(conveying));
632
+ if (edge.isOneway && conveying === "backward") {
633
+ const tmpNode = edge.vertex1;
634
+ edge.vertex1 = edge.vertex2;
635
+ edge.vertex2 = tmpNode;
636
+ }
637
+ }
638
+ static createNodesAndEdgesFromElevator(nodes, edges, elevatorNode) {
639
+ const createdNodes = [];
640
+ const getOrCreateLevelVertex = (level) => {
641
+ let levelVertex = createdNodes.find(({ coords }) => geo.Level.equals(level, coords.level));
642
+ if (!levelVertex) {
643
+ levelVertex = new geo.GeoGraphVertex(elevatorNode.coords.clone(), {
644
+ data: elevatorNode.data,
645
+ name: `${elevatorNode.name} (elevator lvl: ${level})`
646
+ });
647
+ levelVertex.coords.level = level;
648
+ createdNodes.push(levelVertex);
649
+ nodes.push(levelVertex);
650
+ }
651
+ return levelVertex;
574
652
  };
575
- return options;
653
+ elevatorNode.edges.forEach((edge) => {
654
+ if (geo.Level.isRange(edge.level)) {
655
+ throw new Error("Cannot handle this elevator edge due to ambiguity");
656
+ }
657
+ const levelVertex = getOrCreateLevelVertex(edge.level);
658
+ if (edge.vertex1 === elevatorNode) {
659
+ edge.vertex1 = levelVertex;
660
+ } else {
661
+ edge.vertex2 = levelVertex;
662
+ }
663
+ levelVertex.edges.push(edge);
664
+ });
665
+ for (let i = 0; i < createdNodes.length; i++) {
666
+ for (let j = i + 1; j < createdNodes.length; j++) {
667
+ const createdNode1 = createdNodes[i];
668
+ const createdNode2 = createdNodes[j];
669
+ if (createdNode1.coords.level === null || createdNode2.coords.level === null) {
670
+ continue;
671
+ }
672
+ const minLevel = Math.min(createdNode1.coords.level, createdNode2.coords.level);
673
+ const maxLevel = Math.max(createdNode1.coords.level, createdNode2.coords.level);
674
+ const newEdge = new geo.GeoGraphEdge(
675
+ createdNode1,
676
+ createdNode2,
677
+ { data: elevatorNode.data, name: elevatorNode.name, level: [minLevel, maxLevel] }
678
+ );
679
+ edges.push(newEdge);
680
+ }
681
+ }
682
+ const elevatorNodeIndex = nodes.indexOf(elevatorNode);
683
+ if (elevatorNodeIndex > -1) {
684
+ nodes.splice(elevatorNodeIndex, 1);
685
+ }
576
686
  }
577
- };
578
- let WemapOsmRouterOptions = _WemapOsmRouterOptions;
579
- __publicField(WemapOsmRouterOptions, "DEFAULT", new _WemapOsmRouterOptions());
687
+ }
688
+ const DEFAULT_OPTIONS = Object.assign({}, geo.GeoGraphRouter.DEFAULT_OPTIONS, {
689
+ weightEdgeFn: (edge) => edge.data instanceof osm.OsmNode && edge.data.isElevator ? 30 : getDurationFromLength(edge.length)
690
+ });
691
+ const WITHOUT_STAIRS_OPTIONS = Object.assign({}, DEFAULT_OPTIONS, {
692
+ acceptEdgeFn: (edge) => edge.data.tags.highway !== "steps"
693
+ });
580
694
  const buildStepsRules = (graphItinerary) => (currentCoords, nextCoords, previousStep) => {
581
- var _a, _b, _c, _d, _e, _f, _g;
695
+ var _a, _b, _c, _d, _e;
582
696
  const edges = graphItinerary.edges;
583
- const nodes = graphItinerary.nodes;
584
- const node = geo.GraphUtils.getNodeByCoords(nodes, currentCoords);
585
- const nextNode = geo.GraphUtils.getNodeByCoords(nodes, nextCoords);
586
- if (!node || !nextNode)
697
+ const vertices = graphItinerary.vertices;
698
+ const vertex = geo.GeoGraph.getVertexByCoords(vertices, currentCoords);
699
+ const nextVertex = geo.GeoGraph.getVertexByCoords(vertices, nextCoords);
700
+ if (!vertex || !nextVertex)
587
701
  return {};
588
- const edge = geo.GraphUtils.getEdgeByNodes(edges, node, nextNode);
702
+ const edge = geo.GeoGraphEdge.getEdgeByVertices(edges, vertex, nextVertex);
589
703
  if (!edge)
590
704
  return {};
591
705
  const edgeId = edges.findIndex((_edge) => _edge === edge);
592
- const isSubwayEntrance = node ? ((_a = node.builtFrom) == null ? void 0 : _a.tags.railway) === "subway_entrance" : false;
593
- const isGate = node ? ((_b = node.builtFrom) == null ? void 0 : _b.tags.barrier) === "gate" || ((_c = node.builtFrom) == null ? void 0 : _c.tags.aeroway) === "gate" : false;
706
+ const isSubwayEntrance = vertex ? ((_a = vertex.data) == null ? void 0 : _a.tags.railway) === "subway_entrance" : false;
707
+ const isGate = vertex ? ((_b = vertex.data) == null ? void 0 : _b.tags.barrier) === "gate" || ((_c = vertex.data) == null ? void 0 : _c.tags.aeroway) === "gate" : false;
594
708
  let levelChangeType = null;
595
- if ((_d = edge.builtFrom) == null ? void 0 : _d.isElevator) {
709
+ if (edge.data.isElevator) {
596
710
  levelChangeType = "elevator";
597
- } else if ((edge.builtFrom instanceof osm.OsmNode || edge.builtFrom instanceof osm.OsmWay) && edge.builtFrom.isConveying) {
711
+ } else if (edge.data.isConveying) {
598
712
  levelChangeType = "conveyor";
599
- } else if (edge.builtFrom instanceof osm.OsmWay && edge.builtFrom.areStairs) {
713
+ } else if (edge.data instanceof osm.OsmWay && edge.data.areStairs) {
600
714
  levelChangeType = "stairs";
601
715
  }
602
- const edgeTags = ((_e = edge.builtFrom) == null ? void 0 : _e.tags) || {};
716
+ const edgeTags = edge.data.tags || {};
603
717
  let levelChangeDirection = null;
604
- if (edge.builtFrom instanceof osm.OsmWay && edge.builtFrom.areStairs && ["up", "down"].includes(edgeTags.incline) && !(previousStep == null ? void 0 : previousStep.levelChange)) {
718
+ if (edge.data instanceof osm.OsmWay && edge.data.areStairs && ["up", "down"].includes(edgeTags.incline) && !(previousStep == null ? void 0 : previousStep.levelChange)) {
605
719
  levelChangeDirection = edgeTags.incline;
606
- for (const n of edge.builtFrom.nodes) {
607
- if (n !== node.builtFrom)
720
+ for (const n of edge.data.nodes) {
721
+ if (n !== vertex.data)
608
722
  continue;
609
723
  }
610
- const isReversed = edge.builtFrom.nodes.reduce((acc, n, idx, arr) => {
611
- if (n !== node.builtFrom)
724
+ const isReversed = edge.data.nodes.reduce((acc, n, idx, arr) => {
725
+ if (n !== vertex.data)
612
726
  return acc;
613
- acc = !(idx + 1 < arr.length && arr[idx + 1] === nextNode.builtFrom);
727
+ acc = !(idx + 1 < arr.length && arr[idx + 1] === nextVertex.data);
614
728
  return acc;
615
729
  }, null);
616
730
  if (isReversed) {
@@ -620,32 +734,85 @@ const buildStepsRules = (graphItinerary) => (currentCoords, nextCoords, previous
620
734
  const createNewStep = isSubwayEntrance || levelChangeDirection;
621
735
  return {
622
736
  createNewStep,
623
- stepName: (_f = edge.builtFrom) == null ? void 0 : _f.tags.name,
737
+ stepName: (_d = edge.data) == null ? void 0 : _d.tags.name,
624
738
  duration: graphItinerary.edgesWeights[edgeId],
625
739
  stepExtras: {
626
740
  ...isSubwayEntrance && { isSubwayEntrance: true },
627
- ...isSubwayEntrance && ((_g = node.builtFrom) == null ? void 0 : _g.tags.ref) && { subwayEntranceRef: node.builtFrom.tags.ref },
741
+ ...isSubwayEntrance && ((_e = vertex.data) == null ? void 0 : _e.tags.ref) && { subwayEntranceRef: vertex.data.tags.ref },
628
742
  ...isGate && { isGate: true }
629
743
  },
630
744
  ...levelChangeType && { levelChangeType },
631
745
  ...levelChangeDirection && { levelChangeDirection }
632
746
  };
633
747
  };
634
- class WemapOsmRouter extends osm.OsmGraphRouter {
635
- constructor(network) {
636
- super(network);
748
+ class WemapOsmRouter extends geo.GeoGraphRouter {
749
+ constructor(graph) {
750
+ super(graph);
637
751
  }
638
752
  static get rname() {
639
- return "wemap";
753
+ return "wemap-osm";
640
754
  }
641
- getShortestPath(start, end, options = new WemapOsmRouterOptions()) {
755
+ getShortestPath(start, end, options = DEFAULT_OPTIONS) {
642
756
  return super.getShortestPath(start, end, options);
643
757
  }
644
- getItinerary(start, end, options = new WemapOsmRouterOptions()) {
758
+ getItinerary(start, end, options = DEFAULT_OPTIONS) {
645
759
  const graphItinerary = this.getShortestPath(start, end, options);
646
760
  return Itinerary.fromGraphItinerary(graphItinerary, "WALK", buildStepsRules(graphItinerary));
647
761
  }
762
+ static getTurnInfoFromAngle(_angle) {
763
+ let direction, directionExtra;
764
+ const directionAngle = maths.rad2deg(maths.diffAngle(_angle, Math.PI));
765
+ const directionAngleAbs = Math.abs(directionAngle);
766
+ if (directionAngleAbs <= 20) {
767
+ direction = "straight";
768
+ } else {
769
+ direction = directionAngle > 0 ? "left" : "right";
770
+ if (directionAngleAbs < 55) {
771
+ directionExtra = "slight";
772
+ } else if (directionAngleAbs > 120) {
773
+ directionExtra = "sharp";
774
+ }
775
+ }
776
+ return { direction, directionExtra };
777
+ }
778
+ getShortestTrip(waypoints, options = DEFAULT_OPTIONS) {
779
+ const points = waypoints.map((waypoint) => {
780
+ const point = new salesman__default.default.Point(0, 0);
781
+ point.coords = waypoint;
782
+ return point;
783
+ });
784
+ const cache = [];
785
+ const solution = salesman__default.default.solve(points, 0.9, void 0, (p, q) => {
786
+ const osmItinerary = this.getShortestPath(
787
+ p.coords,
788
+ q.coords,
789
+ options
790
+ );
791
+ cache.push(osmItinerary);
792
+ return osmItinerary.edgesWeights.reduce((acc, weight) => acc + weight, 0);
793
+ });
794
+ const orderedPoints = solution.map((i) => points[i]);
795
+ const orderedItineraries = [];
796
+ for (let i = 0; i < orderedPoints.length - 1; i++) {
797
+ const p = orderedPoints[i];
798
+ const q = orderedPoints[i + 1];
799
+ orderedItineraries.push(
800
+ cache.find((itinerary) => itinerary.start === p.coords && itinerary.end === q.coords || itinerary.end === p.coords && itinerary.start === q.coords)
801
+ );
802
+ }
803
+ return orderedItineraries;
804
+ }
805
+ getTripItinerary(waypoints, options = DEFAULT_OPTIONS) {
806
+ const shortestTrip = this.getShortestTrip(waypoints, options);
807
+ return new Itinerary({
808
+ from: shortestTrip[0].start,
809
+ to: shortestTrip[shortestTrip.length - 1].end,
810
+ legs: shortestTrip.map((graphItinerary) => Leg.fromGraphItinerary(graphItinerary))
811
+ });
812
+ }
648
813
  }
814
+ __publicField(WemapOsmRouter, "DEFAULT_OPTIONS", DEFAULT_OPTIONS);
815
+ __publicField(WemapOsmRouter, "WITHOUT_STAIRS_OPTIONS", WITHOUT_STAIRS_OPTIONS);
649
816
  class RemoteRouter {
650
817
  }
651
818
  class RemoteRouterServerUnreachable extends Error {
@@ -797,7 +964,7 @@ class CitywayRemoteRouter extends RemoteRouter {
797
964
  const legCoords = [];
798
965
  let legFrom, legTo;
799
966
  let transportInfo;
800
- let stepsInfo;
967
+ let minStepsInfo;
801
968
  if (legMode === "UNKNOWN") {
802
969
  continue itineraryLoop;
803
970
  }
@@ -810,7 +977,7 @@ class CitywayRemoteRouter extends RemoteRouter {
810
977
  name: jsonLeg.Arrival.Site.Name,
811
978
  coords: jsonToCoordinates$2(jsonLeg.Arrival.Site.Position)
812
979
  };
813
- stepsInfo = [];
980
+ minStepsInfo = [];
814
981
  for (const jsonPathLink of jsonLeg.pathLinks.PathLink) {
815
982
  let stepCoords;
816
983
  if (jsonPathLink.Geometry && jsonPathLink.Geometry !== "Null") {
@@ -823,11 +990,11 @@ class CitywayRemoteRouter extends RemoteRouter {
823
990
  legCoords.push(coords);
824
991
  }
825
992
  });
826
- stepsInfo.push(new StepInfo({
993
+ minStepsInfo.push({
827
994
  coords: stepCoords[0],
828
995
  distance: jsonPathLink.Distance,
829
996
  name: jsonPathLink.Departure.Site.Name
830
- }));
997
+ });
831
998
  }
832
999
  } else if (isRoutingModePublicTransport(legMode)) {
833
1000
  legFrom = {
@@ -856,11 +1023,11 @@ class CitywayRemoteRouter extends RemoteRouter {
856
1023
  }
857
1024
  });
858
1025
  }
859
- stepsInfo = [new StepInfo({
1026
+ minStepsInfo = [{
860
1027
  coords: legCoords[0],
861
1028
  name: jsonLeg.Line.Name,
862
1029
  distance: jsonLeg.Distance
863
- })];
1030
+ }];
864
1031
  } else {
865
1032
  Logger__default.default.warn(`[CitywayParser] Unknown leg mode: ${jsonLeg.TransportMode}`);
866
1033
  continue;
@@ -874,7 +1041,7 @@ class CitywayRemoteRouter extends RemoteRouter {
874
1041
  from: legFrom,
875
1042
  to: legTo,
876
1043
  transportInfo,
877
- stepsInfo
1044
+ minStepsInfo
878
1045
  });
879
1046
  legs.push(leg);
880
1047
  }
@@ -1116,16 +1283,15 @@ class IdfmRemoteRouter extends RemoteRouter {
1116
1283
  newCoords = last(result);
1117
1284
  coords[_idCoordsInLeg] = newCoords;
1118
1285
  }
1119
- outputSteps.push(new StepInfo({
1286
+ outputSteps.push({
1120
1287
  ...step,
1121
1288
  coords: newCoords
1122
- }));
1289
+ });
1123
1290
  previousStep = step;
1124
1291
  }
1125
1292
  return outputSteps;
1126
1293
  }
1127
1294
  createRouterResponseFromJson(json, from, to) {
1128
- var _a;
1129
1295
  const routerResponse = new RouterResponse({ routerName: this.rname, from, to });
1130
1296
  if (!json || !json.journeys) {
1131
1297
  return routerResponse;
@@ -1146,7 +1312,9 @@ class IdfmRemoteRouter extends RemoteRouter {
1146
1312
  }
1147
1313
  return acc;
1148
1314
  }, []);
1149
- let stepsInfo;
1315
+ let minStepsInfo;
1316
+ let transportInfo;
1317
+ let mode = routingModeCorrespondance.get(jsonSection.mode);
1150
1318
  if (jsonSection.path) {
1151
1319
  const idfmIntermediateSteps = [];
1152
1320
  for (const jsonPathLink of jsonSection.path) {
@@ -1155,10 +1323,25 @@ class IdfmRemoteRouter extends RemoteRouter {
1155
1323
  distance: jsonPathLink.length
1156
1324
  });
1157
1325
  }
1158
- stepsInfo = this.findStepsCoord(legCoords, idfmIntermediateSteps);
1326
+ minStepsInfo = this.findStepsCoord(legCoords, idfmIntermediateSteps);
1327
+ }
1328
+ if (jsonSection.type === "public_transport") {
1329
+ transportInfo = {
1330
+ name: jsonSection.display_informations.code,
1331
+ routeColor: jsonSection.display_informations.color,
1332
+ routeTextColor: jsonSection.display_informations.text_color,
1333
+ directionName: jsonSection.display_informations.direction
1334
+ };
1335
+ mode = routingModeCorrespondance.get(jsonSection.display_informations.physical_mode);
1336
+ const legStep = {
1337
+ coords: legCoords[0],
1338
+ name: transportInfo.directionName,
1339
+ distance: jsonSection.geojson.properties[0].length
1340
+ };
1341
+ minStepsInfo = [legStep];
1159
1342
  }
1160
1343
  const leg = new Leg({
1161
- mode: routingModeCorrespondance.get(jsonSection.mode),
1344
+ mode,
1162
1345
  duration: jsonSection.duration,
1163
1346
  startTime: dateStringToTimestamp(jsonSection.departure_date_time, timeZone),
1164
1347
  endTime: dateStringToTimestamp(jsonSection.arrival_date_time, timeZone),
@@ -1171,23 +1354,9 @@ class IdfmRemoteRouter extends RemoteRouter {
1171
1354
  coords: toSection
1172
1355
  },
1173
1356
  coords: legCoords,
1174
- stepsInfo
1357
+ transportInfo,
1358
+ minStepsInfo
1175
1359
  });
1176
- if (jsonSection.type === "public_transport") {
1177
- leg.transportInfo = {
1178
- name: jsonSection.display_informations.code,
1179
- routeColor: jsonSection.display_informations.color,
1180
- routeTextColor: jsonSection.display_informations.text_color,
1181
- directionName: jsonSection.display_informations.direction
1182
- };
1183
- leg.mode = routingModeCorrespondance.get(jsonSection.display_informations.physical_mode);
1184
- const legStep = new StepInfo({
1185
- coords: leg.coords[0],
1186
- name: (_a = leg.transportInfo) == null ? void 0 : _a.directionName,
1187
- distance: jsonSection.geojson.properties[0].length
1188
- });
1189
- leg.stepsInfo = [legStep];
1190
- }
1191
1360
  legs.push(leg);
1192
1361
  }
1193
1362
  const itinerary = new Itinerary({
@@ -1352,19 +1521,19 @@ class OsrmRemoteRouter extends RemoteRouter {
1352
1521
  const legs = jsonItinerary.legs.map((jsonLeg) => {
1353
1522
  var _a;
1354
1523
  const legCoords = jsonLeg.steps.map((step) => step.geometry.coordinates.map(this.jsonToCoordinates)).flat().filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));
1355
- const stepsInfo = (_a = jsonLeg.steps) == null ? void 0 : _a.map(({ maneuver, name, distance, duration }) => {
1524
+ const minStepsInfo = (_a = jsonLeg.steps) == null ? void 0 : _a.map(({ maneuver, name, distance, duration }) => {
1356
1525
  const stepCoords = this.jsonToCoordinates(maneuver.location);
1357
1526
  const distances = legCoords.map((coords) => coords.distanceTo(stepCoords));
1358
1527
  const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));
1359
1528
  if (idStepCoordsInLeg < 0) {
1360
1529
  throw new Error("Osrm Parser: Cannot find step coords in leg coordinates");
1361
1530
  }
1362
- return new StepInfo({
1531
+ return {
1363
1532
  coords: stepCoords,
1364
1533
  name,
1365
1534
  distance,
1366
1535
  duration
1367
- });
1536
+ };
1368
1537
  });
1369
1538
  return new Leg({
1370
1539
  mode,
@@ -1376,7 +1545,7 @@ class OsrmRemoteRouter extends RemoteRouter {
1376
1545
  to: {
1377
1546
  coords: legCoords[legCoords.length - 1]
1378
1547
  },
1379
- stepsInfo
1548
+ minStepsInfo
1380
1549
  });
1381
1550
  });
1382
1551
  return new Itinerary({
@@ -1445,7 +1614,7 @@ class OtpRemoteRouter extends RemoteRouter {
1445
1614
  for (const jsonLeg of jsonItinerary.legs) {
1446
1615
  const legCoords = Polyline__default.default.decode(jsonLeg.legGeometry.points).map(([lat, lon]) => new geo.Coordinates(lat, lon));
1447
1616
  let transportInfo;
1448
- let stepsInfo;
1617
+ let minStepsInfo;
1449
1618
  if (isLegPT(jsonLeg)) {
1450
1619
  transportInfo = {
1451
1620
  name: jsonLeg.routeShortName,
@@ -1453,21 +1622,21 @@ class OtpRemoteRouter extends RemoteRouter {
1453
1622
  routeTextColor: jsonLeg.routeTextColor,
1454
1623
  directionName: jsonLeg.headsign
1455
1624
  };
1456
- stepsInfo = [new StepInfo({
1625
+ minStepsInfo = [{
1457
1626
  coords: legCoords[0],
1458
1627
  name: jsonLeg.headsign
1459
- })];
1628
+ }];
1460
1629
  } else {
1461
- stepsInfo = jsonLeg.steps.map((jsonStep) => {
1630
+ minStepsInfo = jsonLeg.steps.map((jsonStep) => {
1462
1631
  const distances = legCoords.map((coords) => coords.distanceTo(jsonToCoordinates(jsonStep)));
1463
1632
  const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));
1464
1633
  if (idStepCoordsInLeg < 0) {
1465
1634
  throw new Error("OTP Parser: Cannot find closest step");
1466
1635
  }
1467
- return new StepInfo({
1636
+ return {
1468
1637
  coords: legCoords[idStepCoordsInLeg],
1469
1638
  name: jsonStep.streetName
1470
- });
1639
+ };
1471
1640
  });
1472
1641
  }
1473
1642
  const leg = new Leg({
@@ -1485,7 +1654,7 @@ class OtpRemoteRouter extends RemoteRouter {
1485
1654
  },
1486
1655
  coords: legCoords,
1487
1656
  transportInfo,
1488
- stepsInfo
1657
+ minStepsInfo
1489
1658
  });
1490
1659
  legs.push(leg);
1491
1660
  }
@@ -1551,19 +1720,17 @@ class WemapMultiRemoteRouter extends RemoteRouter {
1551
1720
  }
1552
1721
  }
1553
1722
  const WemapMultiRemoteRouter$1 = new WemapMultiRemoteRouter();
1723
+ const remoteRouters = [
1724
+ CitywayRemoteRouter$1,
1725
+ DeutscheBahnRemoteRouter$1,
1726
+ IdfmRemoteRouter$1,
1727
+ OsrmRemoteRouter$1,
1728
+ OtpRemoteRouter$1,
1729
+ WemapMultiRemoteRouter$1
1730
+ ];
1554
1731
  class RemoteRouterManager {
1555
- constructor() {
1556
- __publicField(this, "remoteRouters", [
1557
- CitywayRemoteRouter$1,
1558
- DeutscheBahnRemoteRouter$1,
1559
- IdfmRemoteRouter$1,
1560
- OsrmRemoteRouter$1,
1561
- OtpRemoteRouter$1,
1562
- WemapMultiRemoteRouter$1
1563
- ]);
1564
- }
1565
1732
  getRouterByName(name) {
1566
- return this.remoteRouters.find((remoteRouter) => remoteRouter.rname === name);
1733
+ return remoteRouters.find((remoteRouter) => remoteRouter.rname === name);
1567
1734
  }
1568
1735
  async getItineraries(name, endpointUrl, mode, waypoints, options) {
1569
1736
  const router = this.getRouterByName(name);
@@ -1572,9 +1739,9 @@ class RemoteRouterManager {
1572
1739
  }
1573
1740
  return router.getItineraries(endpointUrl, mode, waypoints, options);
1574
1741
  }
1575
- async getItinerariesWithFallback(remoteRouters, mode, waypoints, options) {
1742
+ async getItinerariesWithFallback(remoteRouters2, mode, waypoints, options) {
1576
1743
  let routerResponse;
1577
- for (const { name, endpointUrl } of remoteRouters) {
1744
+ for (const { name, endpointUrl } of remoteRouters2) {
1578
1745
  routerResponse = await this.getItineraries(name, endpointUrl, mode, waypoints, options);
1579
1746
  if (routerResponse.itineraries.length) {
1580
1747
  return routerResponse;
@@ -1582,7 +1749,7 @@ class RemoteRouterManager {
1582
1749
  }
1583
1750
  if (!routerResponse) {
1584
1751
  routerResponse = new RouterResponse({
1585
- routerName: remoteRouters.map((rr) => rr.name),
1752
+ routerName: remoteRouters2.map((rr) => rr.name),
1586
1753
  from: waypoints[0],
1587
1754
  to: waypoints[waypoints.length]
1588
1755
  });
@@ -1617,7 +1784,7 @@ class WemapMultiRouter {
1617
1784
  from: start,
1618
1785
  to: end
1619
1786
  });
1620
- const remoteRouters = ((_a = options == null ? void 0 : options.remoteRouters) == null ? void 0 : _a.filter(({ name }) => name !== WemapMultiRemoteRouter$1.rname)) || [];
1787
+ const remoteRouters2 = ((_a = options == null ? void 0 : options.remoteRouters) == null ? void 0 : _a.filter(({ name }) => name !== WemapMultiRemoteRouter$1.rname)) || [];
1621
1788
  let ioMapsToTest = this.maps;
1622
1789
  const targetMaps = options == null ? void 0 : options.targetMaps;
1623
1790
  if (targetMaps) {
@@ -1632,7 +1799,7 @@ class WemapMultiRouter {
1632
1799
  }
1633
1800
  if (!ioMapsToTest.length) {
1634
1801
  try {
1635
- return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters, mode, waypoints);
1802
+ return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters2, mode, waypoints);
1636
1803
  } catch (e) {
1637
1804
  if (!isRoutingError(e)) {
1638
1805
  throw e;
@@ -1643,7 +1810,7 @@ class WemapMultiRouter {
1643
1810
  }
1644
1811
  let ioMapItinerary;
1645
1812
  const mapWithStart = ioMapsToTest.find((map) => map.isPointInside(start));
1646
- const wemapOsmRouterOptions = !options || !("useStairs" in options) || options.useStairs ? WemapOsmRouterOptions.DEFAULT : WemapOsmRouterOptions.WITHOUT_STAIRS;
1813
+ const wemapOsmRouterOptions = !options || !("useStairs" in options) || options.useStairs ? WemapOsmRouter.DEFAULT_OPTIONS : WemapOsmRouter.WITHOUT_STAIRS_OPTIONS;
1647
1814
  if (mapWithStart && mapWithStart.isPointInside(end)) {
1648
1815
  try {
1649
1816
  ioMapItinerary = mapWithStart.getItineraryInsideMap(start, end, wemapOsmRouterOptions);
@@ -1662,7 +1829,7 @@ class WemapMultiRouter {
1662
1829
  let remoteRouterResponse;
1663
1830
  if (!mapWithStart && !mapWithEnd) {
1664
1831
  try {
1665
- return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters, mode, waypoints);
1832
+ return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters2, mode, waypoints);
1666
1833
  } catch (e) {
1667
1834
  if (!isRoutingError(e)) {
1668
1835
  throw e;
@@ -1680,7 +1847,7 @@ class WemapMultiRouter {
1680
1847
  try {
1681
1848
  ioMapItinerary = mapWithStart.getBestItineraryFromStartToEntryPoints(start, end, wemapOsmRouterOptions);
1682
1849
  remoteRouterResponse = await RemoteRouterManager$1.getItinerariesWithFallback(
1683
- remoteRouters,
1850
+ remoteRouters2,
1684
1851
  mode,
1685
1852
  [ioMapItinerary.to, end]
1686
1853
  );
@@ -1691,7 +1858,7 @@ class WemapMultiRouter {
1691
1858
  if (!isRoutingError(e)) {
1692
1859
  throw e;
1693
1860
  }
1694
- 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}.`;
1861
+ 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}.`;
1695
1862
  return routerResponse;
1696
1863
  }
1697
1864
  routerResponse.itineraries = remoteRouterResponse.itineraries.map(
@@ -1709,7 +1876,7 @@ class WemapMultiRouter {
1709
1876
  try {
1710
1877
  ioMapItinerary = mapWithEnd.getBestItineraryFromEntryPointsToEnd(start, end, wemapOsmRouterOptions);
1711
1878
  remoteRouterResponse = await RemoteRouterManager$1.getItinerariesWithFallback(
1712
- remoteRouters,
1879
+ remoteRouters2,
1713
1880
  mode,
1714
1881
  [start, ioMapItinerary.from]
1715
1882
  );
@@ -1720,7 +1887,7 @@ class WemapMultiRouter {
1720
1887
  if (!isRoutingError(e)) {
1721
1888
  throw e;
1722
1889
  }
1723
- 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}.`;
1890
+ 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}.`;
1724
1891
  return routerResponse;
1725
1892
  }
1726
1893
  routerResponse.itineraries = remoteRouterResponse.itineraries.map(
@@ -1747,7 +1914,7 @@ class WemapMultiRouter {
1747
1914
  ioMapItinerary1 = mapWithStart.getBestItineraryFromStartToEntryPoints(start, end, wemapOsmRouterOptions);
1748
1915
  ioMapItinerary2 = mapWithEnd.getBestItineraryFromEntryPointsToEnd(start, end, wemapOsmRouterOptions);
1749
1916
  remoteRouterResponse = await RemoteRouterManager$1.getItinerariesWithFallback(
1750
- remoteRouters,
1917
+ remoteRouters2,
1751
1918
  mode,
1752
1919
  [ioMapItinerary1.to, ioMapItinerary2.from]
1753
1920
  );
@@ -1758,7 +1925,7 @@ class WemapMultiRouter {
1758
1925
  if (!isRoutingError(e)) {
1759
1926
  throw e;
1760
1927
  }
1761
- 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}.`;
1928
+ 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}.`;
1762
1929
  return routerResponse;
1763
1930
  }
1764
1931
  routerResponse.itineraries = remoteRouterResponse.itineraries.map(
@@ -1775,18 +1942,18 @@ class WemapMultiRouter {
1775
1942
  }
1776
1943
  }
1777
1944
  class CustomNetworkMap {
1778
- constructor(network, entryPoints, bounds = null, name = null) {
1945
+ constructor(graph, entryPoints, bounds = null, name = null) {
1779
1946
  __publicField(this, "name");
1780
- __publicField(this, "network");
1947
+ __publicField(this, "graph");
1781
1948
  __publicField(this, "router");
1782
1949
  __publicField(this, "bounds");
1783
1950
  __publicField(this, "entryPoints");
1784
1951
  __publicField(this, "disabledWays", /* @__PURE__ */ new Set());
1785
1952
  this.name = name;
1786
- this.network = network;
1787
- this.router = new WemapOsmRouter(network);
1953
+ this.graph = graph;
1954
+ this.router = new WemapOsmRouter(graph);
1788
1955
  entryPoints.forEach((entryPoint) => {
1789
- if (!network.nodes.includes(entryPoint)) {
1956
+ if (!graph.vertices.includes(entryPoint)) {
1790
1957
  throw new Error(`Cannot find entry point ${entryPoint.coords.toString()} in network "${name}"`);
1791
1958
  }
1792
1959
  });
@@ -1794,7 +1961,7 @@ class CustomNetworkMap {
1794
1961
  if (bounds) {
1795
1962
  this.bounds = bounds;
1796
1963
  } else {
1797
- const polygon = [network.nodes.map((node) => [node.coords.lng, node.coords.lat])];
1964
+ const polygon = [graph.vertices.map((vertex) => [vertex.coords.lng, vertex.coords.lat])];
1798
1965
  const convexHull = convexHullFn__default.default({ type: "polygon", coordinates: polygon });
1799
1966
  if (!convexHull) {
1800
1967
  throw new Error(`Cannot calculate convexHull of network "${name}"`);
@@ -1807,8 +1974,8 @@ class CustomNetworkMap {
1807
1974
  }
1808
1975
  static fromOsmXml(osmXmlString, name = null) {
1809
1976
  const osmModel = osm.OsmParser.parseOsmXmlString(osmXmlString);
1810
- const network = osm.OsmNetworkUtils.createNetworkFromOsmModel(osmModel);
1811
- const entryPoints = osmModel.nodes.filter(({ tags }) => tags && tags["wemap:routing-io"]).map((osmNode) => network.getNodeByCoords(osmNode.coords));
1977
+ const graph = OsmGraph.fromOsmModel(osmModel);
1978
+ const entryPoints = graph.vertices.filter(({ data: { tags } }) => tags && tags["wemap:routing-io"]);
1812
1979
  if (entryPoints.some((el) => el === null) || new Set(entryPoints).size !== entryPoints.length) {
1813
1980
  throw new Error("Cannot parse wemap:routing-io correctly");
1814
1981
  }
@@ -1831,7 +1998,7 @@ class CustomNetworkMap {
1831
1998
  if (!bounds.coordinates.length) {
1832
1999
  throw new Error('Search bounds is undefined. Please use OSM tag : "wemap:routing-bounds=yes"');
1833
2000
  }
1834
- return new CustomNetworkMap(network, entryPoints, bounds, name);
2001
+ return new CustomNetworkMap(graph, entryPoints, bounds, name);
1835
2002
  }
1836
2003
  isPointInside(coordinates) {
1837
2004
  return pointInPolygon__default.default([coordinates.lng, coordinates.lat], this.bounds);
@@ -1874,44 +2041,18 @@ class CustomNetworkMap {
1874
2041
  return this.router.getItinerary(start, end, options);
1875
2042
  }
1876
2043
  enableWay(osmId) {
1877
- this.network.edges.filter((edge) => {
1878
- var _a;
1879
- return ((_a = edge.builtFrom) == null ? void 0 : _a.id) === osmId;
1880
- }).forEach((e) => this.router.disabledEdges.delete(e));
2044
+ this.graph.edges.filter((edge) => edge.data.id === osmId).forEach((e) => this.router.disabledEdges.delete(e));
1881
2045
  this.disabledWays.delete(osmId);
1882
2046
  }
1883
2047
  disableWay(osmId) {
1884
- this.network.edges.filter((edge) => {
1885
- var _a;
1886
- return ((_a = edge.builtFrom) == null ? void 0 : _a.id) === osmId;
1887
- }).forEach((e) => this.router.disabledEdges.add(e));
2048
+ this.graph.edges.filter((edge) => edge.data.id === osmId).forEach((e) => this.router.disabledEdges.add(e));
1888
2049
  this.disabledWays.add(osmId);
1889
2050
  }
1890
2051
  }
1891
- function getTurnInfoFromAngle(_angle) {
1892
- let direction, directionExtra;
1893
- const directionAngle = maths.rad2deg(maths.diffAngle(_angle, Math.PI));
1894
- const directionAngleAbs = Math.abs(directionAngle);
1895
- if (directionAngleAbs <= 20) {
1896
- direction = "straight";
1897
- } else {
1898
- direction = directionAngle > 0 ? "left" : "right";
1899
- if (directionAngleAbs < 55) {
1900
- directionExtra = "slight";
1901
- } else if (directionAngleAbs > 120) {
1902
- directionExtra = "sharp";
1903
- }
1904
- }
1905
- return { direction, directionExtra };
1906
- }
1907
- const WemapOsmRouterUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1908
- __proto__: null,
1909
- getTurnInfoFromAngle
1910
- }, Symbol.toStringTag, { value: "Module" }));
1911
2052
  class ItineraryInfoManager {
1912
2053
  constructor(itinerary = null) {
1913
2054
  __publicField(this, "_itinerary", null);
1914
- __publicField(this, "_mapMatching", null);
2055
+ __publicField(this, "_geoGraphProjectionHandler", null);
1915
2056
  __publicField(this, "_steps", []);
1916
2057
  __publicField(this, "_coordsNextStep", []);
1917
2058
  __publicField(this, "_coordsPreviousStep", []);
@@ -1929,8 +2070,8 @@ class ItineraryInfoManager {
1929
2070
  }
1930
2071
  this._itinerary = itinerary;
1931
2072
  this._steps = itinerary.steps;
1932
- const network = itinerary.toNetwork();
1933
- this._mapMatching = new geo.MapMatching(network);
2073
+ const graph = itinerary.toGraph();
2074
+ this._geoGraphProjectionHandler = new geo.GeoGraphProjectionHandler(graph);
1934
2075
  this._coordsNextStep = new Array(itinerary.coords.length);
1935
2076
  this._coordsPreviousStep = new Array(itinerary.coords.length);
1936
2077
  this._coordsDistanceTraveled = new Array(itinerary.coords.length);
@@ -1955,15 +2096,15 @@ class ItineraryInfoManager {
1955
2096
  });
1956
2097
  }
1957
2098
  getInfo(position) {
1958
- if (!this._itinerary || !this._mapMatching) {
2099
+ if (!this._itinerary || !this._geoGraphProjectionHandler) {
1959
2100
  return null;
1960
2101
  }
1961
- const projection = this._mapMatching.getProjection(position);
2102
+ const projection = this._geoGraphProjectionHandler.getProjection(position);
1962
2103
  if (!projection) {
1963
2104
  return null;
1964
2105
  }
1965
2106
  let itineraryInfo = null;
1966
- if (projection.nearestElement instanceof geo.GraphNode) {
2107
+ if (projection.nearestElement instanceof geo.GeoGraphVertex) {
1967
2108
  const idx = this._itinerary.coords.findIndex(
1968
2109
  (coords) => projection.nearestElement.coords === coords
1969
2110
  );
@@ -1982,14 +2123,14 @@ class ItineraryInfoManager {
1982
2123
  traveledPercentage: traveledDistance / this._itinerary.distance,
1983
2124
  remainingPercentage: remainingDistance / this._itinerary.distance
1984
2125
  };
1985
- } else if (projection.nearestElement instanceof geo.GraphEdge) {
1986
- let firstNode = projection.nearestElement.node1.coords;
2126
+ } else if (projection.nearestElement instanceof geo.GeoGraphEdge) {
2127
+ let firstNode = projection.nearestElement.vertex1.coords;
1987
2128
  let idx = this._itinerary.coords.findIndex((coords) => firstNode === coords);
1988
2129
  if (idx === -1) {
1989
2130
  throw new Error("ItineraryInfoManager: could not find projection in itinerary (Edge)");
1990
2131
  }
1991
- if (idx === this._itinerary.coords.length - 1 || this._itinerary.coords[idx + 1] !== projection.nearestElement.node2.coords) {
1992
- firstNode = projection.nearestElement.node2.coords;
2132
+ if (idx === this._itinerary.coords.length - 1 || this._itinerary.coords[idx + 1] !== projection.nearestElement.vertex2.coords) {
2133
+ firstNode = projection.nearestElement.vertex2.coords;
1993
2134
  idx--;
1994
2135
  }
1995
2136
  const traveledDistance = this._coordsDistanceTraveled[idx] + projection.coords.distanceTo(firstNode);
@@ -2015,17 +2156,15 @@ exports.IdfmRemoteRouter = IdfmRemoteRouter$1;
2015
2156
  exports.Itinerary = Itinerary;
2016
2157
  exports.ItineraryInfoManager = ItineraryInfoManager;
2017
2158
  exports.Leg = Leg;
2159
+ exports.OsmGraph = OsmGraph;
2160
+ exports.OsmRouter = WemapOsmRouter;
2018
2161
  exports.OsrmRemoteRouter = OsrmRemoteRouter$1;
2019
2162
  exports.OtpRemoteRouter = OtpRemoteRouter$1;
2020
2163
  exports.RemoteRouterManager = RemoteRouterManager$1;
2021
2164
  exports.RemoteRouterServerUnreachable = RemoteRouterServerUnreachable;
2022
2165
  exports.RouterResponse = RouterResponse;
2023
- exports.StepInfo = StepInfo;
2024
2166
  exports.WemapMultiRemoteRouter = WemapMultiRemoteRouter$1;
2025
2167
  exports.WemapMultiRemoteRouterPayload = WemapMultiRemoteRouterPayload;
2026
2168
  exports.WemapMultiRouter = WemapMultiRouter;
2027
- exports.WemapOsmRouter = WemapOsmRouter;
2028
- exports.WemapOsmRouterOptions = WemapOsmRouterOptions;
2029
- exports.WemapOsmRouterUtils = WemapOsmRouterUtils;
2030
2169
  exports.getDurationFromLength = getDurationFromLength;
2031
2170
  //# sourceMappingURL=index.js.map