@wemap/routers 12.10.8 → 12.10.9
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/helpers/InstructionManager.d.ts +20 -0
- package/dist/helpers/InstructionManagerV1.d.ts +7 -0
- package/{index.ts → dist/index.d.ts} +1 -11
- package/dist/index.js +1 -5099
- package/dist/index.js.map +1 -1
- package/dist/src/ItineraryInfoManager.d.ts +31 -0
- package/dist/src/RoutingError.d.ts +24 -0
- package/{src/StatusCode.ts → dist/src/StatusCode.d.ts} +2 -3
- package/dist/src/Utils.d.ts +6 -0
- package/dist/src/graph/Edge.d.ts +32 -0
- package/dist/src/graph/Graph.d.ts +40 -0
- package/dist/src/graph/GraphProjection.d.ts +11 -0
- package/dist/src/graph/GraphProjectionOptions.d.ts +7 -0
- package/dist/src/graph/GraphRoute.d.ts +19 -0
- package/dist/src/graph/GraphRouter.d.ts +20 -0
- package/dist/src/graph/GraphRouterEngine.d.ts +77 -0
- package/{src/graph/GraphRouterOptions.ts → dist/src/graph/GraphRouterOptions.d.ts} +5 -7
- package/dist/src/graph/GraphRouterOptionsBuilder.d.ts +20 -0
- package/dist/src/graph/NoRouteFoundError.d.ts +12 -0
- package/dist/src/graph/Vertex.d.ts +19 -0
- package/dist/src/model/Itinerary.d.ts +81 -0
- package/dist/src/model/Leg.d.ts +66 -0
- package/dist/src/model/LevelChange.d.ts +7 -0
- package/dist/src/model/RouterRequest.d.ts +40 -0
- package/dist/src/model/Step.d.ts +42 -0
- package/dist/src/model/StepExtra.d.ts +3 -0
- package/dist/src/model/StepsBuilder.d.ts +16 -0
- package/dist/src/model/TransitMode.d.ts +5 -0
- package/{src/model/TravelMode.ts → dist/src/model/TravelMode.d.ts} +1 -2
- package/dist/src/model/generateSteps.d.ts +0 -0
- package/{src/remote/RemoteRouter.ts → dist/src/remote/RemoteRouter.d.ts} +2 -7
- package/dist/src/remote/RemoteRouterManager.d.ts +731 -0
- package/dist/src/remote/RemoteRouterUtils.d.ts +6 -0
- package/dist/src/remote/cityway/CitywayRemoteRouter.d.ts +109 -0
- package/dist/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.d.ts +31 -0
- package/dist/src/remote/geovelo/GeoveloRemoteRouter.d.ts +106 -0
- package/dist/src/remote/idfm/IdfmRemoteRouter.d.ts +123 -0
- package/dist/src/remote/navitia/NavitiaRemoteRouter.d.ts +34 -0
- package/dist/src/remote/navitia/types.d.ts +87 -0
- package/dist/src/remote/osrm/OsrmRemoteRouter.d.ts +70 -0
- package/dist/src/remote/otp/OtpRemoteRouter.d.ts +69 -0
- package/dist/src/remote/wemap-multi/WemapMultiRemoteRouter.d.ts +19 -0
- package/dist/src/types.d.ts +31 -0
- package/dist/src/wemap-multi/CustomGraphMap.d.ts +56 -0
- package/dist/src/wemap-multi/CustomGraphMapTester.d.ts +39 -0
- package/dist/src/wemap-multi/WemapMultiRouter.d.ts +14 -0
- package/dist/src/wemap-osm/OsmGraphUtils.d.ts +11 -0
- package/dist/tests/CommonTest.d.ts +8 -0
- package/package.json +11 -8
- package/assets/biocbon-bergere-rdc-network.osm +0 -163
- package/assets/bureaux-wemap-montpellier-network.osm +0 -174
- package/assets/components.osm +0 -146
- package/assets/elevator-models-4.osm +0 -89
- package/assets/elevator-models.osm +0 -354
- package/assets/exit-graph.osm +0 -25
- package/assets/gare-de-lest-network-pp-bounds.osm +0 -1613
- package/assets/gare-de-lyon-extract.osm +0 -174
- package/assets/geovelo-montpellier.json +0 -1144
- package/assets/horizontal-elevator.osm +0 -12
- package/assets/itinerary-deutsche-bahn-1.json +0 -368
- package/assets/itinerary-grenoble-otp-1.json +0 -1536
- package/assets/itinerary-grenoble-otp-2.json +0 -1092
- package/assets/itinerary-info-two-points-proj.osm +0 -39
- package/assets/itinerary-info-two-points.osm +0 -24
- package/assets/itinerary-lehavre-cityway-1.json +0 -6799
- package/assets/itinerary-lehavre-cityway-2.json +0 -2133
- package/assets/itinerary-lehavre-cityway-3.json +0 -12577
- package/assets/itinerary-lehavre-cityway-4.json +0 -1451
- package/assets/itinerary-lehavre-cityway-5.json +0 -5925
- package/assets/itinerary-lemans-navitia.json +0 -7768
- package/assets/itinerary-montpellier-osrm-3.json +0 -185
- package/assets/itinerary-montpellier-outdoor-without-steps.json +0 -110
- package/assets/itinerary-montpellier-outdoor.json +0 -513
- package/assets/itinerary-paris-idfm-2.json +0 -1838
- package/assets/itinerary-paris-idfm.json +0 -27727
- package/assets/itinerary-step-not-on-path-osrm.json +0 -457
- package/assets/itinerary-with-duplicate-nodes.json +0 -110
- package/assets/network-conveying-backward.osm +0 -74
- package/assets/network-elevator.osm +0 -48
- package/assets/network-escalators.osm +0 -50
- package/assets/network-simple.osm +0 -27
- package/assets/network-steps-same-level.osm +0 -283
- package/assets/network-with-modifiers.osm +0 -39
- package/assets/one-way.osm +0 -46
- package/assets/report-map-1.osm +0 -36
- package/assets/report-map-2.osm +0 -29
- package/assets/report-map-3.osm +0 -15
- package/assets/rr-wemap-multi-indoor-outdoor-indoor.json +0 -1352
- package/assets/rr-wemap-multi-indoor-outdoor.json +0 -145
- package/assets/rr-wemap-multi-multi-level.json +0 -262
- package/assets/rr-wemap-multi-outdoor-indoor.json +0 -145
- package/assets/rr-wemap-multi-outdoor-outdoor.json +0 -207
- package/assets/rr-wemap-multi-remote-indoor-indoor.json +0 -155
- package/assets/rr-wemap-multi-remote-indoor-outdoor-indoor.json +0 -668
- package/assets/rr-wemap-multi-remote-indoor-outdoor.json +0 -154
- package/assets/rr-wemap-multi-remote-outdoor-indoor.json +0 -179
- package/assets/rr-wemap-multi-remote-outdoor-outdoor.json +0 -109
- package/assets/stairs-and-exit.osm +0 -47
- package/helpers/InstructionManager.ts +0 -184
- package/helpers/InstructionManagerV1.ts +0 -95
- package/src/ItineraryInfoManager.spec.ts +0 -183
- package/src/ItineraryInfoManager.ts +0 -181
- package/src/RoutingError.ts +0 -60
- package/src/Utils.ts +0 -8
- package/src/graph/Edge.spec.ts +0 -32
- package/src/graph/Edge.ts +0 -64
- package/src/graph/Graph.spec.ts +0 -509
- package/src/graph/Graph.ts +0 -272
- package/src/graph/GraphProjection.ts +0 -15
- package/src/graph/GraphProjectionOptions.ts +0 -8
- package/src/graph/GraphRoute.spec.ts +0 -15
- package/src/graph/GraphRoute.ts +0 -43
- package/src/graph/GraphRouter.spec.ts +0 -317
- package/src/graph/GraphRouter.ts +0 -229
- package/src/graph/GraphRouterEngine.ts +0 -248
- package/src/graph/GraphRouterOptionsBuilder.ts +0 -98
- package/src/graph/NoRouteFoundError.ts +0 -39
- package/src/graph/Vertex.spec.ts +0 -42
- package/src/graph/Vertex.ts +0 -45
- package/src/model/Itinerary.spec.ts +0 -134
- package/src/model/Itinerary.ts +0 -370
- package/src/model/Leg.spec.ts +0 -107
- package/src/model/Leg.ts +0 -224
- package/src/model/LevelChange.spec.ts +0 -50
- package/src/model/LevelChange.ts +0 -14
- package/src/model/RouterRequest.ts +0 -33
- package/src/model/Step.spec.ts +0 -99
- package/src/model/Step.ts +0 -90
- package/src/model/StepExtra.ts +0 -1
- package/src/model/StepsBuilder.ts +0 -242
- package/src/model/TransitMode.spec.ts +0 -31
- package/src/model/TransitMode.ts +0 -28
- package/src/model/generateSteps.ts +0 -102
- package/src/remote/RemoteRouterManager.spec.ts +0 -178
- package/src/remote/RemoteRouterManager.ts +0 -72
- package/src/remote/RemoteRouterUtils.ts +0 -25
- package/src/remote/cityway/CitywayRemoteRouter.spec.ts +0 -122
- package/src/remote/cityway/CitywayRemoteRouter.ts +0 -435
- package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.spec.ts +0 -52
- package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.ts +0 -85
- package/src/remote/geovelo/GeoveloRemoteRouter.spec.ts +0 -54
- package/src/remote/geovelo/GeoveloRemoteRouter.ts +0 -293
- package/src/remote/idfm/IdfmRemoteRouter.spec.ts +0 -102
- package/src/remote/idfm/IdfmRemoteRouter.ts +0 -523
- package/src/remote/navitia/NavitiaRemoteRouter.spec.ts +0 -116
- package/src/remote/navitia/NavitiaRemoteRouter.ts +0 -445
- package/src/remote/navitia/types.ts +0 -73
- package/src/remote/osrm/OsrmRemoteRouter.spec.ts +0 -127
- package/src/remote/osrm/OsrmRemoteRouter.ts +0 -303
- package/src/remote/otp/OtpRemoteRouter.spec.ts +0 -103
- package/src/remote/otp/OtpRemoteRouter.ts +0 -223
- package/src/remote/wemap-multi/WemapMultiRemoteRouter.spec.ts +0 -103
- package/src/remote/wemap-multi/WemapMultiRemoteRouter.ts +0 -56
- package/src/types.ts +0 -32
- package/src/wemap-multi/CustomGraphMap.spec.ts +0 -40
- package/src/wemap-multi/CustomGraphMap.ts +0 -213
- package/src/wemap-multi/CustomGraphMapTester.spec.ts +0 -48
- package/src/wemap-multi/CustomGraphMapTester.ts +0 -90
- package/src/wemap-multi/WemapMultiRouter.spec.ts +0 -138
- package/src/wemap-multi/WemapMultiRouter.ts +0 -329
- package/src/wemap-osm/OsmGraphUtils.spec.ts +0 -165
- package/src/wemap-osm/OsmGraphUtils.ts +0 -173
- package/src/wemap-osm/OsmRouter.elevators.spec.ts +0 -106
- package/src/wemap-osm/OsmRouter.spec.ts +0 -292
- package/tests/CommonTest.ts +0 -78
- package/tsconfig.json +0 -3
- package/vite.config.ts +0 -4
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import chai from 'chai';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { fileURLToPath } from 'url';
|
|
5
|
-
import fetchMock from 'fetch-mock';
|
|
6
|
-
|
|
7
|
-
import { Coordinates } from '@wemap/geo';
|
|
8
|
-
|
|
9
|
-
import CustomGraphMap from './CustomGraphMap.js';
|
|
10
|
-
import WemapMultiRouter from './WemapMultiRouter.js';
|
|
11
|
-
import OsrmRemoteRouter from '../remote/osrm/OsrmRemoteRouter.js';
|
|
12
|
-
import { type RouterRequest } from '../model/RouterRequest.js';
|
|
13
|
-
import { type RoutingFallbackStrategy } from '../remote/RemoteRouterManager.js';
|
|
14
|
-
|
|
15
|
-
const { expect } = chai;
|
|
16
|
-
|
|
17
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
18
|
-
const assetsPath = path.resolve(__dirname, '../../assets');
|
|
19
|
-
|
|
20
|
-
function mockFetchWithJsonAsset(assetName: string) {
|
|
21
|
-
fetchMock.restore();
|
|
22
|
-
fetchMock.mock('*', (() => {
|
|
23
|
-
const filePath = path.resolve(assetsPath, assetName);
|
|
24
|
-
const fileString = fs.readFileSync(filePath, 'utf8');
|
|
25
|
-
return JSON.parse(fileString);
|
|
26
|
-
})(),)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function createIOMapFromAsset(assetName: string) {
|
|
30
|
-
const filePath = path.resolve(__dirname, '../../assets/' + assetName);
|
|
31
|
-
const osmXmlString = fs.readFileSync(filePath, 'utf8');
|
|
32
|
-
const mapName = path.parse(assetName).name;
|
|
33
|
-
return CustomGraphMap.fromOsmXml(osmXmlString, mapName)!;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
describe('WemapMultiRouter', () => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
let router: WemapMultiRouter;
|
|
40
|
-
let garedelestMap: CustomGraphMap, biocbonMap: CustomGraphMap;
|
|
41
|
-
const travelMode = 'WALK';
|
|
42
|
-
const fallbackStrategy: RoutingFallbackStrategy = [{
|
|
43
|
-
name: OsrmRemoteRouter.rname,
|
|
44
|
-
endpointUrl: 'https://routing-orsm.getwemap.com'
|
|
45
|
-
}]
|
|
46
|
-
|
|
47
|
-
before(async () => {
|
|
48
|
-
|
|
49
|
-
router = new WemapMultiRouter();
|
|
50
|
-
|
|
51
|
-
biocbonMap = createIOMapFromAsset('biocbon-bergere-rdc-network.osm');
|
|
52
|
-
router.addIOMap(biocbonMap);
|
|
53
|
-
garedelestMap = createIOMapFromAsset('gare-de-lest-network-pp-bounds.osm');
|
|
54
|
-
router.addIOMap(garedelestMap);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
after(() => {
|
|
58
|
-
fetchMock.restore();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
it('indoor to indoor', async () => {
|
|
63
|
-
|
|
64
|
-
const request: RouterRequest = {
|
|
65
|
-
origin: new Coordinates(48.8725992, 2.343431),
|
|
66
|
-
destination: new Coordinates(48.8725694, 2.3433),
|
|
67
|
-
travelMode
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const itineraries = await router.getItineraries(request, fallbackStrategy, [biocbonMap]);
|
|
71
|
-
|
|
72
|
-
const osrmResponse = OsrmRemoteRouter.itineraryToOsrmJson(itineraries[0]);
|
|
73
|
-
expect(osrmResponse).is.not.null;
|
|
74
|
-
const routes = osrmResponse.routes!;
|
|
75
|
-
expect(routes.length).equals(1);
|
|
76
|
-
expect(routes[0].geometry.coordinates.length).equals(6);
|
|
77
|
-
expect(routes[0].legs).not.empty;
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('outdoor to outdoor', async () => {
|
|
81
|
-
|
|
82
|
-
const request: RouterRequest = {
|
|
83
|
-
origin: new Coordinates(48.8726513, 2.343449),
|
|
84
|
-
destination: new Coordinates(48.8726397, 2.3431657),
|
|
85
|
-
travelMode
|
|
86
|
-
};
|
|
87
|
-
mockFetchWithJsonAsset('rr-wemap-multi-outdoor-outdoor.json');
|
|
88
|
-
|
|
89
|
-
const itineraries = await router.getItineraries(request, fallbackStrategy, [biocbonMap]);
|
|
90
|
-
|
|
91
|
-
const osrmResponse = OsrmRemoteRouter.itineraryToOsrmJson(itineraries[0]);
|
|
92
|
-
expect(osrmResponse.routes![0].geometry.coordinates.length).equals(4);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('outdoor to indoor', async () => {
|
|
96
|
-
const request: RouterRequest = {
|
|
97
|
-
origin: new Coordinates(48.8726085, 2.3434289),
|
|
98
|
-
destination: new Coordinates(48.8725694, 2.3433),
|
|
99
|
-
travelMode
|
|
100
|
-
};
|
|
101
|
-
mockFetchWithJsonAsset('rr-wemap-multi-outdoor-indoor.json');
|
|
102
|
-
|
|
103
|
-
const itineraries = await router.getItineraries(request, fallbackStrategy, [biocbonMap]);
|
|
104
|
-
|
|
105
|
-
const osrmResponse = OsrmRemoteRouter.itineraryToOsrmJson(itineraries[0]);
|
|
106
|
-
expect(osrmResponse.routes![0].geometry.coordinates.length).equals(6);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('indoor to outdoor', async () => {
|
|
110
|
-
const request: RouterRequest = {
|
|
111
|
-
origin: new Coordinates(48.8725992, 2.343431),
|
|
112
|
-
destination: new Coordinates(48.8726513, 2.343449),
|
|
113
|
-
travelMode
|
|
114
|
-
};
|
|
115
|
-
mockFetchWithJsonAsset('rr-wemap-multi-indoor-outdoor.json');
|
|
116
|
-
|
|
117
|
-
const itineraries = await router.getItineraries(request, fallbackStrategy, [biocbonMap]);
|
|
118
|
-
|
|
119
|
-
const osrmResponse = OsrmRemoteRouter.itineraryToOsrmJson(itineraries[0]);
|
|
120
|
-
expect(osrmResponse.routes![0].geometry.coordinates.length).equals(6);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('indoor to outdoor to indoor', async () => {
|
|
124
|
-
|
|
125
|
-
const request: RouterRequest = {
|
|
126
|
-
origin: new Coordinates(48.8725992, 2.343431),
|
|
127
|
-
destination: new Coordinates(48.8772962, 2.3584458, null, 0),
|
|
128
|
-
travelMode
|
|
129
|
-
};
|
|
130
|
-
mockFetchWithJsonAsset('rr-wemap-multi-indoor-outdoor-indoor.json');
|
|
131
|
-
|
|
132
|
-
const itineraries = await router.getItineraries(request, fallbackStrategy, [biocbonMap, garedelestMap]);
|
|
133
|
-
|
|
134
|
-
const osrmResponse = OsrmRemoteRouter.itineraryToOsrmJson(itineraries[0]);
|
|
135
|
-
expect(osrmResponse.routes![0].geometry.coordinates.length).equals(77);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
});
|
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
/* eslint-disable complexity */
|
|
2
|
-
/* eslint-disable max-statements */
|
|
3
|
-
|
|
4
|
-
import CustomGraphMap from './CustomGraphMap.js';
|
|
5
|
-
import RemoteRouterManager, { type RoutingFallbackStrategy } from '../remote/RemoteRouterManager.js';
|
|
6
|
-
import Itinerary from '../model/Itinerary.js';
|
|
7
|
-
import WemapMultiRemoteRouter from '../remote/wemap-multi/WemapMultiRemoteRouter.js';
|
|
8
|
-
import GraphRoute from '../graph/GraphRoute.js';
|
|
9
|
-
import GraphRouterOptionsBuilder from '../graph/GraphRouterOptionsBuilder.js';
|
|
10
|
-
import { type RouterRequest } from '../model/RouterRequest.js';
|
|
11
|
-
import { RemoteRoutingError, WemapMultiRoutingError } from '../RoutingError.js';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class WemapMultiRouter {
|
|
15
|
-
|
|
16
|
-
maps: CustomGraphMap[] = [];
|
|
17
|
-
|
|
18
|
-
get rname() {
|
|
19
|
-
return 'wemap-multi';
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
addIOMap(customGraphMap: CustomGraphMap) {
|
|
23
|
-
this.maps.push(customGraphMap);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
removeIOMap(customGraphMap: CustomGraphMap) {
|
|
27
|
-
this.maps = this.maps.filter(map => map !== customGraphMap);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
removeAllMaps() {
|
|
31
|
-
this.maps = [];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
getMapByName(mapId: string) {
|
|
35
|
-
return this.maps.find(map => map.name === mapId);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async getItineraries(routerRequest: RouterRequest, fallbackStrategy: RoutingFallbackStrategy = [], targetMaps = this.maps): Promise<Itinerary[]> {
|
|
39
|
-
|
|
40
|
-
const { origin, destination } = routerRequest;
|
|
41
|
-
|
|
42
|
-
/*
|
|
43
|
-
* Here, we try to get the shortest path using io maps networks and a remote router server.
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* ----- 1 -----
|
|
48
|
-
* Parse function params
|
|
49
|
-
* -------------
|
|
50
|
-
*/
|
|
51
|
-
|
|
52
|
-
// Avoid cycles on remoteRouters
|
|
53
|
-
fallbackStrategy = fallbackStrategy.filter(({ name }) => name !== WemapMultiRemoteRouter.rname) || [];
|
|
54
|
-
|
|
55
|
-
/*
|
|
56
|
-
* ----- 2 -----
|
|
57
|
-
* Retrieve the IO maps to consider for this itinerary
|
|
58
|
-
* -------------
|
|
59
|
-
*
|
|
60
|
-
* By default, all maps in this.maps are considered
|
|
61
|
-
* If options.targetMaps is defined, only use this subset
|
|
62
|
-
*/
|
|
63
|
-
// const ioMapsToTest = this.getIoMapsFromOptions(options);
|
|
64
|
-
// TODO: map it with Wemap backend
|
|
65
|
-
const ioMapsToTest = targetMaps;
|
|
66
|
-
|
|
67
|
-
/*
|
|
68
|
-
* If there is no local map to test, use remote router directly.
|
|
69
|
-
* This should happen:
|
|
70
|
-
* 1 - this.maps is empty
|
|
71
|
-
* 2 - options.targetMaps is defined but empty
|
|
72
|
-
* 3 - intersection of this.maps and options.targetMaps is empty
|
|
73
|
-
*/
|
|
74
|
-
if (!ioMapsToTest.length) {
|
|
75
|
-
return await RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* ----- 3 -----
|
|
81
|
-
* Run the IO Maps - Remote Routers logic
|
|
82
|
-
* -------------
|
|
83
|
-
*
|
|
84
|
-
* For this purpose we have to consider 5 use cases
|
|
85
|
-
*
|
|
86
|
-
*/
|
|
87
|
-
|
|
88
|
-
let ioMapRoute: GraphRoute | null;
|
|
89
|
-
let ioMapItinerary: Itinerary;
|
|
90
|
-
|
|
91
|
-
// Find the first map where the "origin" is inside.
|
|
92
|
-
const mapWithOrigin = ioMapsToTest.find(map => map.isPointInside(origin));
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
// Create GraphRouterOptions from request
|
|
96
|
-
const routerOptions = GraphRouterOptionsBuilder.fromJson(routerRequest.itineraryModifiers || {});
|
|
97
|
-
|
|
98
|
-
/*
|
|
99
|
-
* Case 1
|
|
100
|
-
*
|
|
101
|
-
* If "origin" and "destination" are in the same map, use the local router.
|
|
102
|
-
*/
|
|
103
|
-
if (mapWithOrigin && mapWithOrigin.isPointInside(destination)) {
|
|
104
|
-
|
|
105
|
-
ioMapRoute = mapWithOrigin.getRouteInsideMap(origin, destination, routerOptions);
|
|
106
|
-
if (!ioMapRoute) {
|
|
107
|
-
throw WemapMultiRoutingError.notFound(mapWithOrigin.name || "")
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return [Itinerary.fromGraphRoute(ioMapRoute)];
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Find the first map where the "destination" is inside.
|
|
114
|
-
// Note: At this step, mapWithDestination is necessarily different from mapWithOrigin
|
|
115
|
-
const mapWithDestination = ioMapsToTest.find(map => map.isPointInside(destination));
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
let remoteRouterItineraries: Itinerary[];
|
|
119
|
-
|
|
120
|
-
/*
|
|
121
|
-
* Case 2
|
|
122
|
-
*
|
|
123
|
-
* If no io map have been found for "origin" and "destination", therefore use remote router.
|
|
124
|
-
*/
|
|
125
|
-
if (!mapWithOrigin && !mapWithDestination) {
|
|
126
|
-
return await RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Case 3
|
|
131
|
-
*
|
|
132
|
-
* If a map has been found for the "origin" but not for the "destination", so:
|
|
133
|
-
* - A first itinerary (firstRoute) is calculated from "origin" to an "entrypoint"
|
|
134
|
-
* of the IO map network using the wemap router.
|
|
135
|
-
* - A second itinerary (secondRoute) is calculated from an "entrypoint" to the
|
|
136
|
-
* "destination" using remote routers.
|
|
137
|
-
* Itinerary returned is the concatenation of the both itineraries.
|
|
138
|
-
*
|
|
139
|
-
* Note: Check the mapWithDestination.getBestItineraryFromEntryPointsToDestination to understand
|
|
140
|
-
* which "entrypoint" is chosen by the algorithm
|
|
141
|
-
*/
|
|
142
|
-
if (mapWithOrigin && !mapWithDestination) {
|
|
143
|
-
|
|
144
|
-
if (!mapWithOrigin.entryPoints.length) {
|
|
145
|
-
throw WemapMultiRoutingError.notFound(mapWithOrigin.name || '',
|
|
146
|
-
`A map including the "origin" but the "destination" has been
|
|
147
|
-
found (${mapWithOrigin.name}), however, no "entrypoints" have been found to go out`
|
|
148
|
-
)
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const customError = (details: string) => 'Tried to calculate an itinerary from "origin" '
|
|
152
|
-
+ `to "entrypoints" using wemap router on local map "${mapWithOrigin.name}" and `
|
|
153
|
-
+ 'an itinerary from "entrypoints" to "destination" using remote routers '
|
|
154
|
-
+ `(${fallbackStrategy.map(r => r.name).join(', ')}), but failed. `
|
|
155
|
-
+ `Details: ${details}.`;
|
|
156
|
-
|
|
157
|
-
ioMapRoute = mapWithOrigin.getBestRouteFromOriginToEntryPoints(origin, destination, routerOptions);
|
|
158
|
-
if (!ioMapRoute) {
|
|
159
|
-
const details = `No route found from ${origin.toString()} to entry points in map: ${mapWithOrigin.name}`;
|
|
160
|
-
throw WemapMultiRoutingError.notFound(mapWithOrigin.name || "", customError(details))
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const newRouterRequest: RouterRequest = {
|
|
164
|
-
...routerRequest,
|
|
165
|
-
origin: ioMapRoute.end,
|
|
166
|
-
destination,
|
|
167
|
-
waypoints: []
|
|
168
|
-
};
|
|
169
|
-
try {
|
|
170
|
-
remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);
|
|
171
|
-
} catch (e) {
|
|
172
|
-
if (e instanceof RemoteRoutingError) {
|
|
173
|
-
e.message = customError(e.message);
|
|
174
|
-
}
|
|
175
|
-
throw e;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Concat the the IO map itinerary with the remote router response (for each itinerary)
|
|
179
|
-
ioMapItinerary = Itinerary.fromGraphRoute(ioMapRoute);
|
|
180
|
-
return remoteRouterItineraries.map(
|
|
181
|
-
remoteRouterItinerary => Itinerary.fromItineraries(ioMapItinerary, remoteRouterItinerary)
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/*
|
|
186
|
-
* Case 4
|
|
187
|
-
*
|
|
188
|
-
* If a map has been found for the "destination" but not for the "origin", so:
|
|
189
|
-
* - A first itinerary (remoteRouterResponse) is calculated from "origin" to an "entrypoint"
|
|
190
|
-
* of the IO map network using remote routers.
|
|
191
|
-
* - A second itinerary (ioMapItinerary) is calculated from an "entrypoint" to the
|
|
192
|
-
* "destination" using the wemap router.
|
|
193
|
-
* Itinerary returned is the concatenation of the both itineraries.
|
|
194
|
-
*
|
|
195
|
-
* Note: Check the mapWithDestination.getBestItineraryFromEntryPointsToDestination to understand
|
|
196
|
-
* which "entrypoint" is chosen by the algorithm
|
|
197
|
-
*/
|
|
198
|
-
if (!mapWithOrigin && mapWithDestination) {
|
|
199
|
-
|
|
200
|
-
if (!mapWithDestination.entryPoints.length) {
|
|
201
|
-
throw WemapMultiRoutingError.notFound(mapWithDestination.name || '',
|
|
202
|
-
`A map including the "destination" but the "origin" has been
|
|
203
|
-
found (${mapWithDestination.name}), however, no "entrypoints" have been found to go in`
|
|
204
|
-
)
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const customError = (details: string) => 'Tried to calculate an itinerary from "origin" to "entrypoints" '
|
|
208
|
-
+ `using remote routers (${fallbackStrategy.map(r => r.name).join(', ')}) and an `
|
|
209
|
-
+ 'itinerary from "entrypoints" to "destination" using wemap router on local map '
|
|
210
|
-
+ `"${mapWithDestination.name}", but failed. `
|
|
211
|
-
+ `Details: ${details}.`
|
|
212
|
-
|
|
213
|
-
/*
|
|
214
|
-
* ioMapItinerary is computed before the remoteRouterResponse because it is less expensive to
|
|
215
|
-
* calculate all the routes to entrypoints using local router than all the routes with the
|
|
216
|
-
* remote router.
|
|
217
|
-
*/
|
|
218
|
-
ioMapRoute = mapWithDestination.getBestRouteFromEntryPointsToDestination(origin, destination, routerOptions);
|
|
219
|
-
if (!ioMapRoute) {
|
|
220
|
-
const details = `No route found from entry points to ${destination.toString()} in map: ${mapWithDestination.name}`;
|
|
221
|
-
throw WemapMultiRoutingError.notFound(mapWithDestination.name || "", customError(details))
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const newRouterRequest: RouterRequest = {
|
|
225
|
-
...routerRequest,
|
|
226
|
-
origin,
|
|
227
|
-
destination: ioMapRoute.start,
|
|
228
|
-
waypoints: []
|
|
229
|
-
};
|
|
230
|
-
try {
|
|
231
|
-
remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);
|
|
232
|
-
} catch (e) {
|
|
233
|
-
if (e instanceof RemoteRoutingError) {
|
|
234
|
-
e.message = customError(e.message);
|
|
235
|
-
}
|
|
236
|
-
throw e;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// Concat the remote router response (for each itinerary) with the IO map itinerary
|
|
240
|
-
ioMapItinerary = Itinerary.fromGraphRoute(ioMapRoute);
|
|
241
|
-
return remoteRouterItineraries.map(
|
|
242
|
-
remoteRouterItinerary => Itinerary.fromItineraries(remoteRouterItinerary, ioMapItinerary)
|
|
243
|
-
);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Case 5
|
|
248
|
-
*
|
|
249
|
-
* If maps have been found for the "origin" and the "destination" but they are different, so:
|
|
250
|
-
* - A first itinerary (ioMapItinerary1) is calculated from "origin" to an "entrypoint" of
|
|
251
|
-
* the mapWithOrigin using the wemap router.
|
|
252
|
-
* - A second itinerary (remoteRouterResponse) is calculated from an "entrypoint" of the
|
|
253
|
-
* mapWithOrigin to an "entrypoint" of the destinationWithMap using remote routers.
|
|
254
|
-
* - A third itinerary (ioMapItinerary2) is calculated from an "entrypoint" of the mapWithDestination
|
|
255
|
-
* to the "destination" using the wemap router.
|
|
256
|
-
* Itinerary returned is the concatenation of the three itineraries.
|
|
257
|
-
*/
|
|
258
|
-
if (mapWithOrigin && mapWithDestination) {
|
|
259
|
-
|
|
260
|
-
if (!mapWithOrigin.entryPoints.length) {
|
|
261
|
-
throw WemapMultiRoutingError.notFound(mapWithOrigin.name || '',
|
|
262
|
-
`One map including the "origin" (${mapWithOrigin.name}) and another
|
|
263
|
-
including the "destination" (${mapWithDestination.name}) has been found, however, no "entrypoints" have
|
|
264
|
-
been found to go out of the origin map`
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (!mapWithDestination.entryPoints.length) {
|
|
269
|
-
throw WemapMultiRoutingError.notFound(mapWithDestination.name || '',
|
|
270
|
-
`One map including the "origin" (${mapWithOrigin.name}) and another
|
|
271
|
-
including the "destination" (${mapWithDestination.name}) has been found, however, no "entrypoints" have
|
|
272
|
-
been found to go in the second map`
|
|
273
|
-
);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
const customError = (details: string) => 'Tried to calculate an itinerary from "origin" to "entrypoints1" '
|
|
277
|
-
+ `using wemap router on local map "${mapWithOrigin.name}", an itinerary from `
|
|
278
|
-
+ '"entrypoints1" to "entrypoints2" using remote routers '
|
|
279
|
-
+ `(${fallbackStrategy.map(r => r.name).join(', ')}) and an itinerary from "entrypoints2" `
|
|
280
|
-
+ `to "destination" using wemap router on local map "${mapWithDestination.name}", but failed. `
|
|
281
|
-
+ `Details: ${details}.`;
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
const ioMapRoute1 = mapWithOrigin.getBestRouteFromOriginToEntryPoints(origin, destination, routerOptions);
|
|
285
|
-
if (!ioMapRoute1) {
|
|
286
|
-
const details = `No route found from ${origin.toString()} to entry points in map: ${mapWithOrigin.name}`;
|
|
287
|
-
throw WemapMultiRoutingError.notFound(mapWithOrigin.name || "", customError(details))
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
const ioMapRoute2 = mapWithDestination.getBestRouteFromEntryPointsToDestination(origin, destination, routerOptions);
|
|
291
|
-
if (!ioMapRoute2) {
|
|
292
|
-
const details = `No route found from entry points to ${destination.toString()} in map: ${mapWithDestination.name}`;
|
|
293
|
-
throw WemapMultiRoutingError.notFound(mapWithDestination.name || "", customError(details))
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
const newRouterRequest: RouterRequest = {
|
|
297
|
-
...routerRequest,
|
|
298
|
-
origin: ioMapRoute1.end,
|
|
299
|
-
destination: ioMapRoute2.start,
|
|
300
|
-
waypoints: []
|
|
301
|
-
};
|
|
302
|
-
try {
|
|
303
|
-
remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);
|
|
304
|
-
} catch (e) {
|
|
305
|
-
if (e instanceof RemoteRoutingError) {
|
|
306
|
-
e.message = customError(e.message);
|
|
307
|
-
}
|
|
308
|
-
throw e;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
// Concat the IO map itinerary 2 with the remote router response (for each itinerary)
|
|
313
|
-
// and the IO map itinerary 2
|
|
314
|
-
return remoteRouterItineraries.map(remoteRouterItinerary =>
|
|
315
|
-
Itinerary.fromItineraries(
|
|
316
|
-
Itinerary.fromGraphRoute(ioMapRoute1),
|
|
317
|
-
remoteRouterItinerary,
|
|
318
|
-
Itinerary.fromGraphRoute(ioMapRoute2)
|
|
319
|
-
)
|
|
320
|
-
);
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
throw new Error('Should never happen');
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
export default WemapMultiRouter;
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import chai from 'chai';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import { describe, it } from 'mocha';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
|
|
7
|
-
import { OsmParser } from '@wemap/osm';
|
|
8
|
-
import { Level } from '@wemap/geo';
|
|
9
|
-
|
|
10
|
-
import { verifyCoherence } from '../../tests/CommonTest.js';
|
|
11
|
-
import OsmGraphUtils from './OsmGraphUtils.js';
|
|
12
|
-
|
|
13
|
-
const { expect } = chai;
|
|
14
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
15
|
-
|
|
16
|
-
const loadFile = (fileName: string) => {
|
|
17
|
-
const filePath = path.resolve(__dirname, '../../assets/' + fileName);
|
|
18
|
-
return fs.readFileSync(filePath, 'utf8');
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
describe('OsmGraph - simple', () => {
|
|
22
|
-
|
|
23
|
-
const osmXmlString = loadFile('network-simple.osm');
|
|
24
|
-
const osmModel = OsmParser.parseOsmXmlString(osmXmlString);
|
|
25
|
-
|
|
26
|
-
it('OsmGraph creation', () => {
|
|
27
|
-
|
|
28
|
-
const graph = OsmGraphUtils.createGraphFromOsmModel(osmModel);
|
|
29
|
-
|
|
30
|
-
verifyCoherence(graph);
|
|
31
|
-
expect(graph.vertices.length).equals(3);
|
|
32
|
-
expect(graph.edges.length).equals(2);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
it('OsmGraph creation - waySelectionFilter', () => {
|
|
37
|
-
|
|
38
|
-
const selectionGraph = OsmGraphUtils.createGraphFromOsmModel(osmModel, () => true);
|
|
39
|
-
|
|
40
|
-
verifyCoherence(selectionGraph);
|
|
41
|
-
expect(selectionGraph.vertices.length).equals(4);
|
|
42
|
-
expect(selectionGraph.edges.length).equals(3);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('OsmGraph creation - elevator', () => {
|
|
46
|
-
|
|
47
|
-
const elevatorModel = OsmParser.parseOsmXmlString(loadFile('network-elevator.osm'));
|
|
48
|
-
const elevatorGraph = OsmGraphUtils.createGraphFromOsmModel(elevatorModel);
|
|
49
|
-
|
|
50
|
-
verifyCoherence(elevatorGraph);
|
|
51
|
-
expect(elevatorGraph.vertices.length).equals(7);
|
|
52
|
-
expect(elevatorGraph.edges.length).equals(7);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// const osmModel = OsmParser.parseOsmXmlString(`
|
|
56
|
-
// <osm>
|
|
57
|
-
// <node id='1' lat='43' lon='4'>
|
|
58
|
-
// <tag k='highway' v='elevator' />
|
|
59
|
-
// <tag k='level' v='0;1' />
|
|
60
|
-
// </node>
|
|
61
|
-
// <node id='2' lat='43' lon='3' />
|
|
62
|
-
// <way id='3'>
|
|
63
|
-
// <nd ref='1' />
|
|
64
|
-
// <nd ref='2' />
|
|
65
|
-
// <tag k='highway' v='footway' />
|
|
66
|
-
// <tag k='level' v='0;1' />
|
|
67
|
-
// </way>
|
|
68
|
-
// </osm>
|
|
69
|
-
// `);
|
|
70
|
-
// expect(() => OsmGraphUtils.createGraphFromOsmModel(osmModel)).throw(Error);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('getVertexByName', () => {
|
|
74
|
-
const graph = OsmGraphUtils.createGraphFromOsmModel(osmModel);
|
|
75
|
-
|
|
76
|
-
let vertex = graph.getVertexByName('p1');
|
|
77
|
-
expect(vertex).not.undefined;
|
|
78
|
-
|
|
79
|
-
vertex = graph.getVertexByName('p5');
|
|
80
|
-
expect(vertex).is.undefined;
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
describe('OsmGraph - complex', () => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
it('with stairs', () => {
|
|
89
|
-
|
|
90
|
-
const osmXmlString = loadFile('bureaux-wemap-montpellier-network.osm');
|
|
91
|
-
const osmModel = OsmParser.parseOsmXmlString(osmXmlString);
|
|
92
|
-
const graph = OsmGraphUtils.createGraphFromOsmModel(osmModel);
|
|
93
|
-
|
|
94
|
-
verifyCoherence(graph);
|
|
95
|
-
|
|
96
|
-
expect(graph.getEdgeByName('w6')?.properties.areStairs).is.true;
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('exits', () => {
|
|
100
|
-
|
|
101
|
-
const osmXmlString = loadFile('exit-graph.osm');
|
|
102
|
-
const osmModel = OsmParser.parseOsmXmlString(osmXmlString);
|
|
103
|
-
const graph = OsmGraphUtils.createGraphFromOsmModel(osmModel);
|
|
104
|
-
|
|
105
|
-
verifyCoherence(graph);
|
|
106
|
-
|
|
107
|
-
expect(Level.equals(graph.getEdgeByName('e1')!.level, 0));
|
|
108
|
-
expect(Level.equals(graph.getEdgeByName('e2')!.level, null));
|
|
109
|
-
expect(Level.equals(graph.getVertexByName('p1')!.coords.level, 0));
|
|
110
|
-
expect(Level.equals(graph.getVertexByName('p2')!.coords.level, 0));
|
|
111
|
-
expect(Level.equals(graph.getVertexByName('p3')!.coords.level, null));
|
|
112
|
-
|
|
113
|
-
expect(graph.exitVertices.size).equals(1);
|
|
114
|
-
expect(graph.exitVertices.has(graph.getVertexByName('p2')!)).is.true;
|
|
115
|
-
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it('stairs & exit', () => {
|
|
119
|
-
|
|
120
|
-
const osmXmlString = loadFile('stairs-and-exit.osm');
|
|
121
|
-
const osmModel = OsmParser.parseOsmXmlString(osmXmlString);
|
|
122
|
-
const graph = OsmGraphUtils.createGraphFromOsmModel(osmModel);
|
|
123
|
-
|
|
124
|
-
verifyCoherence(graph);
|
|
125
|
-
|
|
126
|
-
expect(Level.equals(graph.getEdgeByName('e1')!.level, [0, 1]));
|
|
127
|
-
expect(Level.equals(graph.getEdgeByName('e2')!.level, 0));
|
|
128
|
-
expect(Level.equals(graph.getEdgeByName('e3')!.level, null));
|
|
129
|
-
expect(Level.equals(graph.getVertexByName('p1')!.coords.level, 1));
|
|
130
|
-
expect(Level.equals(graph.getVertexByName('p2')!.coords.level, 0));
|
|
131
|
-
expect(Level.equals(graph.getVertexByName('p3')!.coords.level, 0));
|
|
132
|
-
expect(Level.equals(graph.getVertexByName('p4')!.coords.level, null));
|
|
133
|
-
|
|
134
|
-
expect(graph.exitVertices.size).equals(1);
|
|
135
|
-
expect(graph.exitVertices.has(graph.getVertexByName('p3')!)).is.true;
|
|
136
|
-
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('escalators', () => {
|
|
140
|
-
|
|
141
|
-
const osmXmlString = loadFile('network-escalators.osm');
|
|
142
|
-
const osmModel = OsmParser.parseOsmXmlString(osmXmlString);
|
|
143
|
-
const graph = OsmGraphUtils.createGraphFromOsmModel(osmModel);
|
|
144
|
-
|
|
145
|
-
verifyCoherence(graph);
|
|
146
|
-
|
|
147
|
-
expect(graph.vertices.length).equals(4);
|
|
148
|
-
expect(graph.edges.length).equals(3);
|
|
149
|
-
graph.vertices.forEach(v => expect(v.coords.level).be.a("number"));
|
|
150
|
-
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it('horizontal elevator', () => {
|
|
154
|
-
|
|
155
|
-
const osmXmlString = loadFile('horizontal-elevator.osm');
|
|
156
|
-
const osmModel = OsmParser.parseOsmXmlString(osmXmlString);
|
|
157
|
-
const graph = OsmGraphUtils.createGraphFromOsmModel(osmModel);
|
|
158
|
-
|
|
159
|
-
verifyCoherence(graph);
|
|
160
|
-
|
|
161
|
-
expect(graph.vertices.length).equals(2);
|
|
162
|
-
expect(graph.edges.length).equals(1);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
});
|