@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.
- package/dist/index.js +543 -362
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2164 -0
- package/dist/index.mjs.map +1 -0
- package/index.ts +7 -9
- package/package.json +14 -7
- package/src/ItineraryInfoManager.spec.ts +14 -14
- package/src/ItineraryInfoManager.ts +13 -13
- package/src/model/Itinerary.spec.ts +16 -12
- package/src/model/Itinerary.ts +69 -73
- package/src/model/Leg.spec.ts +8 -8
- package/src/model/Leg.ts +78 -33
- package/src/model/Step.spec.ts +99 -0
- package/src/model/Step.ts +77 -14
- package/src/model/generateSteps.ts +20 -12
- package/src/remote/RemoteRouterManager.ts +17 -15
- package/src/remote/cityway/CitywayRemoteRouter.ts +10 -11
- package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.ts +1 -3
- package/src/remote/idfm/IdfmRemoteRouter.ts +30 -30
- package/src/remote/osrm/OsrmRemoteRouter.ts +5 -8
- package/src/remote/otp/OtpRemoteRouter.ts +9 -12
- package/src/remote/wemap-multi/WemapMultiRemoteRouter.ts +1 -3
- package/src/remote/wemap-multi/WemapMultiRemoteRouterPayload.ts +3 -3
- package/src/wemap-multi/CustomNetworkMap.ts +51 -32
- package/src/wemap-multi/WemapMultiRouter.ts +8 -9
- package/src/wemap-multi/WemapMultiRouterOptions.ts +3 -1
- package/src/wemap-osm/OsmGraph.spec.ts +99 -0
- package/src/wemap-osm/OsmGraph.ts +169 -0
- package/src/wemap-osm/{WemapOsmRouter.spec.ts → OsmRouter.spec.ts} +94 -35
- package/src/wemap-osm/OsmRouter.ts +201 -0
- package/vite.config.ts +1 -1
- package/src/model/ItineraryInfo.ts +0 -19
- package/src/model/StepInfo.spec.ts +0 -78
- package/src/model/StepInfo.ts +0 -78
- package/src/wemap-osm/WemapOsmRouter.ts +0 -82
- package/src/wemap-osm/WemapOsmRouterOptions.ts +0 -23
- 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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
56
|
+
delete currentStep.duration;
|
|
92
57
|
}
|
|
93
|
-
currentStep =
|
|
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(
|
|
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, "
|
|
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
|
-
|
|
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
|
-
|
|
170
|
-
return
|
|
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
|
|
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
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
261
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
382
|
-
return
|
|
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
|
|
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.
|
|
475
|
-
for (const step of leg.
|
|
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
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
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
|
-
|
|
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
|
-
|
|
573
|
-
|
|
574
|
-
|
|
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
|
|
578
|
-
const
|
|
579
|
-
const
|
|
580
|
-
if (!
|
|
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 =
|
|
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 =
|
|
587
|
-
const isGate =
|
|
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.
|
|
709
|
+
if (edge.data.isElevator) {
|
|
590
710
|
levelChangeType = "elevator";
|
|
591
|
-
} else if (edge.
|
|
711
|
+
} else if (edge.data.isConveying) {
|
|
592
712
|
levelChangeType = "conveyor";
|
|
593
|
-
} else if (edge.
|
|
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
|
|
598
|
-
stepName: (_d = edge.
|
|
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 =
|
|
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
|
|
609
|
-
constructor(
|
|
610
|
-
super(
|
|
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 =
|
|
755
|
+
getShortestPath(start, end, options = DEFAULT_OPTIONS) {
|
|
616
756
|
return super.getShortestPath(start, end, options);
|
|
617
757
|
}
|
|
618
|
-
getItinerary(start, end, options =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1026
|
+
minStepsInfo = [{
|
|
834
1027
|
coords: legCoords[0],
|
|
835
1028
|
name: jsonLeg.Line.Name,
|
|
836
1029
|
distance: jsonLeg.Distance
|
|
837
|
-
}
|
|
1030
|
+
}];
|
|
838
1031
|
} else {
|
|
839
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
1615
|
+
const legCoords = Polyline__default.default.decode(jsonLeg.legGeometry.points).map(([lat, lon]) => new geo.Coordinates(lat, lon));
|
|
1420
1616
|
let transportInfo;
|
|
1421
|
-
let
|
|
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
|
-
|
|
1625
|
+
minStepsInfo = [{
|
|
1430
1626
|
coords: legCoords[0],
|
|
1431
1627
|
name: jsonLeg.headsign
|
|
1432
|
-
}
|
|
1628
|
+
}];
|
|
1433
1629
|
} else {
|
|
1434
|
-
|
|
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
|
|
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
|
-
|
|
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-
|
|
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
|
|
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(
|
|
1742
|
+
async getItinerariesWithFallback(remoteRouters2, mode, waypoints, options) {
|
|
1549
1743
|
let routerResponse;
|
|
1550
|
-
for (const { name, endpointUrl } of
|
|
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:
|
|
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-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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(
|
|
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)
|
|
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(
|
|
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
|
-
|
|
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 (${
|
|
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
|
-
|
|
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 (${
|
|
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
|
-
|
|
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 (${
|
|
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(
|
|
1945
|
+
constructor(graph, entryPoints, bounds = null, name = null) {
|
|
1752
1946
|
__publicField(this, "name");
|
|
1753
|
-
__publicField(this, "
|
|
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.
|
|
1760
|
-
this.router = new WemapOsmRouter(
|
|
1953
|
+
this.graph = graph;
|
|
1954
|
+
this.router = new WemapOsmRouter(graph);
|
|
1761
1955
|
entryPoints.forEach((entryPoint) => {
|
|
1762
|
-
if (!
|
|
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 =
|
|
1962
|
+
this.bounds = bounds;
|
|
1769
1963
|
} else {
|
|
1770
|
-
const
|
|
1771
|
-
const convexHull =
|
|
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 =
|
|
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
|
|
1781
|
-
const entryPoints =
|
|
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
|
|
1786
|
-
|
|
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
|
-
|
|
1790
|
-
return new CustomNetworkMap(network, entryPoints, bounds, name);
|
|
2001
|
+
return new CustomNetworkMap(graph, entryPoints, bounds, name);
|
|
1791
2002
|
}
|
|
1792
2003
|
isPointInside(coordinates) {
|
|
1793
|
-
return
|
|
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.
|
|
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.
|
|
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, "
|
|
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
|
|
1889
|
-
this.
|
|
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.
|
|
2099
|
+
if (!this._itinerary || !this._geoGraphProjectionHandler) {
|
|
1915
2100
|
return null;
|
|
1916
2101
|
}
|
|
1917
|
-
const projection = this.
|
|
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
|
|
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
|
|
1942
|
-
let firstNode = projection.nearestElement.
|
|
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.
|
|
1948
|
-
firstNode = projection.nearestElement.
|
|
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
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
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
|