@wemap/routers 6.2.2 → 7.0.0
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/assets/biocbon-bergere-rdc-network.osm +163 -0
- package/assets/gare-de-lest-network-pp-bounds.osm +1615 -0
- package/dist/wemap-routers.es.js +1811 -695
- package/dist/wemap-routers.es.js.map +1 -1
- package/index.js +13 -5
- package/package.json +9 -6
- package/src/Constants.js +4 -2
- package/src/ItineraryInfoManager.spec.js +2 -2
- package/src/Utils.js +0 -77
- package/src/model/Itinerary.js +41 -5
- package/src/model/Itinerary.spec.js +91 -0
- package/src/model/Itinerary.type.spec.js +3 -78
- package/src/model/Leg.js +89 -19
- package/src/model/Leg.spec.js +110 -0
- package/src/model/Leg.type.spec.js +48 -0
- package/src/model/LevelChange.js +14 -24
- package/src/model/LevelChange.spec.js +78 -0
- package/src/model/LevelChange.type.spec.js +26 -0
- package/src/model/RouterResponse.js +70 -1
- package/src/model/RouterResponse.spec.js +85 -0
- package/src/model/RouterResponse.type.spec.js +7 -4
- package/src/model/Step.js +45 -6
- package/src/model/Step.spec.js +100 -0
- package/src/model/Step.type.spec.js +52 -0
- package/src/remote/RemoteRouter.js +31 -0
- package/src/remote/RemoteRouterManager.js +84 -0
- package/src/remote/RemoteRouterOptions.js +25 -0
- package/src/remote/RemoteRouterServerUnreachable.js +10 -0
- package/src/remote/RemoteRouterUtils.js +78 -0
- package/src/remote/RoutingModeCorrespondanceNotFound.js +18 -0
- package/src/remote/cityway/CitywayRemoteRouter.js +386 -0
- package/src/{cityway/CitywayUtils.spec.js → remote/cityway/CitywayRemoteRouter.spec.js} +19 -18
- package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.js +143 -0
- package/src/{deutsche-bahn/DeutscheBahnRouterUtils.spec.js → remote/deutsche-bahn/DeutscheBahnRemoteRouter.spec.js} +7 -6
- package/src/remote/idfm/IdfmRemoteRouter.js +432 -0
- package/src/{idfm/IdfmUtils.spec.js → remote/idfm/IdfmRemoteRouter.spec.js} +7 -6
- package/src/remote/idfm/IdfmRemoteRouterTokenError.js +6 -0
- package/src/remote/osrm/OsrmRemoteRouter.js +331 -0
- package/src/{osrm/OsrmUtils.spec.js → remote/osrm/OsrmRemoteRouter.spec.js} +9 -15
- package/src/remote/otp/OtpRemoteRouter.js +222 -0
- package/src/{otp/OtpUtils.spec.js → remote/otp/OtpRemoteRouter.spec.js} +10 -9
- package/src/remote/wemap-meta/WemapMetaRemoteRouter.js +57 -0
- package/src/remote/wemap-meta/WemapMetaRemoteRouter.spec.js +22 -0
- package/src/remote/wemap-meta/WemapMetaRemoteRouterOptions.js +36 -0
- package/src/remote/wemap-meta/WemapMetaRemoteRouterPayload.js +44 -0
- package/src/wemap/WemapRouter.js +6 -0
- package/src/wemap/WemapRouterUtils.js +10 -4
- package/src/wemap/WemapStepsGeneration.js +36 -9
- package/src/wemap-meta/IOMap.js +191 -0
- package/src/wemap-meta/WemapMetaRouter.js +314 -0
- package/src/wemap-meta/WemapMetaRouter.spec.js +119 -0
- package/src/wemap-meta/WemapMetaRouterOptions.js +20 -0
- package/src/cityway/CitywayUtils.js +0 -252
- package/src/deutsche-bahn/DeutscheBahnRouterUtils.js +0 -91
- package/src/idfm/IdfmUtils.js +0 -247
- package/src/osrm/OsrmUtils.js +0 -269
- package/src/otp/OtpUtils.js +0 -150
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* eslint-disable max-statements */
|
|
2
|
+
|
|
3
|
+
import { Coordinates } from '@wemap/geo';
|
|
4
|
+
|
|
5
|
+
import RouterResponse from '../../model/RouterResponse.js';
|
|
6
|
+
import RemoteRouter from '../RemoteRouter.js';
|
|
7
|
+
import RemoteRouterServerUnreachable from '../RemoteRouterServerUnreachable.js';
|
|
8
|
+
import WemapMetaRemoteRouterOptions from './WemapMetaRemoteRouterOptions.js';
|
|
9
|
+
import WemapMetaRemoteRouterPayload from './WemapMetaRemoteRouterPayload.js';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Singleton.
|
|
14
|
+
*/
|
|
15
|
+
class WemapMetaRemoteRouter extends RemoteRouter {
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @override
|
|
19
|
+
*/
|
|
20
|
+
get rname() {
|
|
21
|
+
return 'wemap-meta';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {!string} endpointUrl
|
|
26
|
+
* @param {!string} mode see Constants.ROUTING_MODE
|
|
27
|
+
* @param {Array<Coordinates>} waypoints
|
|
28
|
+
* @param {?WemapMetaRemoteRouterOptions} options
|
|
29
|
+
* @returns {!RouterResponse}
|
|
30
|
+
* @throws {RemoteRouterServerUnreachable}
|
|
31
|
+
*/
|
|
32
|
+
async getItineraries(endpointUrl, mode, waypoints, options) {
|
|
33
|
+
|
|
34
|
+
const payload = new WemapMetaRemoteRouterPayload();
|
|
35
|
+
payload.waypoints = waypoints;
|
|
36
|
+
payload.mode = mode;
|
|
37
|
+
payload.options = options;
|
|
38
|
+
|
|
39
|
+
const res = await fetch(endpointUrl, {
|
|
40
|
+
method: 'POST',
|
|
41
|
+
headers: {
|
|
42
|
+
'Accept': 'application/json',
|
|
43
|
+
'Content-Type': 'application/json'
|
|
44
|
+
},
|
|
45
|
+
body: JSON.stringify(payload.toJson())
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (res.status !== 200) {
|
|
49
|
+
throw new RemoteRouterServerUnreachable(this.rname, endpointUrl);
|
|
50
|
+
}
|
|
51
|
+
const response = await res.json();
|
|
52
|
+
return RouterResponse.fromJson(response);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default new WemapMetaRemoteRouter();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* eslint-disable max-statements */
|
|
2
|
+
// import chai from 'chai';
|
|
3
|
+
// import fs from 'fs';
|
|
4
|
+
// import path from 'path';
|
|
5
|
+
// import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
// import { Coordinates } from '@wemap/geo';
|
|
8
|
+
|
|
9
|
+
// import CitywayUtils from './CitywayUtils.js';
|
|
10
|
+
|
|
11
|
+
// import { verifyRouterResponseData } from '../model/RouterResponse.type.spec.js';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
// const { expect } = chai;
|
|
15
|
+
|
|
16
|
+
// const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
|
|
18
|
+
// describe('CitywayUtils - createRouterResponseFromJson', () => {
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
// });
|
|
22
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import RemoteRouterOptions from '../RemoteRouterOptions.js';
|
|
2
|
+
|
|
3
|
+
class WemapMetaRemoteRouterOptions extends RemoteRouterOptions {
|
|
4
|
+
|
|
5
|
+
/** @type {!{name: string, endpointUrl: string}[]} */
|
|
6
|
+
remoteRouters = [];
|
|
7
|
+
|
|
8
|
+
/** @type {?(string[])} */
|
|
9
|
+
targetMaps = null;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @returns {object}
|
|
13
|
+
*/
|
|
14
|
+
toJson() {
|
|
15
|
+
const json = super.toJson();
|
|
16
|
+
json.remoteRouters = this.remoteRouters;
|
|
17
|
+
if (this.targetMaps) {
|
|
18
|
+
json.targetMaps = this.targetMaps;
|
|
19
|
+
}
|
|
20
|
+
return json;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {object}
|
|
25
|
+
* @returns {WemapMetaRemoteRouterOptions}
|
|
26
|
+
*/
|
|
27
|
+
static fromJson(json) {
|
|
28
|
+
const obj = new WemapMetaRemoteRouterOptions();
|
|
29
|
+
obj.useStairs = json.useStairs;
|
|
30
|
+
obj.remoteRouters = json.remoteRouters;
|
|
31
|
+
obj.targetMaps = json.targetMaps ? json.targetMaps : null;
|
|
32
|
+
return obj;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default WemapMetaRemoteRouterOptions;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Coordinates } from '@wemap/geo';
|
|
2
|
+
import WemapMetaRemoteRouterOptions from './WemapMetaRemoteRouterOptions.js';
|
|
3
|
+
|
|
4
|
+
class WemapMetaRemoteRouterPayload {
|
|
5
|
+
|
|
6
|
+
/** @type {!(Coordinates[])} */
|
|
7
|
+
waypoints;
|
|
8
|
+
|
|
9
|
+
/** @type {!string} */
|
|
10
|
+
mode;
|
|
11
|
+
|
|
12
|
+
/** @type {!WemapMetaRemoteRouterOptions} */
|
|
13
|
+
options = null;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @returns {object}
|
|
17
|
+
*/
|
|
18
|
+
toJson() {
|
|
19
|
+
const json = {
|
|
20
|
+
waypoints: this.waypoints.map(coords => coords.toCompressedJson()),
|
|
21
|
+
mode: this.mode
|
|
22
|
+
};
|
|
23
|
+
if (this.options) {
|
|
24
|
+
json.options = this.options.toJson();
|
|
25
|
+
}
|
|
26
|
+
return json;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {object}
|
|
31
|
+
* @returns {WemapMetaRemoteRouterPayload}
|
|
32
|
+
*/
|
|
33
|
+
static fromJson(json) {
|
|
34
|
+
const obj = new WemapMetaRemoteRouterPayload();
|
|
35
|
+
obj.waypoints = json.waypoints.map(coords => Coordinates.fromCompressedJson(coords));
|
|
36
|
+
obj.mode = json.mode;
|
|
37
|
+
if (json.options) {
|
|
38
|
+
obj.options = WemapMetaRemoteRouterOptions.fromJson(json.options);
|
|
39
|
+
}
|
|
40
|
+
return obj;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default WemapMetaRemoteRouterPayload;
|
package/src/wemap/WemapRouter.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { GraphItinerary } from '@wemap/geo';
|
|
2
2
|
import { OsmElement } from '@wemap/osm';
|
|
3
3
|
|
|
4
|
+
import Constants from '../Constants.js';
|
|
4
5
|
import Itinerary from '../model/Itinerary.js';
|
|
5
6
|
import Leg from '../model/Leg.js';
|
|
6
7
|
import WemapStepsGeneration from './WemapStepsGeneration.js';
|
|
@@ -10,17 +11,21 @@ import WemapStepsGeneration from './WemapStepsGeneration.js';
|
|
|
10
11
|
* @param {string} mode
|
|
11
12
|
* @returns {Leg}
|
|
12
13
|
*/
|
|
13
|
-
export function createLegFromGraphItinerary(graphItinerary,
|
|
14
|
+
export function createLegFromGraphItinerary(graphItinerary,
|
|
15
|
+
mode = Constants.ROUTING_MODE.WALK) {
|
|
14
16
|
|
|
15
17
|
const leg = new Leg();
|
|
16
18
|
|
|
17
|
-
leg.from = { coords: graphItinerary.start };
|
|
18
|
-
leg.to = { coords: graphItinerary.end };
|
|
19
|
+
leg.from = { coords: graphItinerary.start, name: null };
|
|
20
|
+
leg.to = { coords: graphItinerary.end, name: null };
|
|
19
21
|
leg.coords = graphItinerary.nodes.map(node => node.coords);
|
|
20
22
|
leg.distance = graphItinerary.edges.reduce((acc, edge) => acc + edge.length, 0);
|
|
21
23
|
leg.duration = graphItinerary.edgesWeights.reduce((acc, weight) => acc + weight, 0);
|
|
22
24
|
leg.mode = mode;
|
|
23
25
|
leg.steps = WemapStepsGeneration.fromGraphItinerary(graphItinerary);
|
|
26
|
+
leg.steps.forEach(step => {
|
|
27
|
+
step._idCoordsInLeg = leg.coords.findIndex(coords => coords === step.coords);
|
|
28
|
+
});
|
|
24
29
|
|
|
25
30
|
return leg;
|
|
26
31
|
}
|
|
@@ -30,7 +35,8 @@ export function createLegFromGraphItinerary(graphItinerary, mode = 'WALK') {
|
|
|
30
35
|
* @param {string} mode
|
|
31
36
|
* @returns {Itinerary}
|
|
32
37
|
*/
|
|
33
|
-
export function createItineraryFromGraphItinerary(graphItinerary,
|
|
38
|
+
export function createItineraryFromGraphItinerary(graphItinerary,
|
|
39
|
+
mode = Constants.ROUTING_MODE.WALK) {
|
|
34
40
|
|
|
35
41
|
const leg = createLegFromGraphItinerary(graphItinerary, mode);
|
|
36
42
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable complexity */
|
|
2
2
|
/* eslint-disable max-statements */
|
|
3
|
-
import { Coordinates, GraphItinerary } from '@wemap/geo';
|
|
3
|
+
import { Coordinates, Level, GraphItinerary, GraphNode, GraphUtils } from '@wemap/geo';
|
|
4
4
|
import { diffAngle, deg2rad } from '@wemap/maths';
|
|
5
5
|
import { OsmElement } from '@wemap/osm';
|
|
6
6
|
|
|
@@ -69,7 +69,7 @@ class WemapStepsGeneration {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
if (splitByLevel) {
|
|
72
|
-
currentStep.levelChange =
|
|
72
|
+
currentStep.levelChange = WemapStepsGeneration.levelChangefromTwoNodes(node, nextNode);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
steps.push(currentStep);
|
|
@@ -85,20 +85,47 @@ class WemapStepsGeneration {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
const lastNode = nodes[nodes.length - 1];
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
lastStep.number = steps.length + 1;
|
|
91
|
-
lastStep.previousBearing = previousBearing;
|
|
92
|
-
lastStep.distance = lastNode.coords.distanceTo(end);
|
|
88
|
+
|
|
89
|
+
// Create a last step if end is not on the network
|
|
93
90
|
if (!Coordinates.equalsTo(lastNode.coords, end)) {
|
|
91
|
+
const lastStep = new Step();
|
|
92
|
+
lastStep.coords = lastNode.coords;
|
|
93
|
+
lastStep.number = steps.length + 1;
|
|
94
|
+
lastStep.previousBearing = previousBearing;
|
|
95
|
+
lastStep.distance = lastNode.coords.distanceTo(end);
|
|
94
96
|
lastStep.nextBearing = lastNode.coords.bearingTo(end);
|
|
95
97
|
lastStep.angle = diffAngle(lastStep.previousBearing, lastStep.nextBearing + Math.PI);
|
|
98
|
+
steps.push(lastStep);
|
|
96
99
|
}
|
|
97
|
-
|
|
98
|
-
steps.
|
|
100
|
+
|
|
101
|
+
steps[steps.length - 1].lastStep = true;
|
|
99
102
|
|
|
100
103
|
return steps;
|
|
101
104
|
}
|
|
102
105
|
|
|
106
|
+
/**
|
|
107
|
+
* @param {GraphNode<OsmElement>} firstNode
|
|
108
|
+
* @param {GraphNode<OsmElement>} secondNode
|
|
109
|
+
* @returns {LevelChange}
|
|
110
|
+
*/
|
|
111
|
+
static levelChangefromTwoNodes(firstNode, secondNode) {
|
|
112
|
+
|
|
113
|
+
const levelChange = new LevelChange();
|
|
114
|
+
|
|
115
|
+
const edge = GraphUtils.getEdgeByNodes(firstNode.edges, firstNode, secondNode);
|
|
116
|
+
|
|
117
|
+
if (edge.builtFrom.isElevator) {
|
|
118
|
+
levelChange.type = 'elevator';
|
|
119
|
+
} else if (edge.builtFrom.isConveying) {
|
|
120
|
+
levelChange.type = 'conveyor';
|
|
121
|
+
} else if (edge.builtFrom.areStairs) {
|
|
122
|
+
levelChange.type = 'stairs';
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
levelChange.difference = Level.diff(firstNode.coords.level, secondNode.coords.level);
|
|
126
|
+
levelChange.direction = levelChange.difference > 0 ? 'up' : 'down';
|
|
127
|
+
|
|
128
|
+
return levelChange;
|
|
129
|
+
}
|
|
103
130
|
}
|
|
104
131
|
export default WemapStepsGeneration;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import pointInPolygon from '@turf/boolean-point-in-polygon';
|
|
2
|
+
import convexHullFn from '@turf/convex';
|
|
3
|
+
import { polygon as turfPolygon } from '@turf/helpers';
|
|
4
|
+
|
|
5
|
+
import { Coordinates, GraphNode, GraphRouter, Network, NoRouteFoundError } from '@wemap/geo';
|
|
6
|
+
import { OsmParser } from '@wemap/osm';
|
|
7
|
+
import { Itinerary, WemapNetworkUtils, WemapRouterOptions, WemapRouterUtils } from '@wemap/routers';
|
|
8
|
+
|
|
9
|
+
import Constants from '../Constants.js';
|
|
10
|
+
|
|
11
|
+
class IOMap {
|
|
12
|
+
|
|
13
|
+
/** @type {?string} */
|
|
14
|
+
name;
|
|
15
|
+
|
|
16
|
+
/** @type {!GraphRouter} */
|
|
17
|
+
router;
|
|
18
|
+
|
|
19
|
+
/** @type {!([number, number][])} */
|
|
20
|
+
bounds;
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/** @type {!(GraphNode[])} */
|
|
24
|
+
entryPoints;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {Network} network The network of the map
|
|
28
|
+
* @param {GraphNode[]} entryPoints The map vertex that can be used to go inside / outside a IOMap
|
|
29
|
+
* @param {Coordinates[]} bounds The bounds
|
|
30
|
+
* @param {string} name The name of the map
|
|
31
|
+
* @returns {IOMap}
|
|
32
|
+
*/
|
|
33
|
+
constructor(network, entryPoints, bounds = null, name = null) {
|
|
34
|
+
|
|
35
|
+
this.name = name;
|
|
36
|
+
this.router = new GraphRouter(network);
|
|
37
|
+
|
|
38
|
+
// Entry points
|
|
39
|
+
entryPoints.forEach(entryPoint => {
|
|
40
|
+
if (!network.nodes.includes(entryPoint)) {
|
|
41
|
+
throw new Error(`Cannot find entry point ${entryPoint.coords.toString()} in network "${name}"`);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
this.entryPoints = entryPoints;
|
|
45
|
+
|
|
46
|
+
// Bounds
|
|
47
|
+
if (bounds) {
|
|
48
|
+
this.bounds = turfPolygon([bounds.map(coords => [coords.lng, coords.lat])]);
|
|
49
|
+
} else {
|
|
50
|
+
const polygon = [network.nodes.map(node => [node.coords.lng, node.coords.lat])];
|
|
51
|
+
const convexHull = convexHullFn(polygon);
|
|
52
|
+
if (!convexHull) {
|
|
53
|
+
throw new Error(`Cannot calculate convexHull of network "${name}"`);
|
|
54
|
+
}
|
|
55
|
+
this.bounds = convexHull;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @param {string} osmXmlString
|
|
61
|
+
* @param {string} name
|
|
62
|
+
* @returns {IOMap}
|
|
63
|
+
*/
|
|
64
|
+
static fromOsmXml(osmXmlString, name = null) {
|
|
65
|
+
|
|
66
|
+
const osmModel = OsmParser.parseOsmXmlString(osmXmlString);
|
|
67
|
+
const network = WemapNetworkUtils.createNetworkFromOsmModel(osmModel);
|
|
68
|
+
|
|
69
|
+
const entryPoints = osmModel.nodes
|
|
70
|
+
.filter(({ tags }) => tags && tags['wemap:routing-io'])
|
|
71
|
+
.map(osmNode => network.getNodeByCoords(osmNode.coords));
|
|
72
|
+
if (entryPoints.some(el => el === null)
|
|
73
|
+
|| new Set(entryPoints).size !== entryPoints.length
|
|
74
|
+
) {
|
|
75
|
+
throw new Error('Cannot parse wemap:routing-io correctly');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const wayBounds = osmModel.ways.find(({ tags }) => tags['wemap:routing-bounds']);
|
|
79
|
+
if (!wayBounds) {
|
|
80
|
+
throw new Error('Search bounds is undefined. Please use OSM tag : "wemap:routing-bounds=yes"');
|
|
81
|
+
}
|
|
82
|
+
const bounds = wayBounds.nodes.map(node => node.coords);
|
|
83
|
+
return new IOMap(network, entryPoints, bounds, name);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @param {Coordinates} coordinates
|
|
88
|
+
* @returns {boolean}
|
|
89
|
+
*/
|
|
90
|
+
isPointInside(coordinates) {
|
|
91
|
+
return pointInPolygon([coordinates.lng, coordinates.lat], this.bounds);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get the list of entry points sorted by the lowest distance between:
|
|
96
|
+
* start -> entry point -> end
|
|
97
|
+
* (as the crow flies)
|
|
98
|
+
*
|
|
99
|
+
* @param {Coordinates} start
|
|
100
|
+
* @param {Coordinates} end
|
|
101
|
+
* @returns {GraphNode[]}
|
|
102
|
+
*/
|
|
103
|
+
getOrderedEntryPointsSortedByDistance(start, end) {
|
|
104
|
+
const entryPointsCopy = [...this.entryPoints];
|
|
105
|
+
return entryPointsCopy.sort((ep1, ep2) =>
|
|
106
|
+
+ ep1.coords.distanceTo(start) + ep1.coords.distanceTo(end)
|
|
107
|
+
- ep2.coords.distanceTo(start) - ep2.coords.distanceTo(end)
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Get the best itinerary from any entry point to an end coordinates.
|
|
113
|
+
*
|
|
114
|
+
* The algorithm works as following:
|
|
115
|
+
* 1 - Entry points are sorted using distance (as the crow flies) between start - entry point - end
|
|
116
|
+
* 2 - Try to calculate an itinerary from the first entry point to the end coordinates.
|
|
117
|
+
* 3 - If an itinerary is found, it is returned. Otherwise it tries from the next entry point.
|
|
118
|
+
*
|
|
119
|
+
* /!\ start is only used to sort the entry points (step 1).
|
|
120
|
+
*
|
|
121
|
+
* @param {Coordinates} start The start coordinates (which is outside the network)
|
|
122
|
+
* @param {Coordinates} end Then end coordinates (which is inside the network)
|
|
123
|
+
* @param {WemapRouterOptions} options
|
|
124
|
+
* @returns {Itinerary}
|
|
125
|
+
*/
|
|
126
|
+
getBestItineraryFromEntryPointsToEnd(start, end, options) {
|
|
127
|
+
|
|
128
|
+
const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);
|
|
129
|
+
for (const entryPoint of sortedEntryPoints) {
|
|
130
|
+
const itinerary = this.getItineraryInsideMap(entryPoint, end, options);
|
|
131
|
+
if (itinerary) {
|
|
132
|
+
return itinerary;
|
|
133
|
+
}
|
|
134
|
+
// no route found
|
|
135
|
+
}
|
|
136
|
+
throw new NoRouteFoundError(start, end,
|
|
137
|
+
`No route found from entry points to ${end.toString()} in map: ${this.name}`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get the best itinerary from start coordinates to any entry point.
|
|
144
|
+
*
|
|
145
|
+
* The algorithm works as following:
|
|
146
|
+
* 1 - Entry points are sorted using distance (as the crow flies) between start - entry point - end
|
|
147
|
+
* 2 - Try to calculate an itinerary from the start coordinates to the first entry point.
|
|
148
|
+
* 3 - If an itinerary is found, it is returned. Otherwise it tries to the next entry point.
|
|
149
|
+
*
|
|
150
|
+
* /!\ end is only used to sort the entry points (step 1).
|
|
151
|
+
*
|
|
152
|
+
* @param {Coordinates} start The start coordinates (which is inside the network)
|
|
153
|
+
* @param {Coordinates} end Then end coordinates (which is outside the network)
|
|
154
|
+
* @param {WemapRouterOptions} options
|
|
155
|
+
* @returns {Itinerary}
|
|
156
|
+
*/
|
|
157
|
+
getBestItineraryFromStartToEntryPoints(start, end, options) {
|
|
158
|
+
|
|
159
|
+
const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);
|
|
160
|
+
for (const entryPoint of sortedEntryPoints) {
|
|
161
|
+
const itinerary = this.getItineraryInsideMap(start, entryPoint, options);
|
|
162
|
+
if (itinerary) {
|
|
163
|
+
return itinerary;
|
|
164
|
+
}
|
|
165
|
+
// no route found
|
|
166
|
+
}
|
|
167
|
+
throw new NoRouteFoundError(start, end,
|
|
168
|
+
`No route found from ${start.toString()} to entry points in map: ${this.name}`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @param {Coordinates} start the start coordinates
|
|
174
|
+
* @param {Coordinates} end the end coordinates
|
|
175
|
+
* @param {WemapRouterOptions} options
|
|
176
|
+
* @returns {?Itinerary}
|
|
177
|
+
*/
|
|
178
|
+
getItineraryInsideMap(start, end, options) {
|
|
179
|
+
|
|
180
|
+
// Call the Wemap router to get the shortest path
|
|
181
|
+
const graphItinerary = this.router.getShortestPath(start, end, options);
|
|
182
|
+
if (graphItinerary === null) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Transform a network itinerary (nodes, edges...) to a router itinerary (legs, steps...)
|
|
187
|
+
return WemapRouterUtils.createItineraryFromGraphItinerary(graphItinerary, Constants.ROUTING_MODE.WALK);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export default IOMap;
|