@wemap/routers 11.0.0-alpha.2 → 11.0.0-alpha.20

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 (37) hide show
  1. package/dist/index.js +543 -362
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +2164 -0
  4. package/dist/index.mjs.map +1 -0
  5. package/index.ts +7 -9
  6. package/package.json +14 -7
  7. package/src/ItineraryInfoManager.spec.ts +14 -14
  8. package/src/ItineraryInfoManager.ts +13 -13
  9. package/src/model/Itinerary.spec.ts +16 -12
  10. package/src/model/Itinerary.ts +69 -73
  11. package/src/model/Leg.spec.ts +8 -8
  12. package/src/model/Leg.ts +78 -33
  13. package/src/model/Step.spec.ts +99 -0
  14. package/src/model/Step.ts +77 -14
  15. package/src/model/generateSteps.ts +20 -12
  16. package/src/remote/RemoteRouterManager.ts +17 -15
  17. package/src/remote/cityway/CitywayRemoteRouter.ts +10 -11
  18. package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.ts +1 -3
  19. package/src/remote/idfm/IdfmRemoteRouter.ts +30 -30
  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/remote/wemap-multi/WemapMultiRemoteRouterPayload.ts +3 -3
  24. package/src/wemap-multi/CustomNetworkMap.ts +51 -32
  25. package/src/wemap-multi/WemapMultiRouter.ts +8 -9
  26. package/src/wemap-multi/WemapMultiRouterOptions.ts +3 -1
  27. package/src/wemap-osm/OsmGraph.spec.ts +99 -0
  28. package/src/wemap-osm/OsmGraph.ts +169 -0
  29. package/src/wemap-osm/{WemapOsmRouter.spec.ts → OsmRouter.spec.ts} +94 -35
  30. package/src/wemap-osm/OsmRouter.ts +201 -0
  31. package/vite.config.ts +1 -1
  32. package/src/model/ItineraryInfo.ts +0 -19
  33. package/src/model/StepInfo.spec.ts +0 -78
  34. package/src/model/StepInfo.ts +0 -78
  35. package/src/wemap-osm/WemapOsmRouter.ts +0 -82
  36. package/src/wemap-osm/WemapOsmRouterOptions.ts +0 -23
  37. package/src/wemap-osm/WemapOsmRouterUtils.ts +0 -21
package/dist/index.js CHANGED
@@ -1,68 +1,29 @@
1
+ "use strict";
1
2
  var __defProp = Object.defineProperty;
2
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
4
  var __publicField = (obj, key, value) => {
4
5
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
6
  return value;
6
7
  };
7
- import { Coordinates, Level, Utils, Network, GraphRouterOptions, GraphRouter, GraphUtils, NoRouteFoundError, MapMatching, GraphNode, GraphEdge } from "@wemap/geo";
8
- import { deg2rad, diffAngle, positiveMod, rad2deg } from "@wemap/maths";
9
- import { OsmNode, OsmWay, OsmParser, OsmNetworkUtils } from "@wemap/osm";
10
- import Logger from "@wemap/logger";
11
- import Polyline from "@mapbox/polyline";
12
- import pointInPolygon from "@turf/boolean-point-in-polygon";
13
- import convexHullFn from "@turf/convex";
14
- import { polygon } from "@turf/helpers";
8
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
9
+ const geo = require("@wemap/geo");
10
+ const maths = require("@wemap/maths");
11
+ const salesman = require("@wemap/salesman.js");
12
+ const osm = require("@wemap/osm");
13
+ const Logger = require("@wemap/logger");
14
+ const Polyline = require("@mapbox/polyline");
15
+ const pointInPolygon = require("@turf/boolean-point-in-polygon");
16
+ const convexHullFn = require("@turf/convex");
17
+ const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
18
+ const salesman__default = /* @__PURE__ */ _interopDefaultLegacy(salesman);
19
+ const Logger__default = /* @__PURE__ */ _interopDefaultLegacy(Logger);
20
+ const Polyline__default = /* @__PURE__ */ _interopDefaultLegacy(Polyline);
21
+ const pointInPolygon__default = /* @__PURE__ */ _interopDefaultLegacy(pointInPolygon);
22
+ const convexHullFn__default = /* @__PURE__ */ _interopDefaultLegacy(convexHullFn);
15
23
  function getDurationFromLength(length, speed = 5) {
16
24
  return length / (speed * 1e3 / 3600);
17
25
  }
18
- function areLevelChangeEquals(l1, l2) {
19
- return l1 === l2 || l1.difference === l2.difference && l1.direction === l2.direction && l1.type === l2.type;
20
- }
21
- class StepInfo {
22
- constructor({
23
- coords,
24
- distance,
25
- name,
26
- levelChange,
27
- extras,
28
- duration
29
- }) {
30
- __publicField(this, "coords");
31
- __publicField(this, "name");
32
- __publicField(this, "distance");
33
- __publicField(this, "duration");
34
- __publicField(this, "levelChange");
35
- __publicField(this, "extras");
36
- this.coords = coords;
37
- this.name = name || null;
38
- this.distance = typeof distance === "number" ? distance : null;
39
- this.duration = typeof duration === "number" ? duration : null;
40
- this.levelChange = levelChange || null;
41
- this.extras = extras || null;
42
- }
43
- static equals(obj1, obj2) {
44
- 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));
45
- }
46
- equals(obj) {
47
- return StepInfo.equals(this, obj);
48
- }
49
- toJson() {
50
- return {
51
- coords: this.coords.toCompressedJson(),
52
- ...this.distance !== null && { distance: this.distance },
53
- ...this.duration !== null && { duration: this.duration },
54
- ...this.name !== null && { name: this.name },
55
- ...this.levelChange !== null && { levelChange: this.levelChange },
56
- ...this.extras && Object.keys(this.extras).length !== 0 && { extras: this.extras }
57
- };
58
- }
59
- static fromJson(json) {
60
- return new StepInfo(Object.assign({}, json, {
61
- coords: Coordinates.fromCompressedJson(json.coords)
62
- }));
63
- }
64
- }
65
- const SKIP_STEP_ANGLE_MAX = deg2rad(20);
26
+ const SKIP_STEP_ANGLE_MAX = maths.deg2rad(20);
66
27
  function generateSteps(leg, rules) {
67
28
  const steps = [];
68
29
  const { from, to, coords: coordsArray } = leg;
@@ -72,32 +33,36 @@ function generateSteps(leg, rules) {
72
33
  const isFirstStep = i === 0;
73
34
  const currentCoords = coordsArray[i];
74
35
  const nextCoords = coordsArray[i + 1];
75
- const edgeLevel = Level.union(currentCoords.level, nextCoords.level);
36
+ const edgeLevel = geo.Level.union(currentCoords.level, nextCoords.level);
76
37
  const nextBearing = currentCoords.bearingTo(nextCoords);
77
- const angle = diffAngle(previousBearing, nextBearing + Math.PI);
78
- let splitByAngle = Math.abs(diffAngle(Math.PI, angle)) >= SKIP_STEP_ANGLE_MAX;
79
- const splitByLevel = Level.isRange(edgeLevel) && !Level.isRange(currentCoords.level);
80
- splitByAngle = splitByAngle && !(currentCoords.level && Level.isRange(currentCoords.level));
81
- const customRules = rules == null ? void 0 : rules(currentCoords, nextCoords);
38
+ const angle = maths.diffAngle(previousBearing, nextBearing + Math.PI);
39
+ let splitByAngle = Math.abs(maths.diffAngle(Math.PI, angle)) >= SKIP_STEP_ANGLE_MAX;
40
+ const splitByLevel = geo.Level.isRange(edgeLevel) && !geo.Level.isRange(currentCoords.level);
41
+ splitByAngle = splitByAngle && !(currentCoords.level && geo.Level.isRange(currentCoords.level));
42
+ const previousStep = steps.length ? steps[steps.length - 1] : null;
43
+ const customRules = rules == null ? void 0 : rules(currentCoords, nextCoords, previousStep);
82
44
  const splitStepCondition = splitByAngle || splitByLevel || (customRules == null ? void 0 : customRules.createNewStep);
83
45
  if (isFirstStep || splitStepCondition) {
84
46
  let levelChange;
85
- if (splitByLevel) {
86
- const difference = Level.diff(currentCoords.level, nextCoords.level);
87
- 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
+ }
88
53
  levelChange = { difference, direction, type: customRules == null ? void 0 : customRules.levelChangeType };
89
54
  }
90
55
  if (currentStep && currentStep.duration === 0) {
91
- currentStep.duration = null;
56
+ delete currentStep.duration;
92
57
  }
93
- currentStep = new StepInfo({
58
+ currentStep = {
94
59
  coords: currentCoords,
95
60
  name: customRules == null ? void 0 : customRules.stepName,
96
61
  extras: customRules == null ? void 0 : customRules.stepExtras,
97
62
  levelChange,
98
63
  distance: 0,
99
64
  duration: 0
100
- });
65
+ };
101
66
  steps.push(currentStep);
102
67
  }
103
68
  currentStep.distance += currentCoords.distanceTo(nextCoords);
@@ -107,8 +72,8 @@ function generateSteps(leg, rules) {
107
72
  previousBearing = nextBearing;
108
73
  }
109
74
  const lastCoords = coordsArray[coordsArray.length - 1];
110
- if (!Coordinates.equals(lastCoords, to.coords)) {
111
- steps.push(new StepInfo({ coords: lastCoords }));
75
+ if (!geo.Coordinates.equals(lastCoords, to.coords)) {
76
+ steps.push({ coords: lastCoords });
112
77
  }
113
78
  return steps;
114
79
  }
@@ -124,6 +89,36 @@ function isRoutingModePublicTransport(routingMode) {
124
89
  "TRAM"
125
90
  ].includes(routingMode);
126
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
+ }
127
122
  class Leg {
128
123
  constructor({
129
124
  from,
@@ -144,7 +139,7 @@ class Leg {
144
139
  __publicField(this, "duration");
145
140
  __publicField(this, "startTime");
146
141
  __publicField(this, "endTime");
147
- __publicField(this, "stepsInfo");
142
+ __publicField(this, "steps");
148
143
  __publicField(this, "transportInfo");
149
144
  this.from = {
150
145
  name: from.name || null,
@@ -156,22 +151,27 @@ class Leg {
156
151
  };
157
152
  this.coords = coords;
158
153
  this.mode = mode;
159
- this.distance = Utils.calcDistance(coords);
154
+ this.distance = geo.Utils.calcDistance(coords);
160
155
  this.duration = typeof duration === "number" ? duration : getDurationFromLength(this.distance);
161
156
  this.startTime = typeof startTime === "number" ? startTime : null;
162
157
  this.endTime = typeof endTime === "number" ? endTime : null;
163
158
  this.transportInfo = transportInfo || null;
164
- 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);
165
165
  }
166
166
  isPublicTransport() {
167
167
  return isRoutingModePublicTransport(this.mode);
168
168
  }
169
- toNetwork() {
170
- return Network.fromCoordinates([this.coords]);
169
+ toGraph() {
170
+ return geo.GeoGraph.fromCoordinates([this.coords]);
171
171
  }
172
172
  static equals(obj1, obj2) {
173
173
  var _a, _b;
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.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));
175
175
  if (!intermediate) {
176
176
  return false;
177
177
  }
@@ -181,11 +181,9 @@ class Leg {
181
181
  return false;
182
182
  }
183
183
  }
184
- if (obj1.stepsInfo && obj2.stepsInfo) {
185
- for (i = 0; i < obj1.stepsInfo.length; i++) {
186
- if (!obj1.stepsInfo[i].equals(obj2.stepsInfo[i])) {
187
- return false;
188
- }
184
+ for (i = 0; i < obj1.steps.length; i++) {
185
+ if (!stepEquals(obj1.steps[i], obj2.steps[i])) {
186
+ return false;
189
187
  }
190
188
  }
191
189
  if (obj1.transportInfo !== obj2.transportInfo) {
@@ -212,9 +210,9 @@ class Leg {
212
210
  coords: this.to.coords.toCompressedJson(),
213
211
  ...this.to.name && { name: this.to.name }
214
212
  },
215
- duration: this.duration,
213
+ duration: Number(this.duration.toFixed(1)),
216
214
  coords: this.coords.map((coords) => coords.toCompressedJson()),
217
- steps: this.stepsInfo.map((stepInfo) => stepInfo.toJson()),
215
+ steps: this.steps.map(stepToJson),
218
216
  ...this.startTime !== null && { startTime: this.startTime },
219
217
  ...this.endTime !== null && { endTime: this.endTime },
220
218
  ...this.transportInfo !== null && { transportInfo: this.transportInfo }
@@ -224,16 +222,15 @@ class Leg {
224
222
  var _a;
225
223
  const leg = new Leg(Object.assign({}, json, {
226
224
  from: {
227
- coords: Coordinates.fromCompressedJson(json.from.coords),
225
+ coords: geo.Coordinates.fromCompressedJson(json.from.coords),
228
226
  name: json.from.name || null
229
227
  },
230
228
  to: {
231
- coords: Coordinates.fromCompressedJson(json.to.coords),
229
+ coords: geo.Coordinates.fromCompressedJson(json.to.coords),
232
230
  name: json.to.name || null
233
231
  },
234
- coords: json.coords.map(Coordinates.fromCompressedJson),
235
- stepsInfo: ((_a = json.steps) == null ? void 0 : _a.map(StepInfo.fromJson)) || null,
236
- stepsGenerationRules: void 0
232
+ coords: json.coords.map(geo.Coordinates.fromCompressedJson),
233
+ steps: ((_a = json.steps) == null ? void 0 : _a.map(jsonToStep)) || null
237
234
  }));
238
235
  return leg;
239
236
  }
@@ -241,24 +238,57 @@ class Leg {
241
238
  return new Leg({
242
239
  from: { coords: graphItinerary.start },
243
240
  to: { coords: graphItinerary.end },
244
- coords: graphItinerary.nodes.map((node) => node.coords),
241
+ coords: graphItinerary.vertices.map((vertex) => vertex.coords),
245
242
  duration: graphItinerary.edgesWeights.reduce((acc, weight) => acc + weight, 0),
246
243
  mode,
247
244
  stepsGenerationRules
248
245
  });
249
246
  }
250
247
  multiplyLevel(levelFactor) {
251
- this.from.coords.level = Level.multiplyBy(this.from.coords.level, levelFactor);
252
- this.to.coords.level = Level.multiplyBy(this.to.coords.level, levelFactor);
248
+ this.from.coords.level = geo.Level.multiplyBy(this.from.coords.level, levelFactor);
249
+ this.to.coords.level = geo.Level.multiplyBy(this.to.coords.level, levelFactor);
253
250
  for (const coords of this.coords) {
254
- coords.level = Level.multiplyBy(coords.level, levelFactor);
251
+ coords.level = geo.Level.multiplyBy(coords.level, levelFactor);
255
252
  }
256
- this.stepsInfo.forEach((step) => {
257
- step.coords.level = Level.multiplyBy(step.coords.level, levelFactor);
253
+ this.steps.forEach((step) => {
254
+ step.coords.level = geo.Level.multiplyBy(step.coords.level, levelFactor);
258
255
  });
259
256
  }
260
- getSteps(itinerarySteps) {
261
- 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
+ });
262
292
  }
263
293
  }
264
294
  class Itinerary {
@@ -278,7 +308,6 @@ class Itinerary {
278
308
  __publicField(this, "startTime");
279
309
  __publicField(this, "endTime");
280
310
  __publicField(this, "_coords", null);
281
- __publicField(this, "_steps", null);
282
311
  __publicField(this, "_distance", null);
283
312
  this.from = from;
284
313
  this.to = to;
@@ -286,6 +315,7 @@ class Itinerary {
286
315
  this.duration = typeof duration === "number" ? duration : this.legs.reduce((dur, leg) => dur + leg.duration, 0);
287
316
  this.startTime = typeof startTime === "number" ? startTime : null;
288
317
  this.endTime = typeof endTime === "number" ? endTime : null;
318
+ this.updateStepsFromLegs();
289
319
  }
290
320
  set coords(_) {
291
321
  throw new Error("Itinerary.coords cannot be set. They are calculated from Itinerary.legs.");
@@ -300,49 +330,7 @@ class Itinerary {
300
330
  throw new Error("Itinerary.step cannot be set. They are calculated from Itinerary.legs.");
301
331
  }
302
332
  get steps() {
303
- if (this._steps) {
304
- return this._steps;
305
- }
306
- const itineraryCoords = this.coords.filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));
307
- const stepsInfo = this.legs.map((leg) => leg.stepsInfo).flat();
308
- const steps = stepsInfo.map((stepInfo, stepId) => {
309
- const coordsId = itineraryCoords.findIndex((coords) => coords.equals(stepInfo.coords));
310
- if (coordsId === -1) {
311
- throw new Error("Cannot find step coordinates in itinerary coordinates.");
312
- }
313
- const coordsBeforeStep = coordsId === 0 ? this.from : itineraryCoords[coordsId - 1];
314
- const coordsAfterStep = coordsId === itineraryCoords.length - 1 ? this.to : itineraryCoords[coordsId + 1];
315
- const previousBearing = coordsBeforeStep.bearingTo(stepInfo.coords);
316
- const nextBearing = stepInfo.coords.bearingTo(coordsAfterStep);
317
- let distance = 0;
318
- const coordsToStopCalculation = stepId !== stepsInfo.length - 1 ? stepsInfo[stepId + 1].coords : itineraryCoords[itineraryCoords.length - 1];
319
- let currentCoordsId = coordsId;
320
- while (!itineraryCoords[currentCoordsId].equals(coordsToStopCalculation)) {
321
- distance += itineraryCoords[currentCoordsId].distanceTo(itineraryCoords[currentCoordsId + 1]);
322
- currentCoordsId++;
323
- }
324
- if (currentCoordsId === itineraryCoords.length - 1) {
325
- distance += itineraryCoords[currentCoordsId].distanceTo(this.to);
326
- }
327
- return {
328
- ...stepInfo,
329
- number: stepId + 1,
330
- previousBearing,
331
- nextBearing,
332
- angle: diffAngle(previousBearing, nextBearing + Math.PI),
333
- firstStep: stepId === 0,
334
- lastStep: stepId === stepsInfo.length - 1,
335
- distance,
336
- duration: stepInfo.duration || getDurationFromLength(distance),
337
- previousStep: null,
338
- nextStep: null
339
- };
340
- });
341
- for (let i = 0; i < steps.length; i++) {
342
- steps[i].previousStep = i !== 0 ? steps[i - 1] : null;
343
- steps[i].nextStep = i !== steps.length - 1 ? steps[i + 1] : null;
344
- }
345
- return steps;
333
+ return this.legs.map((leg) => leg.steps).flat();
346
334
  }
347
335
  set mode(_) {
348
336
  throw new Error("Itinerary.mode cannot be set. They are calculated from Itinerary.legs.");
@@ -374,12 +362,12 @@ class Itinerary {
374
362
  }
375
363
  get distance() {
376
364
  if (this._distance === null) {
377
- this._distance = Utils.calcDistance(this.coords);
365
+ this._distance = geo.Utils.calcDistance(this.coords);
378
366
  }
379
367
  return this._distance;
380
368
  }
381
- toNetwork() {
382
- return Network.fromCoordinates([this.coords]);
369
+ toGraph() {
370
+ return geo.GeoGraph.fromCoordinates([this.coords]);
383
371
  }
384
372
  static fromItineraries(...itineraries) {
385
373
  let duration = 0;
@@ -396,7 +384,7 @@ class Itinerary {
396
384
  });
397
385
  }
398
386
  static fromOrderedPointsArray(points, start, end) {
399
- const pointToCoordinates = (point) => new Coordinates(point[0], point[1], null, point[2]);
387
+ const pointToCoordinates = (point) => new geo.Coordinates(point[0], point[1], null, point[2]);
400
388
  return this.fromOrderedCoordinates(
401
389
  points.map(pointToCoordinates),
402
390
  pointToCoordinates(start),
@@ -413,7 +401,7 @@ class Itinerary {
413
401
  return new Itinerary({ from, to, legs: [leg] });
414
402
  }
415
403
  static equals(obj1, obj2) {
416
- 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;
417
405
  if (!intermediate) {
418
406
  return false;
419
407
  }
@@ -440,8 +428,8 @@ class Itinerary {
440
428
  }
441
429
  static fromJson(json) {
442
430
  return new Itinerary({
443
- from: Coordinates.fromCompressedJson(json.from),
444
- to: Coordinates.fromCompressedJson(json.to),
431
+ from: geo.Coordinates.fromCompressedJson(json.from),
432
+ to: geo.Coordinates.fromCompressedJson(json.to),
445
433
  duration: json.duration,
446
434
  legs: json.legs.map(Leg.fromJson),
447
435
  startTime: json.startTime,
@@ -458,8 +446,8 @@ class Itinerary {
458
446
  });
459
447
  }
460
448
  multiplyLevel(levelFactor) {
461
- this.from.level = Level.multiplyBy(this.from.level, levelFactor);
462
- this.to.level = Level.multiplyBy(this.to.level, levelFactor);
449
+ this.from.level = geo.Level.multiplyBy(this.from.level, levelFactor);
450
+ this.to.level = geo.Level.multiplyBy(this.to.level, levelFactor);
463
451
  this.legs.forEach((leg) => leg.multiplyLevel(levelFactor));
464
452
  }
465
453
  forceUnknownLevelTo0() {
@@ -471,8 +459,8 @@ class Itinerary {
471
459
  for (const coords of leg.coords) {
472
460
  coords.level = coords.level || 0;
473
461
  }
474
- if (leg.stepsInfo) {
475
- for (const step of leg.stepsInfo) {
462
+ if (leg.steps) {
463
+ for (const step of leg.steps) {
476
464
  step.coords.level = step.coords.level || 0;
477
465
  }
478
466
  }
@@ -493,6 +481,36 @@ class Itinerary {
493
481
  }
494
482
  };
495
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
+ }
496
514
  }
497
515
  class RouterResponse {
498
516
  constructor({
@@ -541,85 +559,260 @@ class RouterResponse {
541
559
  var _a;
542
560
  return new RouterResponse({
543
561
  routerName: json.routerName,
544
- from: Coordinates.fromCompressedJson(json.from),
545
- to: Coordinates.fromCompressedJson(json.to),
562
+ from: geo.Coordinates.fromCompressedJson(json.from),
563
+ to: geo.Coordinates.fromCompressedJson(json.to),
546
564
  itineraries: (_a = json.itineraries) == null ? void 0 : _a.map(Itinerary.fromJson),
547
565
  error: json.error
548
566
  });
549
567
  }
550
568
  multiplyLevel(levelFactor) {
551
- this.from.level = Level.multiplyBy(this.from.level, levelFactor);
552
- this.to.level = Level.multiplyBy(this.to.level, levelFactor);
569
+ this.from.level = geo.Level.multiplyBy(this.from.level, levelFactor);
570
+ this.to.level = geo.Level.multiplyBy(this.to.level, levelFactor);
553
571
  for (const itinerary of this.itineraries) {
554
572
  itinerary.multiplyLevel(levelFactor);
555
573
  }
556
574
  }
557
575
  }
558
- const _WemapOsmRouterOptions = class extends GraphRouterOptions {
559
- constructor() {
560
- super(...arguments);
561
- __publicField(this, "weightEdgeFn", (edge) => edge.builtFrom instanceof OsmNode && edge.builtFrom.isElevator ? 30 : getDurationFromLength(edge.length));
562
- }
563
- static get WITHOUT_STAIRS() {
564
- const options = new _WemapOsmRouterOptions();
565
- options.acceptEdgeFn = (edge) => {
566
- var _a;
567
- 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;
568
652
  };
569
- 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
+ }
570
686
  }
571
- };
572
- let WemapOsmRouterOptions = _WemapOsmRouterOptions;
573
- __publicField(WemapOsmRouterOptions, "DEFAULT", new _WemapOsmRouterOptions());
574
- const buildStepsRules = (graphItinerary) => (currentCoords, nextCoords) => {
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
+ });
694
+ const buildStepsRules = (graphItinerary) => (currentCoords, nextCoords, previousStep) => {
575
695
  var _a, _b, _c, _d, _e;
576
696
  const edges = graphItinerary.edges;
577
- const nodes = graphItinerary.nodes;
578
- const node = GraphUtils.getNodeByCoords(nodes, currentCoords);
579
- const nextNode = GraphUtils.getNodeByCoords(nodes, nextCoords);
580
- 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)
581
701
  return {};
582
- const edge = GraphUtils.getEdgeByNodes(edges, node, nextNode);
702
+ const edge = geo.GeoGraphEdge.getEdgeByVertices(edges, vertex, nextVertex);
583
703
  if (!edge)
584
704
  return {};
585
705
  const edgeId = edges.findIndex((_edge) => _edge === edge);
586
- const isSubwayEntrance = node ? ((_a = node.builtFrom) == null ? void 0 : _a.tags.railway) === "subway_entrance" : false;
587
- 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;
588
708
  let levelChangeType = null;
589
- if (edge.builtFrom instanceof OsmNode && edge.builtFrom.isElevator) {
709
+ if (edge.data.isElevator) {
590
710
  levelChangeType = "elevator";
591
- } else if (edge.builtFrom instanceof OsmNode || edge.builtFrom instanceof OsmWay && edge.builtFrom.isConveying) {
711
+ } else if (edge.data.isConveying) {
592
712
  levelChangeType = "conveyor";
593
- } else if (edge.builtFrom instanceof OsmWay && edge.builtFrom.areStairs) {
713
+ } else if (edge.data instanceof osm.OsmWay && edge.data.areStairs) {
594
714
  levelChangeType = "stairs";
595
715
  }
716
+ const edgeTags = edge.data.tags || {};
717
+ let levelChangeDirection = null;
718
+ if (edge.data instanceof osm.OsmWay && edge.data.areStairs && ["up", "down"].includes(edgeTags.incline) && !(previousStep == null ? void 0 : previousStep.levelChange)) {
719
+ levelChangeDirection = edgeTags.incline;
720
+ for (const n of edge.data.nodes) {
721
+ if (n !== vertex.data)
722
+ continue;
723
+ }
724
+ const isReversed = edge.data.nodes.reduce((acc, n, idx, arr) => {
725
+ if (n !== vertex.data)
726
+ return acc;
727
+ acc = !(idx + 1 < arr.length && arr[idx + 1] === nextVertex.data);
728
+ return acc;
729
+ }, null);
730
+ if (isReversed) {
731
+ levelChangeDirection = levelChangeDirection === "up" ? "down" : "up";
732
+ }
733
+ }
734
+ const createNewStep = isSubwayEntrance || levelChangeDirection;
596
735
  return {
597
- createNewStep: isSubwayEntrance,
598
- stepName: (_d = edge.builtFrom) == null ? void 0 : _d.tags.name,
736
+ createNewStep,
737
+ stepName: (_d = edge.data) == null ? void 0 : _d.tags.name,
599
738
  duration: graphItinerary.edgesWeights[edgeId],
600
739
  stepExtras: {
601
740
  ...isSubwayEntrance && { isSubwayEntrance: true },
602
- ...isSubwayEntrance && ((_e = node.builtFrom) == null ? void 0 : _e.tags.ref) && { subwayEntranceRef: node.builtFrom.tags.ref },
741
+ ...isSubwayEntrance && ((_e = vertex.data) == null ? void 0 : _e.tags.ref) && { subwayEntranceRef: vertex.data.tags.ref },
603
742
  ...isGate && { isGate: true }
604
743
  },
605
- ...levelChangeType && { levelChangeType }
744
+ ...levelChangeType && { levelChangeType },
745
+ ...levelChangeDirection && { levelChangeDirection }
606
746
  };
607
747
  };
608
- class WemapOsmRouter extends GraphRouter {
609
- constructor(network) {
610
- super(network);
748
+ class WemapOsmRouter extends geo.GeoGraphRouter {
749
+ constructor(graph) {
750
+ super(graph);
611
751
  }
612
752
  static get rname() {
613
- return "wemap";
753
+ return "wemap-osm";
614
754
  }
615
- getShortestPath(start, end, options = new WemapOsmRouterOptions()) {
755
+ getShortestPath(start, end, options = DEFAULT_OPTIONS) {
616
756
  return super.getShortestPath(start, end, options);
617
757
  }
618
- getItinerary(start, end, options = new WemapOsmRouterOptions()) {
758
+ getItinerary(start, end, options = DEFAULT_OPTIONS) {
619
759
  const graphItinerary = this.getShortestPath(start, end, options);
620
760
  return Itinerary.fromGraphItinerary(graphItinerary, "WALK", buildStepsRules(graphItinerary));
621
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
+ }
622
813
  }
814
+ __publicField(WemapOsmRouter, "DEFAULT_OPTIONS", DEFAULT_OPTIONS);
815
+ __publicField(WemapOsmRouter, "WITHOUT_STAIRS_OPTIONS", WITHOUT_STAIRS_OPTIONS);
623
816
  class RemoteRouter {
624
817
  }
625
818
  class RemoteRouterServerUnreachable extends Error {
@@ -643,10 +836,10 @@ function dateWithTimeZone(year, month, day, hour, minute, second, timeZone = "Eu
643
836
  return date;
644
837
  }
645
838
  function isRoutingError(e) {
646
- return e instanceof RemoteRouterServerUnreachable || e instanceof RoutingModeCorrespondanceNotFound || e instanceof NoRouteFoundError;
839
+ return e instanceof RemoteRouterServerUnreachable || e instanceof RoutingModeCorrespondanceNotFound || e instanceof geo.NoRouteFoundError;
647
840
  }
648
841
  function jsonToCoordinates$2(json) {
649
- return new Coordinates(json.Lat, json.Long);
842
+ return new geo.Coordinates(json.Lat, json.Long);
650
843
  }
651
844
  function jsonDateToTimestamp(jsonDate) {
652
845
  const [dateStr, timeStr] = jsonDate.split(" ");
@@ -711,11 +904,11 @@ function parseWKTGeometry(wktGeometry) {
711
904
  const tmpCoordsPt = wktGeometry.match(/POINT ?\((.*)\)/i);
712
905
  if (tmpCoordsPt) {
713
906
  const [lng, lat] = tmpCoordsPt[1].split(" ");
714
- return [new Coordinates(Number(lat), Number(lng))];
907
+ return [new geo.Coordinates(Number(lat), Number(lng))];
715
908
  }
716
909
  return tmpCoordsStr[1].split(",").map((str) => {
717
910
  const sp = str.trim().split(" ");
718
- return new Coordinates(Number(sp[1]), Number(sp[0]));
911
+ return new geo.Coordinates(Number(sp[1]), Number(sp[0]));
719
912
  });
720
913
  }
721
914
  class CitywayRemoteRouter extends RemoteRouter {
@@ -738,7 +931,7 @@ class CitywayRemoteRouter extends RemoteRouter {
738
931
  throw new RoutingModeCorrespondanceNotFound(this.rname, mode);
739
932
  }
740
933
  if (waypoints.length > 2) {
741
- Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints.length})`);
934
+ Logger__default.default.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints.length})`);
742
935
  }
743
936
  const fromPlace = `DepartureLatitude=${waypoints[0].latitude}&DepartureLongitude=${waypoints[0].longitude}`;
744
937
  const toPlace = `ArrivalLatitude=${waypoints[1].latitude}&ArrivalLongitude=${waypoints[1].longitude}`;
@@ -771,7 +964,7 @@ class CitywayRemoteRouter extends RemoteRouter {
771
964
  const legCoords = [];
772
965
  let legFrom, legTo;
773
966
  let transportInfo;
774
- let stepsInfo;
967
+ let minStepsInfo;
775
968
  if (legMode === "UNKNOWN") {
776
969
  continue itineraryLoop;
777
970
  }
@@ -784,7 +977,7 @@ class CitywayRemoteRouter extends RemoteRouter {
784
977
  name: jsonLeg.Arrival.Site.Name,
785
978
  coords: jsonToCoordinates$2(jsonLeg.Arrival.Site.Position)
786
979
  };
787
- stepsInfo = [];
980
+ minStepsInfo = [];
788
981
  for (const jsonPathLink of jsonLeg.pathLinks.PathLink) {
789
982
  let stepCoords;
790
983
  if (jsonPathLink.Geometry && jsonPathLink.Geometry !== "Null") {
@@ -797,11 +990,11 @@ class CitywayRemoteRouter extends RemoteRouter {
797
990
  legCoords.push(coords);
798
991
  }
799
992
  });
800
- stepsInfo.push(new StepInfo({
993
+ minStepsInfo.push({
801
994
  coords: stepCoords[0],
802
995
  distance: jsonPathLink.Distance,
803
996
  name: jsonPathLink.Departure.Site.Name
804
- }));
997
+ });
805
998
  }
806
999
  } else if (isRoutingModePublicTransport(legMode)) {
807
1000
  legFrom = {
@@ -830,13 +1023,13 @@ class CitywayRemoteRouter extends RemoteRouter {
830
1023
  }
831
1024
  });
832
1025
  }
833
- stepsInfo = [new StepInfo({
1026
+ minStepsInfo = [{
834
1027
  coords: legCoords[0],
835
1028
  name: jsonLeg.Line.Name,
836
1029
  distance: jsonLeg.Distance
837
- })];
1030
+ }];
838
1031
  } else {
839
- Logger.warn(`[CitywayParser] Unknown leg mode: ${jsonLeg.TransportMode}`);
1032
+ Logger__default.default.warn(`[CitywayParser] Unknown leg mode: ${jsonLeg.TransportMode}`);
840
1033
  continue;
841
1034
  }
842
1035
  const leg = new Leg({
@@ -847,7 +1040,8 @@ class CitywayRemoteRouter extends RemoteRouter {
847
1040
  coords: legCoords,
848
1041
  from: legFrom,
849
1042
  to: legTo,
850
- transportInfo
1043
+ transportInfo,
1044
+ minStepsInfo
851
1045
  });
852
1046
  legs.push(leg);
853
1047
  }
@@ -895,7 +1089,7 @@ class DeutscheBahnRemoteRouter extends RemoteRouter {
895
1089
  let url = endpointUrl + "/route/v1/walking/";
896
1090
  url += waypoints.map((waypoint) => {
897
1091
  if (waypoint.level !== null) {
898
- const altitude = Level.isRange(waypoint.level) ? waypoint.level[0] : waypoint.level;
1092
+ const altitude = geo.Level.isRange(waypoint.level) ? waypoint.level[0] : waypoint.level;
899
1093
  return waypoint.longitude + "," + waypoint.latitude + "," + altitude;
900
1094
  }
901
1095
  return waypoint.longitude + "," + waypoint.latitude;
@@ -909,9 +1103,9 @@ class DeutscheBahnRemoteRouter extends RemoteRouter {
909
1103
  return routerResponse;
910
1104
  }
911
1105
  const legs = json.segments.map((segment) => {
912
- const level = Level.union(segment.fromLevel, segment.toLevel);
1106
+ const level = geo.Level.union(segment.fromLevel, segment.toLevel);
913
1107
  const coords = segment.polyline.map(
914
- ({ lon, lat }) => new Coordinates(lat, lon, null, level)
1108
+ ({ lon, lat }) => new geo.Coordinates(lat, lon, null, level)
915
1109
  );
916
1110
  return new Leg({
917
1111
  mode: "WALK",
@@ -968,7 +1162,7 @@ const TRANSPORT_IDS = [
968
1162
  ];
969
1163
  const apiKey = "qWHj6ax6DMttG8DX6tH9CQARaiTgQ1Di";
970
1164
  function jsonToCoordinates$1(json) {
971
- return new Coordinates(Number(json.lat), Number(json.lon));
1165
+ return new geo.Coordinates(Number(json.lat), Number(json.lon));
972
1166
  }
973
1167
  function last(array) {
974
1168
  return array[array.length - 1];
@@ -1017,7 +1211,7 @@ class IdfmRemoteRouter extends RemoteRouter {
1017
1211
  }
1018
1212
  getURL(endpointUrl, mode, waypoints) {
1019
1213
  if (waypoints.length > 2) {
1020
- Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints.length})`);
1214
+ Logger__default.default.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints.length})`);
1021
1215
  }
1022
1216
  const fromPlace = `from=${waypoints[0].longitude};${waypoints[0].latitude}`;
1023
1217
  const toPlace = `to=${waypoints[1].longitude};${waypoints[1].latitude}`;
@@ -1082,7 +1276,7 @@ class IdfmRemoteRouter extends RemoteRouter {
1082
1276
  newCoords = duplicatedCoords[0];
1083
1277
  coords[_idCoordsInLeg] = newCoords;
1084
1278
  } else {
1085
- const result = Utils.trimRoute(duplicatedCoords, duplicatedCoords[0], previousStep.distance);
1279
+ const result = geo.Utils.trimRoute(duplicatedCoords, duplicatedCoords[0], previousStep.distance);
1086
1280
  accumulatedIndex += result.length - 1;
1087
1281
  duplicatedCoords.splice(0, result.length - 1);
1088
1282
  _idCoordsInLeg = accumulatedIndex;
@@ -1098,7 +1292,6 @@ class IdfmRemoteRouter extends RemoteRouter {
1098
1292
  return outputSteps;
1099
1293
  }
1100
1294
  createRouterResponseFromJson(json, from, to) {
1101
- var _a;
1102
1295
  const routerResponse = new RouterResponse({ routerName: this.rname, from, to });
1103
1296
  if (!json || !json.journeys) {
1104
1297
  return routerResponse;
@@ -1115,11 +1308,13 @@ class IdfmRemoteRouter extends RemoteRouter {
1115
1308
  const legCoords = jsonSection.geojson.coordinates.reduce((acc, [lon, lat]) => {
1116
1309
  if (!existingCoords.includes(`${lon}-${lat}`)) {
1117
1310
  existingCoords = existingCoords.concat(`${lon}-${lat}`);
1118
- acc.push(new Coordinates(lat, lon));
1311
+ acc.push(new geo.Coordinates(lat, lon));
1119
1312
  }
1120
1313
  return acc;
1121
1314
  }, []);
1122
- let stepsInfo;
1315
+ let minStepsInfo;
1316
+ let transportInfo;
1317
+ let mode = routingModeCorrespondance.get(jsonSection.mode);
1123
1318
  if (jsonSection.path) {
1124
1319
  const idfmIntermediateSteps = [];
1125
1320
  for (const jsonPathLink of jsonSection.path) {
@@ -1128,10 +1323,25 @@ class IdfmRemoteRouter extends RemoteRouter {
1128
1323
  distance: jsonPathLink.length
1129
1324
  });
1130
1325
  }
1131
- 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];
1132
1342
  }
1133
1343
  const leg = new Leg({
1134
- mode: routingModeCorrespondance.get(jsonSection.mode),
1344
+ mode,
1135
1345
  duration: jsonSection.duration,
1136
1346
  startTime: dateStringToTimestamp(jsonSection.departure_date_time, timeZone),
1137
1347
  endTime: dateStringToTimestamp(jsonSection.arrival_date_time, timeZone),
@@ -1144,23 +1354,9 @@ class IdfmRemoteRouter extends RemoteRouter {
1144
1354
  coords: toSection
1145
1355
  },
1146
1356
  coords: legCoords,
1147
- stepsInfo
1357
+ transportInfo,
1358
+ minStepsInfo
1148
1359
  });
1149
- if (jsonSection.type === "public_transport") {
1150
- leg.transportInfo = {
1151
- name: jsonSection.display_informations.code,
1152
- routeColor: jsonSection.display_informations.color,
1153
- routeTextColor: jsonSection.display_informations.text_color,
1154
- directionName: jsonSection.display_informations.direction
1155
- };
1156
- leg.mode = routingModeCorrespondance.get(jsonSection.display_informations.physical_mode);
1157
- const legStep = new StepInfo({
1158
- coords: leg.coords[0],
1159
- name: (_a = leg.transportInfo) == null ? void 0 : _a.directionName,
1160
- distance: jsonSection.geojson.properties[0].length
1161
- });
1162
- leg.stepsInfo = [legStep];
1163
- }
1164
1360
  legs.push(leg);
1165
1361
  }
1166
1362
  const itinerary = new Itinerary({
@@ -1213,20 +1409,20 @@ class OsrmRemoteRouter extends RemoteRouter {
1213
1409
  if (level === null) {
1214
1410
  return [lng, lat];
1215
1411
  }
1216
- if (Level.isRange(level)) {
1412
+ if (geo.Level.isRange(level)) {
1217
1413
  return [lng, lat, level[0]];
1218
1414
  }
1219
1415
  return [lng, lat, level];
1220
1416
  }
1221
1417
  jsonToCoordinates(json) {
1222
- const coords = new Coordinates(json[1], json[0]);
1418
+ const coords = new geo.Coordinates(json[1], json[0]);
1223
1419
  if (json.length > 2) {
1224
1420
  coords.level = json[2];
1225
1421
  }
1226
1422
  return coords;
1227
1423
  }
1228
1424
  getModifierFromAngle(_angle) {
1229
- const angle = positiveMod(rad2deg(_angle), 360);
1425
+ const angle = maths.positiveMod(maths.rad2deg(_angle), 360);
1230
1426
  if (angle > 0 && angle < 60) {
1231
1427
  return "sharp right";
1232
1428
  }
@@ -1281,8 +1477,8 @@ class OsrmRemoteRouter extends RemoteRouter {
1281
1477
  duration: step.duration || 0,
1282
1478
  ...step.name && { name: step.name },
1283
1479
  maneuver: {
1284
- bearing_before: rad2deg(step.previousBearing),
1285
- bearing_after: rad2deg(step.nextBearing),
1480
+ bearing_before: maths.rad2deg(step.previousBearing),
1481
+ bearing_after: maths.rad2deg(step.nextBearing),
1286
1482
  location: this.coordinatesToJson(step.coords),
1287
1483
  modifier: this.getModifierFromAngle(step.angle),
1288
1484
  type
@@ -1325,19 +1521,19 @@ class OsrmRemoteRouter extends RemoteRouter {
1325
1521
  const legs = jsonItinerary.legs.map((jsonLeg) => {
1326
1522
  var _a;
1327
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));
1328
- 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 }) => {
1329
1525
  const stepCoords = this.jsonToCoordinates(maneuver.location);
1330
1526
  const distances = legCoords.map((coords) => coords.distanceTo(stepCoords));
1331
1527
  const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));
1332
1528
  if (idStepCoordsInLeg < 0) {
1333
1529
  throw new Error("Osrm Parser: Cannot find step coords in leg coordinates");
1334
1530
  }
1335
- return new StepInfo({
1531
+ return {
1336
1532
  coords: stepCoords,
1337
1533
  name,
1338
1534
  distance,
1339
1535
  duration
1340
- });
1536
+ };
1341
1537
  });
1342
1538
  return new Leg({
1343
1539
  mode,
@@ -1349,7 +1545,7 @@ class OsrmRemoteRouter extends RemoteRouter {
1349
1545
  to: {
1350
1546
  coords: legCoords[legCoords.length - 1]
1351
1547
  },
1352
- stepsInfo
1548
+ minStepsInfo
1353
1549
  });
1354
1550
  });
1355
1551
  return new Itinerary({
@@ -1367,7 +1563,7 @@ function isLegPT(leg) {
1367
1563
  return leg.mode === "BUS" || leg.mode === "TRAM";
1368
1564
  }
1369
1565
  function jsonToCoordinates(json) {
1370
- return new Coordinates(json.lat, json.lon);
1566
+ return new geo.Coordinates(json.lat, json.lon);
1371
1567
  }
1372
1568
  const inputModeCorrespondance = /* @__PURE__ */ new Map();
1373
1569
  inputModeCorrespondance.set("CAR", "CAR");
@@ -1395,7 +1591,7 @@ class OtpRemoteRouter extends RemoteRouter {
1395
1591
  throw new RoutingModeCorrespondanceNotFound(this.rname, mode);
1396
1592
  }
1397
1593
  if (waypoints.length > 2) {
1398
- Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints.length})`);
1594
+ Logger__default.default.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints.length})`);
1399
1595
  }
1400
1596
  const fromPlace = `fromPlace=${waypoints[0].latitude},${waypoints[0].longitude}`;
1401
1597
  const toPlace = `toPlace=${waypoints[1].latitude},${waypoints[1].longitude}`;
@@ -1416,9 +1612,9 @@ class OtpRemoteRouter extends RemoteRouter {
1416
1612
  for (const jsonItinerary of jsonPlan.itineraries) {
1417
1613
  const legs = [];
1418
1614
  for (const jsonLeg of jsonItinerary.legs) {
1419
- const legCoords = Polyline.decode(jsonLeg.legGeometry.points).map(([lat, lon]) => new Coordinates(lat, lon));
1615
+ const legCoords = Polyline__default.default.decode(jsonLeg.legGeometry.points).map(([lat, lon]) => new geo.Coordinates(lat, lon));
1420
1616
  let transportInfo;
1421
- let stepsInfo;
1617
+ let minStepsInfo;
1422
1618
  if (isLegPT(jsonLeg)) {
1423
1619
  transportInfo = {
1424
1620
  name: jsonLeg.routeShortName,
@@ -1426,21 +1622,21 @@ class OtpRemoteRouter extends RemoteRouter {
1426
1622
  routeTextColor: jsonLeg.routeTextColor,
1427
1623
  directionName: jsonLeg.headsign
1428
1624
  };
1429
- stepsInfo = [new StepInfo({
1625
+ minStepsInfo = [{
1430
1626
  coords: legCoords[0],
1431
1627
  name: jsonLeg.headsign
1432
- })];
1628
+ }];
1433
1629
  } else {
1434
- stepsInfo = jsonLeg.steps.map((jsonStep) => {
1630
+ minStepsInfo = jsonLeg.steps.map((jsonStep) => {
1435
1631
  const distances = legCoords.map((coords) => coords.distanceTo(jsonToCoordinates(jsonStep)));
1436
1632
  const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));
1437
1633
  if (idStepCoordsInLeg < 0) {
1438
1634
  throw new Error("OTP Parser: Cannot find closest step");
1439
1635
  }
1440
- return new StepInfo({
1636
+ return {
1441
1637
  coords: legCoords[idStepCoordsInLeg],
1442
1638
  name: jsonStep.streetName
1443
- });
1639
+ };
1444
1640
  });
1445
1641
  }
1446
1642
  const leg = new Leg({
@@ -1458,7 +1654,7 @@ class OtpRemoteRouter extends RemoteRouter {
1458
1654
  },
1459
1655
  coords: legCoords,
1460
1656
  transportInfo,
1461
- stepsInfo
1657
+ minStepsInfo
1462
1658
  });
1463
1659
  legs.push(leg);
1464
1660
  }
@@ -1491,7 +1687,7 @@ class WemapMultiRemoteRouterPayload {
1491
1687
  }
1492
1688
  static fromJson(json) {
1493
1689
  return new WemapMultiRemoteRouterPayload(
1494
- json.waypoints.map(Coordinates.fromCompressedJson),
1690
+ json.waypoints.map(geo.Coordinates.fromCompressedJson),
1495
1691
  json.mode,
1496
1692
  json.options
1497
1693
  );
@@ -1499,7 +1695,7 @@ class WemapMultiRemoteRouterPayload {
1499
1695
  }
1500
1696
  class WemapMultiRemoteRouter extends RemoteRouter {
1501
1697
  get rname() {
1502
- return "wemap-meta";
1698
+ return "wemap-multi";
1503
1699
  }
1504
1700
  async getItineraries(endpointUrl, mode, waypoints, options) {
1505
1701
  const payload = new WemapMultiRemoteRouterPayload(
@@ -1524,19 +1720,17 @@ class WemapMultiRemoteRouter extends RemoteRouter {
1524
1720
  }
1525
1721
  }
1526
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
+ ];
1527
1731
  class RemoteRouterManager {
1528
- constructor() {
1529
- __publicField(this, "remoteRouters", [
1530
- CitywayRemoteRouter$1,
1531
- DeutscheBahnRemoteRouter$1,
1532
- IdfmRemoteRouter$1,
1533
- OsrmRemoteRouter$1,
1534
- OtpRemoteRouter$1,
1535
- WemapMultiRemoteRouter$1
1536
- ]);
1537
- }
1538
1732
  getRouterByName(name) {
1539
- return this.remoteRouters.find((remoteRouter) => remoteRouter.rname === name);
1733
+ return remoteRouters.find((remoteRouter) => remoteRouter.rname === name);
1540
1734
  }
1541
1735
  async getItineraries(name, endpointUrl, mode, waypoints, options) {
1542
1736
  const router = this.getRouterByName(name);
@@ -1545,9 +1739,9 @@ class RemoteRouterManager {
1545
1739
  }
1546
1740
  return router.getItineraries(endpointUrl, mode, waypoints, options);
1547
1741
  }
1548
- async getItinerariesWithFallback(remoteRouters, mode, waypoints, options) {
1742
+ async getItinerariesWithFallback(remoteRouters2, mode, waypoints, options) {
1549
1743
  let routerResponse;
1550
- for (const { name, endpointUrl } of remoteRouters) {
1744
+ for (const { name, endpointUrl } of remoteRouters2) {
1551
1745
  routerResponse = await this.getItineraries(name, endpointUrl, mode, waypoints, options);
1552
1746
  if (routerResponse.itineraries.length) {
1553
1747
  return routerResponse;
@@ -1555,7 +1749,7 @@ class RemoteRouterManager {
1555
1749
  }
1556
1750
  if (!routerResponse) {
1557
1751
  routerResponse = new RouterResponse({
1558
- routerName: remoteRouters.map((rr) => rr.name),
1752
+ routerName: remoteRouters2.map((rr) => rr.name),
1559
1753
  from: waypoints[0],
1560
1754
  to: waypoints[waypoints.length]
1561
1755
  });
@@ -1570,7 +1764,7 @@ class WemapMultiRouter {
1570
1764
  __publicField(this, "maps", []);
1571
1765
  }
1572
1766
  get rname() {
1573
- return "wemap-meta";
1767
+ return "wemap-multi";
1574
1768
  }
1575
1769
  addIOMap(customNetworkMap) {
1576
1770
  this.maps.push(customNetworkMap);
@@ -1578,10 +1772,10 @@ class WemapMultiRouter {
1578
1772
  removeIOMap(customNetworkMap) {
1579
1773
  this.maps = this.maps.filter((map) => map !== customNetworkMap);
1580
1774
  }
1581
- async getItineraries(mode, waypoints, options) {
1775
+ async getItineraries(mode, waypoints, options = null) {
1582
1776
  var _a;
1583
1777
  if (waypoints.length > 2) {
1584
- Logger.warn(`WemapMultiRouter uses only the first 2 waypoints (asked ${waypoints.length})`);
1778
+ Logger__default.default.warn(`WemapMultiRouter uses only the first 2 waypoints (asked ${waypoints.length})`);
1585
1779
  }
1586
1780
  const start = waypoints[0];
1587
1781
  const end = waypoints[1];
@@ -1590,22 +1784,22 @@ class WemapMultiRouter {
1590
1784
  from: start,
1591
1785
  to: end
1592
1786
  });
1593
- const remoteRouters = ((_a = 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)) || [];
1594
1788
  let ioMapsToTest = this.maps;
1595
- const { targetMaps } = options;
1789
+ const targetMaps = options == null ? void 0 : options.targetMaps;
1596
1790
  if (targetMaps) {
1597
1791
  ioMapsToTest = this.maps.filter((map) => map.name && targetMaps.includes(map.name));
1598
1792
  if (ioMapsToTest.length !== targetMaps.length) {
1599
1793
  ioMapsToTest.forEach((map) => {
1600
1794
  if (map.name && !targetMaps.includes(map.name)) {
1601
- Logger.warn(`CustomNetworkMap "${map.name}" not found in WemapMultiRouter`);
1795
+ Logger__default.default.warn(`CustomNetworkMap "${map.name}" not found in WemapMultiRouter`);
1602
1796
  }
1603
1797
  });
1604
1798
  }
1605
1799
  }
1606
1800
  if (!ioMapsToTest.length) {
1607
1801
  try {
1608
- return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters, mode, waypoints);
1802
+ return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters2, mode, waypoints);
1609
1803
  } catch (e) {
1610
1804
  if (!isRoutingError(e)) {
1611
1805
  throw e;
@@ -1616,7 +1810,7 @@ class WemapMultiRouter {
1616
1810
  }
1617
1811
  let ioMapItinerary;
1618
1812
  const mapWithStart = ioMapsToTest.find((map) => map.isPointInside(start));
1619
- const wemapOsmRouterOptions = !("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;
1620
1814
  if (mapWithStart && mapWithStart.isPointInside(end)) {
1621
1815
  try {
1622
1816
  ioMapItinerary = mapWithStart.getItineraryInsideMap(start, end, wemapOsmRouterOptions);
@@ -1635,7 +1829,7 @@ class WemapMultiRouter {
1635
1829
  let remoteRouterResponse;
1636
1830
  if (!mapWithStart && !mapWithEnd) {
1637
1831
  try {
1638
- return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters, mode, waypoints);
1832
+ return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters2, mode, waypoints);
1639
1833
  } catch (e) {
1640
1834
  if (!isRoutingError(e)) {
1641
1835
  throw e;
@@ -1653,18 +1847,18 @@ class WemapMultiRouter {
1653
1847
  try {
1654
1848
  ioMapItinerary = mapWithStart.getBestItineraryFromStartToEntryPoints(start, end, wemapOsmRouterOptions);
1655
1849
  remoteRouterResponse = await RemoteRouterManager$1.getItinerariesWithFallback(
1656
- remoteRouters,
1850
+ remoteRouters2,
1657
1851
  mode,
1658
1852
  [ioMapItinerary.to, end]
1659
1853
  );
1660
1854
  if (!remoteRouterResponse.itineraries.length) {
1661
- throw new NoRouteFoundError(ioMapItinerary.to, end, remoteRouterResponse.error);
1855
+ throw new geo.NoRouteFoundError(ioMapItinerary.to, end, remoteRouterResponse.error);
1662
1856
  }
1663
1857
  } catch (e) {
1664
1858
  if (!isRoutingError(e)) {
1665
1859
  throw e;
1666
1860
  }
1667
- 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}.`;
1668
1862
  return routerResponse;
1669
1863
  }
1670
1864
  routerResponse.itineraries = remoteRouterResponse.itineraries.map(
@@ -1682,18 +1876,18 @@ class WemapMultiRouter {
1682
1876
  try {
1683
1877
  ioMapItinerary = mapWithEnd.getBestItineraryFromEntryPointsToEnd(start, end, wemapOsmRouterOptions);
1684
1878
  remoteRouterResponse = await RemoteRouterManager$1.getItinerariesWithFallback(
1685
- remoteRouters,
1879
+ remoteRouters2,
1686
1880
  mode,
1687
1881
  [start, ioMapItinerary.from]
1688
1882
  );
1689
1883
  if (!remoteRouterResponse.itineraries.length) {
1690
- throw new NoRouteFoundError(start, ioMapItinerary.from, remoteRouterResponse.error);
1884
+ throw new geo.NoRouteFoundError(start, ioMapItinerary.from, remoteRouterResponse.error);
1691
1885
  }
1692
1886
  } catch (e) {
1693
1887
  if (!isRoutingError(e)) {
1694
1888
  throw e;
1695
1889
  }
1696
- 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}.`;
1697
1891
  return routerResponse;
1698
1892
  }
1699
1893
  routerResponse.itineraries = remoteRouterResponse.itineraries.map(
@@ -1720,18 +1914,18 @@ class WemapMultiRouter {
1720
1914
  ioMapItinerary1 = mapWithStart.getBestItineraryFromStartToEntryPoints(start, end, wemapOsmRouterOptions);
1721
1915
  ioMapItinerary2 = mapWithEnd.getBestItineraryFromEntryPointsToEnd(start, end, wemapOsmRouterOptions);
1722
1916
  remoteRouterResponse = await RemoteRouterManager$1.getItinerariesWithFallback(
1723
- remoteRouters,
1917
+ remoteRouters2,
1724
1918
  mode,
1725
1919
  [ioMapItinerary1.to, ioMapItinerary2.from]
1726
1920
  );
1727
1921
  if (!remoteRouterResponse.itineraries.length) {
1728
- throw new NoRouteFoundError(ioMapItinerary1.to, ioMapItinerary2.from, remoteRouterResponse.error);
1922
+ throw new geo.NoRouteFoundError(ioMapItinerary1.to, ioMapItinerary2.from, remoteRouterResponse.error);
1729
1923
  }
1730
1924
  } catch (e) {
1731
1925
  if (!isRoutingError(e)) {
1732
1926
  throw e;
1733
1927
  }
1734
- 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}.`;
1735
1929
  return routerResponse;
1736
1930
  }
1737
1931
  routerResponse.itineraries = remoteRouterResponse.itineraries.map(
@@ -1748,49 +1942,66 @@ class WemapMultiRouter {
1748
1942
  }
1749
1943
  }
1750
1944
  class CustomNetworkMap {
1751
- constructor(network, entryPoints, bounds = null, name = null) {
1945
+ constructor(graph, entryPoints, bounds = null, name = null) {
1752
1946
  __publicField(this, "name");
1753
- __publicField(this, "network");
1947
+ __publicField(this, "graph");
1754
1948
  __publicField(this, "router");
1755
1949
  __publicField(this, "bounds");
1756
1950
  __publicField(this, "entryPoints");
1757
1951
  __publicField(this, "disabledWays", /* @__PURE__ */ new Set());
1758
1952
  this.name = name;
1759
- this.network = network;
1760
- this.router = new WemapOsmRouter(network);
1953
+ this.graph = graph;
1954
+ this.router = new WemapOsmRouter(graph);
1761
1955
  entryPoints.forEach((entryPoint) => {
1762
- if (!network.nodes.includes(entryPoint)) {
1956
+ if (!graph.vertices.includes(entryPoint)) {
1763
1957
  throw new Error(`Cannot find entry point ${entryPoint.coords.toString()} in network "${name}"`);
1764
1958
  }
1765
1959
  });
1766
1960
  this.entryPoints = entryPoints;
1767
1961
  if (bounds) {
1768
- this.bounds = polygon([bounds.map((coords) => [coords.lng, coords.lat])]);
1962
+ this.bounds = bounds;
1769
1963
  } else {
1770
- const polygon2 = [network.nodes.map((node) => [node.coords.lng, node.coords.lat])];
1771
- const convexHull = convexHullFn({ type: "polygon", coordinates: polygon2 });
1964
+ const polygon = [graph.vertices.map((vertex) => [vertex.coords.lng, vertex.coords.lat])];
1965
+ const convexHull = convexHullFn__default.default({ type: "polygon", coordinates: polygon });
1772
1966
  if (!convexHull) {
1773
1967
  throw new Error(`Cannot calculate convexHull of network "${name}"`);
1774
1968
  }
1775
- this.bounds = convexHull;
1969
+ this.bounds = {
1970
+ type: "MultiPolygon",
1971
+ coordinates: [convexHull.geometry.coordinates]
1972
+ };
1776
1973
  }
1777
1974
  }
1778
1975
  static fromOsmXml(osmXmlString, name = null) {
1779
- const osmModel = OsmParser.parseOsmXmlString(osmXmlString);
1780
- const network = OsmNetworkUtils.createNetworkFromOsmModel(osmModel);
1781
- const entryPoints = osmModel.nodes.filter(({ tags }) => tags && tags["wemap:routing-io"]).map((osmNode) => network.getNodeByCoords(osmNode.coords));
1976
+ const osmModel = osm.OsmParser.parseOsmXmlString(osmXmlString);
1977
+ const graph = OsmGraph.fromOsmModel(osmModel);
1978
+ const entryPoints = graph.vertices.filter(({ data: { tags } }) => tags && tags["wemap:routing-io"]);
1782
1979
  if (entryPoints.some((el) => el === null) || new Set(entryPoints).size !== entryPoints.length) {
1783
1980
  throw new Error("Cannot parse wemap:routing-io correctly");
1784
1981
  }
1785
- const wayBounds = osmModel.ways.find(({ tags }) => tags["wemap:routing-bounds"]);
1786
- if (!wayBounds) {
1982
+ const bounds = {
1983
+ type: "MultiPolygon",
1984
+ coordinates: []
1985
+ };
1986
+ osmModel.ways.filter(({ tags }) => tags["wemap:routing-bounds"]).forEach((way) => {
1987
+ bounds.coordinates.push([
1988
+ way.nodes.reduce((acc, node) => {
1989
+ acc.push([node.coords.lng, node.coords.lat]);
1990
+ return acc;
1991
+ }, [])
1992
+ ]);
1993
+ });
1994
+ osmModel.relations.filter((rel) => rel.tags["wemap:routing-bounds"] && rel.isMultipolygon()).forEach((rel) => {
1995
+ const polygon = rel.getGeoJsonPolygon();
1996
+ polygon && bounds.coordinates.push(polygon.coordinates);
1997
+ });
1998
+ if (!bounds.coordinates.length) {
1787
1999
  throw new Error('Search bounds is undefined. Please use OSM tag : "wemap:routing-bounds=yes"');
1788
2000
  }
1789
- const bounds = wayBounds.nodes.map((node) => node.coords);
1790
- return new CustomNetworkMap(network, entryPoints, bounds, name);
2001
+ return new CustomNetworkMap(graph, entryPoints, bounds, name);
1791
2002
  }
1792
2003
  isPointInside(coordinates) {
1793
- return pointInPolygon([coordinates.lng, coordinates.lat], this.bounds);
2004
+ return pointInPolygon__default.default([coordinates.lng, coordinates.lat], this.bounds);
1794
2005
  }
1795
2006
  getOrderedEntryPointsSortedByDistance(start, end) {
1796
2007
  const entryPointsCopy = [...this.entryPoints];
@@ -1806,7 +2017,7 @@ class CustomNetworkMap {
1806
2017
  return itinerary;
1807
2018
  }
1808
2019
  }
1809
- throw new NoRouteFoundError(
2020
+ throw new geo.NoRouteFoundError(
1810
2021
  start,
1811
2022
  end,
1812
2023
  `No route found from entry points to ${end.toString()} in map: ${this.name}`
@@ -1820,7 +2031,7 @@ class CustomNetworkMap {
1820
2031
  return itinerary;
1821
2032
  }
1822
2033
  }
1823
- throw new NoRouteFoundError(
2034
+ throw new geo.NoRouteFoundError(
1824
2035
  start,
1825
2036
  end,
1826
2037
  `No route found from ${start.toString()} to entry points in map: ${this.name}`
@@ -1830,44 +2041,18 @@ class CustomNetworkMap {
1830
2041
  return this.router.getItinerary(start, end, options);
1831
2042
  }
1832
2043
  enableWay(osmId) {
1833
- this.network.edges.filter((edge) => {
1834
- var _a;
1835
- return ((_a = edge.builtFrom) == null ? void 0 : _a.id) === osmId;
1836
- }).forEach((e) => this.router.disabledEdges.delete(e));
2044
+ this.graph.edges.filter((edge) => edge.data.id === osmId).forEach((e) => this.router.disabledEdges.delete(e));
1837
2045
  this.disabledWays.delete(osmId);
1838
2046
  }
1839
2047
  disableWay(osmId) {
1840
- this.network.edges.filter((edge) => {
1841
- var _a;
1842
- return ((_a = edge.builtFrom) == null ? void 0 : _a.id) === osmId;
1843
- }).forEach((e) => this.router.disabledEdges.add(e));
2048
+ this.graph.edges.filter((edge) => edge.data.id === osmId).forEach((e) => this.router.disabledEdges.add(e));
1844
2049
  this.disabledWays.add(osmId);
1845
2050
  }
1846
2051
  }
1847
- function getTurnInfoFromAngle(_angle) {
1848
- let direction, directionExtra;
1849
- const directionAngle = rad2deg(diffAngle(_angle, Math.PI));
1850
- const directionAngleAbs = Math.abs(directionAngle);
1851
- if (directionAngleAbs <= 20) {
1852
- direction = "straight";
1853
- } else {
1854
- direction = directionAngle > 0 ? "left" : "right";
1855
- if (directionAngleAbs < 55) {
1856
- directionExtra = "slight";
1857
- } else if (directionAngleAbs > 120) {
1858
- directionExtra = "sharp";
1859
- }
1860
- }
1861
- return { direction, directionExtra };
1862
- }
1863
- const WemapOsmRouterUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1864
- __proto__: null,
1865
- getTurnInfoFromAngle
1866
- }, Symbol.toStringTag, { value: "Module" }));
1867
2052
  class ItineraryInfoManager {
1868
2053
  constructor(itinerary = null) {
1869
2054
  __publicField(this, "_itinerary", null);
1870
- __publicField(this, "_mapMatching", null);
2055
+ __publicField(this, "_geoGraphProjectionHandler", null);
1871
2056
  __publicField(this, "_steps", []);
1872
2057
  __publicField(this, "_coordsNextStep", []);
1873
2058
  __publicField(this, "_coordsPreviousStep", []);
@@ -1885,8 +2070,8 @@ class ItineraryInfoManager {
1885
2070
  }
1886
2071
  this._itinerary = itinerary;
1887
2072
  this._steps = itinerary.steps;
1888
- const network = itinerary.toNetwork();
1889
- this._mapMatching = new MapMatching(network);
2073
+ const graph = itinerary.toGraph();
2074
+ this._geoGraphProjectionHandler = new geo.GeoGraphProjectionHandler(graph);
1890
2075
  this._coordsNextStep = new Array(itinerary.coords.length);
1891
2076
  this._coordsPreviousStep = new Array(itinerary.coords.length);
1892
2077
  this._coordsDistanceTraveled = new Array(itinerary.coords.length);
@@ -1911,15 +2096,15 @@ class ItineraryInfoManager {
1911
2096
  });
1912
2097
  }
1913
2098
  getInfo(position) {
1914
- if (!this._itinerary || !this._mapMatching) {
2099
+ if (!this._itinerary || !this._geoGraphProjectionHandler) {
1915
2100
  return null;
1916
2101
  }
1917
- const projection = this._mapMatching.getProjection(position);
2102
+ const projection = this._geoGraphProjectionHandler.getProjection(position);
1918
2103
  if (!projection) {
1919
2104
  return null;
1920
2105
  }
1921
2106
  let itineraryInfo = null;
1922
- if (projection.nearestElement instanceof GraphNode) {
2107
+ if (projection.nearestElement instanceof geo.GeoGraphVertex) {
1923
2108
  const idx = this._itinerary.coords.findIndex(
1924
2109
  (coords) => projection.nearestElement.coords === coords
1925
2110
  );
@@ -1938,14 +2123,14 @@ class ItineraryInfoManager {
1938
2123
  traveledPercentage: traveledDistance / this._itinerary.distance,
1939
2124
  remainingPercentage: remainingDistance / this._itinerary.distance
1940
2125
  };
1941
- } else if (projection.nearestElement instanceof GraphEdge) {
1942
- let firstNode = projection.nearestElement.node1.coords;
2126
+ } else if (projection.nearestElement instanceof geo.GeoGraphEdge) {
2127
+ let firstNode = projection.nearestElement.vertex1.coords;
1943
2128
  let idx = this._itinerary.coords.findIndex((coords) => firstNode === coords);
1944
2129
  if (idx === -1) {
1945
2130
  throw new Error("ItineraryInfoManager: could not find projection in itinerary (Edge)");
1946
2131
  }
1947
- if (idx === this._itinerary.coords.length - 1 || this._itinerary.coords[idx + 1] !== projection.nearestElement.node2.coords) {
1948
- 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;
1949
2134
  idx--;
1950
2135
  }
1951
2136
  const traveledDistance = this._coordsDistanceTraveled[idx] + projection.coords.distanceTo(firstNode);
@@ -1964,26 +2149,22 @@ class ItineraryInfoManager {
1964
2149
  return itineraryInfo;
1965
2150
  }
1966
2151
  }
1967
- export {
1968
- CitywayRemoteRouter$1 as CitywayRemoteRouter,
1969
- DeutscheBahnRemoteRouter$1 as DeutscheBahnRemoteRouter,
1970
- IdfmRemoteRouter$1 as IdfmRemoteRouter,
1971
- Itinerary,
1972
- ItineraryInfoManager,
1973
- Leg,
1974
- OsrmRemoteRouter$1 as OsrmRemoteRouter,
1975
- OtpRemoteRouter$1 as OtpRemoteRouter,
1976
- RemoteRouterManager$1 as RemoteRouterManager,
1977
- RemoteRouterServerUnreachable,
1978
- RouterResponse,
1979
- StepInfo,
1980
- CustomNetworkMap as WemapMetaRouterIOMap,
1981
- WemapMultiRemoteRouter$1 as WemapMultiRemoteRouter,
1982
- WemapMultiRemoteRouterPayload,
1983
- WemapMultiRouter,
1984
- WemapOsmRouter,
1985
- WemapOsmRouterOptions,
1986
- WemapOsmRouterUtils,
1987
- getDurationFromLength
1988
- };
2152
+ exports.CitywayRemoteRouter = CitywayRemoteRouter$1;
2153
+ exports.CustomNetworkMap = CustomNetworkMap;
2154
+ exports.DeutscheBahnRemoteRouter = DeutscheBahnRemoteRouter$1;
2155
+ exports.IdfmRemoteRouter = IdfmRemoteRouter$1;
2156
+ exports.Itinerary = Itinerary;
2157
+ exports.ItineraryInfoManager = ItineraryInfoManager;
2158
+ exports.Leg = Leg;
2159
+ exports.OsmGraph = OsmGraph;
2160
+ exports.OsmRouter = WemapOsmRouter;
2161
+ exports.OsrmRemoteRouter = OsrmRemoteRouter$1;
2162
+ exports.OtpRemoteRouter = OtpRemoteRouter$1;
2163
+ exports.RemoteRouterManager = RemoteRouterManager$1;
2164
+ exports.RemoteRouterServerUnreachable = RemoteRouterServerUnreachable;
2165
+ exports.RouterResponse = RouterResponse;
2166
+ exports.WemapMultiRemoteRouter = WemapMultiRemoteRouter$1;
2167
+ exports.WemapMultiRemoteRouterPayload = WemapMultiRemoteRouterPayload;
2168
+ exports.WemapMultiRouter = WemapMultiRouter;
2169
+ exports.getDurationFromLength = getDurationFromLength;
1989
2170
  //# sourceMappingURL=index.js.map