@wemap/routers 12.10.8 → 12.11.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.
Files changed (170) hide show
  1. package/dist/helpers/InstructionManager.d.ts +20 -0
  2. package/dist/helpers/InstructionManagerV1.d.ts +7 -0
  3. package/{index.ts → dist/index.d.ts} +1 -11
  4. package/dist/index.js +1 -5099
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +100 -5
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/src/ItineraryInfoManager.d.ts +31 -0
  9. package/dist/src/RoutingError.d.ts +24 -0
  10. package/{src/StatusCode.ts → dist/src/StatusCode.d.ts} +2 -3
  11. package/dist/src/Utils.d.ts +6 -0
  12. package/dist/src/graph/Edge.d.ts +38 -0
  13. package/dist/src/graph/Graph.d.ts +40 -0
  14. package/dist/src/graph/GraphProjection.d.ts +11 -0
  15. package/dist/src/graph/GraphProjectionOptions.d.ts +7 -0
  16. package/dist/src/graph/GraphRoute.d.ts +19 -0
  17. package/dist/src/graph/GraphRouter.d.ts +20 -0
  18. package/dist/src/graph/GraphRouterEngine.d.ts +80 -0
  19. package/{src/graph/GraphRouterOptions.ts → dist/src/graph/GraphRouterOptions.d.ts} +6 -7
  20. package/dist/src/graph/GraphRouterOptionsBuilder.d.ts +23 -0
  21. package/dist/src/graph/GraphRouterOptionsFactors.d.ts +8 -0
  22. package/dist/src/graph/NoRouteFoundError.d.ts +12 -0
  23. package/dist/src/graph/Vertex.d.ts +19 -0
  24. package/dist/src/model/Itinerary.d.ts +81 -0
  25. package/dist/src/model/Leg.d.ts +66 -0
  26. package/dist/src/model/LevelChange.d.ts +7 -0
  27. package/dist/src/model/RouterRequest.d.ts +42 -0
  28. package/dist/src/model/Step.d.ts +42 -0
  29. package/dist/src/model/StepExtra.d.ts +3 -0
  30. package/dist/src/model/StepsBuilder.d.ts +16 -0
  31. package/dist/src/model/TransitMode.d.ts +5 -0
  32. package/{src/model/TravelMode.ts → dist/src/model/TravelMode.d.ts} +1 -2
  33. package/dist/src/model/generateSteps.d.ts +0 -0
  34. package/{src/remote/RemoteRouter.ts → dist/src/remote/RemoteRouter.d.ts} +2 -7
  35. package/dist/src/remote/RemoteRouterManager.d.ts +731 -0
  36. package/dist/src/remote/RemoteRouterUtils.d.ts +6 -0
  37. package/dist/src/remote/cityway/CitywayRemoteRouter.d.ts +109 -0
  38. package/dist/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.d.ts +31 -0
  39. package/dist/src/remote/geovelo/GeoveloRemoteRouter.d.ts +106 -0
  40. package/dist/src/remote/idfm/IdfmRemoteRouter.d.ts +123 -0
  41. package/dist/src/remote/navitia/NavitiaRemoteRouter.d.ts +34 -0
  42. package/dist/src/remote/navitia/types.d.ts +87 -0
  43. package/dist/src/remote/osrm/OsrmRemoteRouter.d.ts +70 -0
  44. package/dist/src/remote/otp/OtpRemoteRouter.d.ts +69 -0
  45. package/dist/src/remote/wemap-multi/WemapMultiRemoteRouter.d.ts +19 -0
  46. package/dist/src/types.d.ts +31 -0
  47. package/dist/src/wemap-multi/CustomGraphMap.d.ts +56 -0
  48. package/dist/src/wemap-multi/CustomGraphMapTester.d.ts +39 -0
  49. package/dist/src/wemap-multi/WemapMultiRouter.d.ts +14 -0
  50. package/dist/src/wemap-osm/OsmGraphUtils.d.ts +11 -0
  51. package/dist/tests/CommonTest.d.ts +8 -0
  52. package/package.json +11 -8
  53. package/assets/biocbon-bergere-rdc-network.osm +0 -163
  54. package/assets/bureaux-wemap-montpellier-network.osm +0 -174
  55. package/assets/components.osm +0 -146
  56. package/assets/elevator-models-4.osm +0 -89
  57. package/assets/elevator-models.osm +0 -354
  58. package/assets/exit-graph.osm +0 -25
  59. package/assets/gare-de-lest-network-pp-bounds.osm +0 -1613
  60. package/assets/gare-de-lyon-extract.osm +0 -174
  61. package/assets/geovelo-montpellier.json +0 -1144
  62. package/assets/horizontal-elevator.osm +0 -12
  63. package/assets/itinerary-deutsche-bahn-1.json +0 -368
  64. package/assets/itinerary-grenoble-otp-1.json +0 -1536
  65. package/assets/itinerary-grenoble-otp-2.json +0 -1092
  66. package/assets/itinerary-info-two-points-proj.osm +0 -39
  67. package/assets/itinerary-info-two-points.osm +0 -24
  68. package/assets/itinerary-lehavre-cityway-1.json +0 -6799
  69. package/assets/itinerary-lehavre-cityway-2.json +0 -2133
  70. package/assets/itinerary-lehavre-cityway-3.json +0 -12577
  71. package/assets/itinerary-lehavre-cityway-4.json +0 -1451
  72. package/assets/itinerary-lehavre-cityway-5.json +0 -5925
  73. package/assets/itinerary-lemans-navitia.json +0 -7768
  74. package/assets/itinerary-montpellier-osrm-3.json +0 -185
  75. package/assets/itinerary-montpellier-outdoor-without-steps.json +0 -110
  76. package/assets/itinerary-montpellier-outdoor.json +0 -513
  77. package/assets/itinerary-paris-idfm-2.json +0 -1838
  78. package/assets/itinerary-paris-idfm.json +0 -27727
  79. package/assets/itinerary-step-not-on-path-osrm.json +0 -457
  80. package/assets/itinerary-with-duplicate-nodes.json +0 -110
  81. package/assets/network-conveying-backward.osm +0 -74
  82. package/assets/network-elevator.osm +0 -48
  83. package/assets/network-escalators.osm +0 -50
  84. package/assets/network-simple.osm +0 -27
  85. package/assets/network-steps-same-level.osm +0 -283
  86. package/assets/network-with-modifiers.osm +0 -39
  87. package/assets/one-way.osm +0 -46
  88. package/assets/report-map-1.osm +0 -36
  89. package/assets/report-map-2.osm +0 -29
  90. package/assets/report-map-3.osm +0 -15
  91. package/assets/rr-wemap-multi-indoor-outdoor-indoor.json +0 -1352
  92. package/assets/rr-wemap-multi-indoor-outdoor.json +0 -145
  93. package/assets/rr-wemap-multi-multi-level.json +0 -262
  94. package/assets/rr-wemap-multi-outdoor-indoor.json +0 -145
  95. package/assets/rr-wemap-multi-outdoor-outdoor.json +0 -207
  96. package/assets/rr-wemap-multi-remote-indoor-indoor.json +0 -155
  97. package/assets/rr-wemap-multi-remote-indoor-outdoor-indoor.json +0 -668
  98. package/assets/rr-wemap-multi-remote-indoor-outdoor.json +0 -154
  99. package/assets/rr-wemap-multi-remote-outdoor-indoor.json +0 -179
  100. package/assets/rr-wemap-multi-remote-outdoor-outdoor.json +0 -109
  101. package/assets/stairs-and-exit.osm +0 -47
  102. package/helpers/InstructionManager.ts +0 -184
  103. package/helpers/InstructionManagerV1.ts +0 -95
  104. package/src/ItineraryInfoManager.spec.ts +0 -183
  105. package/src/ItineraryInfoManager.ts +0 -181
  106. package/src/RoutingError.ts +0 -60
  107. package/src/Utils.ts +0 -8
  108. package/src/graph/Edge.spec.ts +0 -32
  109. package/src/graph/Edge.ts +0 -64
  110. package/src/graph/Graph.spec.ts +0 -509
  111. package/src/graph/Graph.ts +0 -272
  112. package/src/graph/GraphProjection.ts +0 -15
  113. package/src/graph/GraphProjectionOptions.ts +0 -8
  114. package/src/graph/GraphRoute.spec.ts +0 -15
  115. package/src/graph/GraphRoute.ts +0 -43
  116. package/src/graph/GraphRouter.spec.ts +0 -317
  117. package/src/graph/GraphRouter.ts +0 -229
  118. package/src/graph/GraphRouterEngine.ts +0 -248
  119. package/src/graph/GraphRouterOptionsBuilder.ts +0 -98
  120. package/src/graph/NoRouteFoundError.ts +0 -39
  121. package/src/graph/Vertex.spec.ts +0 -42
  122. package/src/graph/Vertex.ts +0 -45
  123. package/src/model/Itinerary.spec.ts +0 -134
  124. package/src/model/Itinerary.ts +0 -370
  125. package/src/model/Leg.spec.ts +0 -107
  126. package/src/model/Leg.ts +0 -224
  127. package/src/model/LevelChange.spec.ts +0 -50
  128. package/src/model/LevelChange.ts +0 -14
  129. package/src/model/RouterRequest.ts +0 -33
  130. package/src/model/Step.spec.ts +0 -99
  131. package/src/model/Step.ts +0 -90
  132. package/src/model/StepExtra.ts +0 -1
  133. package/src/model/StepsBuilder.ts +0 -242
  134. package/src/model/TransitMode.spec.ts +0 -31
  135. package/src/model/TransitMode.ts +0 -28
  136. package/src/model/generateSteps.ts +0 -102
  137. package/src/remote/RemoteRouterManager.spec.ts +0 -178
  138. package/src/remote/RemoteRouterManager.ts +0 -72
  139. package/src/remote/RemoteRouterUtils.ts +0 -25
  140. package/src/remote/cityway/CitywayRemoteRouter.spec.ts +0 -122
  141. package/src/remote/cityway/CitywayRemoteRouter.ts +0 -435
  142. package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.spec.ts +0 -52
  143. package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.ts +0 -85
  144. package/src/remote/geovelo/GeoveloRemoteRouter.spec.ts +0 -54
  145. package/src/remote/geovelo/GeoveloRemoteRouter.ts +0 -293
  146. package/src/remote/idfm/IdfmRemoteRouter.spec.ts +0 -102
  147. package/src/remote/idfm/IdfmRemoteRouter.ts +0 -523
  148. package/src/remote/navitia/NavitiaRemoteRouter.spec.ts +0 -116
  149. package/src/remote/navitia/NavitiaRemoteRouter.ts +0 -445
  150. package/src/remote/navitia/types.ts +0 -73
  151. package/src/remote/osrm/OsrmRemoteRouter.spec.ts +0 -127
  152. package/src/remote/osrm/OsrmRemoteRouter.ts +0 -303
  153. package/src/remote/otp/OtpRemoteRouter.spec.ts +0 -103
  154. package/src/remote/otp/OtpRemoteRouter.ts +0 -223
  155. package/src/remote/wemap-multi/WemapMultiRemoteRouter.spec.ts +0 -103
  156. package/src/remote/wemap-multi/WemapMultiRemoteRouter.ts +0 -56
  157. package/src/types.ts +0 -32
  158. package/src/wemap-multi/CustomGraphMap.spec.ts +0 -40
  159. package/src/wemap-multi/CustomGraphMap.ts +0 -213
  160. package/src/wemap-multi/CustomGraphMapTester.spec.ts +0 -48
  161. package/src/wemap-multi/CustomGraphMapTester.ts +0 -90
  162. package/src/wemap-multi/WemapMultiRouter.spec.ts +0 -138
  163. package/src/wemap-multi/WemapMultiRouter.ts +0 -329
  164. package/src/wemap-osm/OsmGraphUtils.spec.ts +0 -165
  165. package/src/wemap-osm/OsmGraphUtils.ts +0 -173
  166. package/src/wemap-osm/OsmRouter.elevators.spec.ts +0 -106
  167. package/src/wemap-osm/OsmRouter.spec.ts +0 -292
  168. package/tests/CommonTest.ts +0 -78
  169. package/tsconfig.json +0 -3
  170. package/vite.config.ts +0 -4
@@ -1,523 +0,0 @@
1
- /* eslint-disable max-statements */
2
- import { Coordinates, Utils as GeoUtils } from '@wemap/geo';
3
- import Logger from '@wemap/logger';
4
-
5
- import Itinerary from '../../model/Itinerary.js';
6
- import Leg, { TransportInfo } from '../../model/Leg.js';
7
- import { dateWithTimeZone } from '../RemoteRouterUtils.js';
8
- import StepsBuilder from '../../model/StepsBuilder.js';
9
- import RemoteRouter from '../RemoteRouter.js';
10
- import { areTransitAndTravelModeConsistent, type TransitMode } from '../../model/TransitMode.js';
11
- import { type MinStepInfo } from '../../model/Step.js';
12
- import { RouterRequest } from '../../model/RouterRequest.js';
13
- import { RemoteRoutingError } from '../../RoutingError.js';
14
- import GeoveloRemoteRouter from '../geovelo/GeoveloRemoteRouter.js';
15
-
16
- type IdfmCoordinates = { lat: number | string, lon: number | string };
17
- type IdfmPath = {
18
- name: string,
19
- length: number
20
- } & ({ instruction_start_coordinate: IdfmCoordinates } | { via_uri: string });
21
-
22
- type IdfmWaypoint = { name: string }
23
- & (
24
- { stop_point: { coord: IdfmCoordinates } } |
25
- { address: { coord: IdfmCoordinates } } |
26
- { poi: { coord: IdfmCoordinates } }
27
- )
28
-
29
- type IdfmSection = {
30
- id: string;
31
- type: 'waiting' | 'transfer' | string,
32
- mode: string,
33
- departure_date_time: string,
34
- arrival_date_time: string,
35
- duration: number,
36
- geojson: {
37
- coordinates: [number, number][],
38
- properties: { length: number }[]
39
- },
40
- path: IdfmPath[],
41
- display_informations: {
42
- code: string,
43
- color: string,
44
- text_color: string,
45
- direction: string,
46
- physical_mode: string
47
- },
48
- from: IdfmWaypoint,
49
- to: IdfmWaypoint,
50
- vias?: {
51
- id: string;
52
- name: string;
53
- access_point: {
54
- id: string;
55
- name: string;
56
- coord: {
57
- lon: string;
58
- lat: string;
59
- },
60
- embedded_type: string;
61
- },
62
- is_entrance: boolean,
63
- is_exit: boolean,
64
- length: number,
65
- traversal_time: number,
66
- pathway_mode: number
67
- }[]
68
- }
69
- type IdfmJson = {
70
- journeys: {
71
- duration: number,
72
- departure_date_time: string,
73
- arrival_date_time: string,
74
- sections: IdfmSection[]
75
- }[],
76
- context: {
77
- timezone: string
78
- };
79
- error: {
80
- message?: string;
81
- }
82
- };
83
-
84
- type IdfmIntermediateStep = {
85
- name: string,
86
- distance: number
87
- };
88
-
89
- /**
90
- * List of all modes supported by the API
91
- * http://doc.navitia.io/#physical-mode
92
- */
93
-
94
- const transitModeCorrespondance = new Map<string, TransitMode>();
95
- transitModeCorrespondance.set('Air', 'AIRPLANE');
96
- transitModeCorrespondance.set('Boat', 'BOAT');
97
- transitModeCorrespondance.set('Bus', 'BUS');
98
- transitModeCorrespondance.set('BusRapidTransit', 'BUS');
99
- transitModeCorrespondance.set('Coach', 'BUS');
100
- transitModeCorrespondance.set('Ferry', 'FERRY');
101
- transitModeCorrespondance.set('Funicular', 'FUNICULAR');
102
- transitModeCorrespondance.set('LocalTrain', 'TRAIN');
103
- transitModeCorrespondance.set('LongDistanceTrain', 'TRAIN');
104
- transitModeCorrespondance.set('Metro', 'METRO');
105
- transitModeCorrespondance.set('Métro', 'METRO');
106
- transitModeCorrespondance.set('RailShuttle', 'TRAIN');
107
- transitModeCorrespondance.set('RapidTransit', 'BUS');
108
- transitModeCorrespondance.set('Shuttle', 'BUS');
109
- transitModeCorrespondance.set('SuspendedCableCar', 'FUNICULAR');
110
- transitModeCorrespondance.set('Taxi', 'TAXI');
111
- transitModeCorrespondance.set('Train', 'TRAIN');
112
- transitModeCorrespondance.set('RER', 'TRAIN');
113
- transitModeCorrespondance.set('Tramway', 'TRAM');
114
- transitModeCorrespondance.set('walking', 'WALK');
115
- transitModeCorrespondance.set('bike', 'BIKE');
116
-
117
- /**
118
- * List of transports modes
119
- */
120
- const TRANSPORT_IDS = [
121
- 'physical_mode:Air',
122
- 'physical_mode:Boat',
123
- 'physical_mode:Bus',
124
- 'physical_mode:BusRapidTransit',
125
- 'physical_mode:Coach',
126
- 'physical_mode:Ferry',
127
- 'physical_mode:Funicular',
128
- 'physical_mode:LocalTrain',
129
- 'physical_mode:LongDistanceTrain',
130
- 'physical_mode:Metro',
131
- 'physical_mode:RailShuttle',
132
- 'physical_mode:RapidTransit',
133
- 'physical_mode:Shuttle',
134
- 'physical_mode:SuspendedCableCar',
135
- 'physical_mode:Taxi',
136
- 'physical_mode:Train',
137
- 'physical_mode:Tramway'
138
- ];
139
-
140
- const apiKey = 'qWHj6ax6DMttG8DX6tH9CQARaiTgQ1Di';
141
-
142
-
143
- function jsonToCoordinates(json: IdfmCoordinates) {
144
- return new Coordinates(Number(json.lat), Number(json.lon));
145
- }
146
-
147
- function last<T>(array: T[]) {
148
- return array[array.length - 1];
149
- }
150
-
151
- /**
152
- * stringDate (e.g. 20211117T104516)
153
- */
154
- function dateStringToTimestamp(stringDate: string, timeZone: string) {
155
- const yearStr = stringDate.substr(0, 4);
156
- const monthStr = stringDate.substr(4, 2);
157
- const dayStr = stringDate.substr(6, 2);
158
- const hoursStr = stringDate.substr(9, 2);
159
- const minutesStr = stringDate.substr(11, 2);
160
- const secondsStr = stringDate.substr(13, 2);
161
-
162
- return dateWithTimeZone(
163
- Number(yearStr),
164
- Number(monthStr) - 1,
165
- Number(dayStr),
166
- Number(hoursStr),
167
- Number(minutesStr),
168
- Number(secondsStr),
169
- timeZone
170
- ).getTime();
171
- }
172
-
173
-
174
- /**
175
- * Singleton.
176
- */
177
- class IdfmRemoteRouter extends RemoteRouter {
178
-
179
- /**
180
- * @override
181
- */
182
- get rname() { return 'idfm' as const; }
183
-
184
-
185
- async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {
186
- const { travelMode } = routerRequest;
187
- if (travelMode === 'BIKE') {
188
- // IDFM does not support bike routing, we use Geovelo instead
189
- return GeoveloRemoteRouter.getItineraries('https://idfm.getwemap.com/marketplace/computedroutes', routerRequest);
190
- }
191
-
192
- const url = this.getURL(endpointUrl, routerRequest);
193
-
194
- const res = await (fetch(url, {
195
- method: 'GET',
196
- headers: { apiKey }
197
- }).catch(() => {
198
- throw RemoteRoutingError.unreachableServer(this.rname, url);
199
- }));
200
-
201
-
202
- const jsonResponse: IdfmJson = await res.json().catch(() => {
203
- throw RemoteRoutingError.responseNotParsing(this.rname, url);
204
- });
205
-
206
- // When IDFM failed to calculate an itinerary (ie. start or end
207
- // point is far from network), it respond a 404 with an error message
208
- // or a 200 with an error message
209
- if (jsonResponse && jsonResponse.error) {
210
- throw RemoteRoutingError.notFound(this.rname, jsonResponse.error.message);
211
- }
212
-
213
- const itineraries = this.parseResponse(jsonResponse);
214
-
215
- const sameModeFound = itineraries.some((itinerary) => areTransitAndTravelModeConsistent(itinerary.transitMode, routerRequest.travelMode));
216
-
217
- if (!sameModeFound) {
218
- throw RemoteRoutingError.notFound(
219
- this.rname,
220
- 'Selected mode of transport was not found for this itinerary.'
221
- )
222
- }
223
-
224
- return itineraries;
225
- }
226
-
227
- getURL(endpointUrl: string, routerRequest: RouterRequest) {
228
- const { origin, destination, waypoints, travelMode } = routerRequest;
229
-
230
- if ((waypoints || []).length > 0) {
231
- Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints?.length})`);
232
- }
233
-
234
- const url = new URL(endpointUrl);
235
-
236
- const coreParams = new URLSearchParams();
237
- coreParams.set('from', `${origin.longitude};${origin.latitude}`);
238
- coreParams.set('to', `${destination.longitude};${destination.latitude}`);
239
- coreParams.set('data_freshness', 'realtime');
240
-
241
- if (routerRequest.itineraryModifiers?.avoidStairs) {
242
- coreParams.set('wheelchair', 'true')
243
- }
244
-
245
- let queryParams: URLSearchParams = new URLSearchParams();
246
- switch (travelMode) {
247
- case 'WALK':
248
- queryParams = this.getWalkingQuery();
249
- break;
250
- case 'BIKE':
251
- queryParams = this.getBikeQuery();
252
- break;
253
- case 'CAR':
254
- queryParams = this.getCarQuery();
255
- break;
256
- default:
257
- break;
258
- }
259
-
260
- [coreParams, queryParams].map(params => {
261
- for (const pair of params.entries()) {
262
- url.searchParams.append(pair[0], pair[1]);
263
- }
264
- });
265
-
266
- return url.toString();
267
- }
268
-
269
- getCarQuery() {
270
- const urlSearchParams = new URLSearchParams();
271
-
272
- TRANSPORT_IDS.forEach((id) => {
273
- urlSearchParams.append('forbidden_uris[]', id);
274
- });
275
-
276
- urlSearchParams.append('first_section_mode[]', 'walking');
277
- urlSearchParams.append('first_section_mode[]', 'car');
278
- urlSearchParams.append('last_section_mode[]', 'walking');
279
- urlSearchParams.append('last_section_mode[]', 'car');
280
-
281
- return urlSearchParams;
282
- }
283
-
284
- getWalkingQuery() {
285
- const urlSearchParams = new URLSearchParams();
286
-
287
- TRANSPORT_IDS.forEach((id) => {
288
- urlSearchParams.append('forbidden_uris[]', id);
289
- });
290
-
291
- urlSearchParams.append('first_section_mode[]', 'walking');
292
- urlSearchParams.append('last_section_mode[]', 'walking');
293
-
294
- return urlSearchParams;
295
- }
296
-
297
- getBikeQuery() {
298
- const urlSearchParams = new URLSearchParams();
299
-
300
- TRANSPORT_IDS.forEach((id) => {
301
- urlSearchParams.append('forbidden_uris[]', id);
302
- });
303
-
304
- urlSearchParams.append('first_section_mode[]', 'bike');
305
- urlSearchParams.append('last_section_mode[]', 'bike');
306
-
307
- return urlSearchParams;
308
- }
309
-
310
-
311
- getSectionCoords(section: IdfmSection) {
312
- let from: IdfmCoordinates | undefined;
313
- let to: IdfmCoordinates | undefined;
314
-
315
- if ('stop_point' in section.from) {
316
- from = section.from.stop_point.coord;
317
- } else if ('address' in section.from) {
318
- from = section.from.address.coord;
319
- } else {
320
- from = section.from.poi.coord;
321
- }
322
-
323
- if ('stop_point' in section.to) {
324
- to = section.to.stop_point.coord;
325
- } else if ('address' in section.to) {
326
- to = section.to.address.coord;
327
- } else {
328
- to = section.to.poi.coord;
329
- }
330
-
331
- return {
332
- from: jsonToCoordinates(from),
333
- to: jsonToCoordinates(to)
334
- };
335
- }
336
-
337
- /**
338
- * Since the IDFM API does not provide coords for each step, we need to compute them
339
- * We trim the coordinates of the leg with the distance of each step and keep the last result as the coords of the step
340
- * @param {Leg} leg
341
- */
342
- findStepsCoord(legCoords: Coordinates[], steps: IdfmIntermediateStep[]) {
343
- const coords = legCoords;
344
-
345
- const duplicatedCoords = [...coords];
346
- let previousStep = steps[0];
347
- let accumulatedIndex = 0;
348
- const outputSteps = [];
349
-
350
- for (const [idx, step] of steps.entries()) {
351
- let newCoords: Coordinates;
352
-
353
- let _idCoordsInLeg;
354
-
355
- if (idx === 0) {
356
- _idCoordsInLeg = 0;
357
- newCoords = coords[0];
358
- } else if (idx === steps.length - 1) {
359
- _idCoordsInLeg = coords.length - 1;
360
- newCoords = last(coords);
361
- } else if (duplicatedCoords.length === 1) {
362
- accumulatedIndex++;
363
-
364
- _idCoordsInLeg = accumulatedIndex;
365
-
366
- newCoords = duplicatedCoords[0];
367
-
368
- coords[_idCoordsInLeg] = newCoords;
369
- } else {
370
- const result = GeoUtils.trimRoute(duplicatedCoords, duplicatedCoords[0], previousStep.distance);
371
- accumulatedIndex += result.length - 1;
372
-
373
- duplicatedCoords.splice(0, result.length - 1);
374
-
375
- _idCoordsInLeg = accumulatedIndex;
376
-
377
- newCoords = last(result);
378
-
379
- coords[_idCoordsInLeg] = newCoords;
380
- }
381
-
382
- outputSteps.push({
383
- ...step,
384
- coords: newCoords
385
- });
386
-
387
- previousStep = step;
388
- }
389
-
390
- return outputSteps;
391
- }
392
-
393
- findStepCoords(step: IdfmSection['path'][number], section: IdfmSection) {
394
- if ('instruction_start_coordinate' in step) {
395
- return jsonToCoordinates(step.instruction_start_coordinate);
396
- }
397
-
398
- const via = section.vias?.find(via => via.id === step.via_uri);
399
- if (via) {
400
- return jsonToCoordinates(via.access_point.coord);
401
- }
402
- }
403
-
404
- parseResponse(json: IdfmJson) {
405
-
406
- if (!json || !json.journeys) {
407
- throw RemoteRoutingError.notFound(this.rname, json.error?.message);
408
- }
409
-
410
- const itineraries = [];
411
-
412
- const timeZone = json.context.timezone;
413
-
414
- for (const jsonItinerary of json.journeys) {
415
-
416
- const legs = [];
417
-
418
- for (const jsonSection of jsonItinerary.sections) {
419
-
420
- if (jsonSection.type === 'waiting' || jsonSection.type === 'transfer') {
421
- continue;
422
- }
423
-
424
- const { from: startSection, to: endSection } = this.getSectionCoords(jsonSection);
425
-
426
- // A section can have multiple same coordinates, we need to remove them
427
- let existingCoords: string[] = [];
428
- const legCoords = jsonSection.geojson.coordinates.reduce((acc, [lon, lat]) => {
429
- if (!existingCoords.includes(`${lon}-${lat}`)) {
430
- existingCoords = existingCoords.concat(`${lon}-${lat}`);
431
- acc.push(new Coordinates(lat, lon));
432
- }
433
- return acc;
434
- }, [] as Coordinates[]);
435
-
436
- const stepsBuilder = new StepsBuilder().setStart(startSection).setEnd(endSection).setPathCoords(legCoords);
437
- let transportInfo: TransportInfo | undefined;
438
- let transitMode = transitModeCorrespondance.get(jsonSection.mode) as TransitMode;
439
-
440
- if (jsonSection.path) {
441
- const useIDFMSteps = jsonSection.path.every(step => 'instruction_start_coordinate' in step || step.via_uri);
442
- const idfmIntermediateSteps = [];
443
-
444
- for (const jsonPathLink of jsonSection.path) {
445
- let coords: Coordinates;
446
- if (useIDFMSteps) {
447
- coords = this.findStepCoords(jsonPathLink, jsonSection)!;
448
-
449
- const intermediateStep = {
450
- name: jsonPathLink.name,
451
- distance: jsonPathLink.length,
452
- coords
453
- };
454
-
455
- stepsBuilder.addStepInfo(intermediateStep);
456
- } else {
457
- idfmIntermediateSteps.push({
458
- name: jsonPathLink.name,
459
- distance: jsonPathLink.length,
460
- });
461
- }
462
- }
463
-
464
- if (!useIDFMSteps) {
465
- stepsBuilder.setStepsInfo(this.findStepsCoord(legCoords, idfmIntermediateSteps));
466
- }
467
- }
468
-
469
- if (jsonSection.type === 'public_transport') {
470
- transportInfo = {
471
- name: jsonSection.display_informations.code,
472
- routeColor: jsonSection.display_informations.color,
473
- routeTextColor: jsonSection.display_informations.text_color,
474
- directionName: jsonSection.display_informations.direction
475
- };
476
-
477
- transitMode = transitModeCorrespondance.get(jsonSection.display_informations.physical_mode) as TransitMode;
478
-
479
- const legStep: MinStepInfo = {
480
- coords: legCoords[0],
481
- name: transportInfo.directionName,
482
- distance: jsonSection.geojson.properties[0].length
483
- };
484
- stepsBuilder.setStepsInfo([legStep]);
485
- }
486
-
487
- const leg = new Leg({
488
- transitMode,
489
- duration: jsonSection.duration,
490
- startTime: dateStringToTimestamp(jsonSection.departure_date_time, timeZone),
491
- endTime: dateStringToTimestamp(jsonSection.arrival_date_time, timeZone),
492
- start: {
493
- name: jsonSection.from.name,
494
- coords: startSection
495
- },
496
- end: {
497
- name: jsonSection.to.name,
498
- coords: endSection
499
- },
500
- coords: legCoords,
501
- transportInfo,
502
- steps: stepsBuilder.build()
503
- });
504
- legs.push(leg);
505
- }
506
-
507
- const itinerary = new Itinerary({
508
- duration: jsonItinerary.duration,
509
- startTime: dateStringToTimestamp(jsonItinerary.departure_date_time, timeZone),
510
- endTime: dateStringToTimestamp(jsonItinerary.arrival_date_time, timeZone),
511
- origin: this.getSectionCoords(jsonItinerary.sections[0]).from,
512
- destination: this.getSectionCoords(last(jsonItinerary.sections)).to,
513
- legs
514
- });
515
-
516
- itineraries.push(itinerary);
517
- }
518
-
519
- return itineraries;
520
- }
521
- }
522
-
523
- export default new IdfmRemoteRouter();
@@ -1,116 +0,0 @@
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 NavitiaRemoteRouter from './NavitiaRemoteRouter.js';
10
- import { verifyStepsCoherence } from '../../model/Itinerary.spec.js';
11
- import { areTransitAndTravelModeConsistent } from '../../model/TransitMode.js';
12
-
13
- const { expect } = chai;
14
-
15
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
- const assetsPath = path.resolve(__dirname, '../../../assets');
17
-
18
- describe('NavitiaRouter - parseResponse', () => {
19
-
20
- it('Itineraries - 1', () => {
21
-
22
- const filePath = path.resolve(assetsPath, 'itinerary-lemans-navitia.json');
23
- const fileString = fs.readFileSync(filePath, 'utf8');
24
- const json = JSON.parse(fileString);
25
-
26
- const itineraries = NavitiaRemoteRouter.parseResponse(json);
27
- itineraries.forEach(verifyStepsCoherence);
28
-
29
- expect(itineraries.length).equal(5);
30
-
31
- const itinerary1 = itineraries[0];
32
- expect(itinerary1.origin.equals(new Coordinates(48.007274, 0.187574))).true;
33
- expect(itinerary1.destination.equals(new Coordinates(48.005228, 0.205664))).true;
34
- expect(itinerary1.distance).to.be.closeTo(1710, 1);
35
- expect(itinerary1.duration).equal(1140);
36
- expect(itinerary1.transitMode).equal('TRAM');
37
- // Do not work because of the input time format
38
- expect(itinerary1.startTime).equal(1722854691000);
39
- expect(itinerary1.endTime).equal(1722855831000);
40
- expect(itinerary1.legs.length).equal(3);
41
-
42
- expect(areTransitAndTravelModeConsistent(itinerary1.transitMode, 'TRANSIT')).is.true;
43
-
44
- const itinerary1leg1 = itinerary1.legs[0];
45
- // Do not work because of the input time format
46
- expect(itinerary1leg1.startTime).equal(1722854691000);
47
- expect(itinerary1leg1.endTime).equal(1722854885000);
48
- expect(itinerary1leg1.distance).to.be.closeTo(224, 1);
49
- expect(itinerary1leg1.transitMode).equal('WALK');
50
- expect(itinerary1leg1.transportInfo).is.null;
51
- expect(itinerary1leg1.start.name).equal('33 Rue Saint-Pavin des Champs (Le Mans)');
52
- expect(itinerary1leg1.start.coords.distanceTo(new Coordinates(48.007274, 0.187574))).to.be.closeTo(0, 1);
53
- expect(itinerary1leg1.end.name).equal('Lafayette (Le Mans)');
54
- expect(itinerary1leg1.end.coords.distanceTo(new Coordinates(48.006794, 0.190226))).to.be.closeTo(0, 1);
55
-
56
- const itinerary1leg2 = itinerary1.legs[1];
57
- expect(itinerary1leg2.transitMode).equal('TRAM');
58
- expect(itinerary1leg2.transportInfo).is.not.null;
59
- expect(itinerary1leg2.transportInfo?.name).equal('T1');
60
- expect(itinerary1leg2.transportInfo?.routeColor).equal('E5261D');
61
- expect(itinerary1leg2.transportInfo?.routeTextColor).equal('FFFFFF');
62
- expect(itinerary1leg2.transportInfo?.directionName).equal('Antarès - Stade Marie Marvingt (Le Mans)');
63
- });
64
-
65
- it('Itineraries - 2', () => {
66
-
67
- const filePath = path.resolve(assetsPath, 'itinerary-lemans-navitia.json');
68
- const fileString = fs.readFileSync(filePath, 'utf8');
69
- const json = JSON.parse(fileString);
70
-
71
- const itineraries = NavitiaRemoteRouter.parseResponse(json);
72
- itineraries.forEach(verifyStepsCoherence);
73
-
74
-
75
- const itinerary2 = itineraries[1];
76
- expect(itinerary2.origin.equals(new Coordinates(48.007274, 0.187574))).true;
77
- expect(itinerary2.destination.equals(new Coordinates(48.005228, 0.205664))).true;
78
- expect(itinerary2.distance).to.be.closeTo(1995, 1);
79
- expect(itinerary2.duration).equal(1452);
80
- expect(itinerary2.transitMode).equal('MULTI');
81
- // Do not work because of the input time format
82
- expect(itinerary2.startTime).equal(1722854691000);
83
- expect(itinerary2.endTime).equal(1722856143000);
84
- expect(itinerary2.legs.length).equal(4);
85
-
86
- expect(areTransitAndTravelModeConsistent(itinerary2.transitMode, 'TRANSIT')).is.true;
87
-
88
- const itinerary2leg1 = itinerary2.legs[0];
89
- // Do not work because of the input time format
90
- expect(itinerary2leg1.startTime).equal(1722854691000);
91
- expect(itinerary2leg1.endTime).equal(1722854885000);
92
- expect(itinerary2leg1.distance).to.be.closeTo(224, 1);
93
- expect(itinerary2leg1.transitMode).equal('WALK');
94
- expect(itinerary2leg1.transportInfo).is.null;
95
- expect(itinerary2leg1.start.name).equal('33 Rue Saint-Pavin des Champs (Le Mans)');
96
- expect(itinerary2leg1.start.coords.distanceTo(new Coordinates(48.007274, 0.187574))).to.be.closeTo(0, 1);
97
- expect(itinerary2leg1.end.name).equal('Lafayette (Le Mans)');
98
- expect(itinerary2leg1.end.coords.distanceTo(new Coordinates(48.006794, 0.190226))).to.be.closeTo(0, 1);
99
-
100
- const itinerary2leg2 = itinerary2.legs[1];
101
- expect(itinerary2leg2.transitMode).equal('TRAM');
102
- expect(itinerary2leg2.transportInfo).is.not.null;
103
- expect(itinerary2leg2.transportInfo?.name).equal('T1');
104
- expect(itinerary2leg2.transportInfo?.routeColor).equal('E5261D');
105
- expect(itinerary2leg2.transportInfo?.routeTextColor).equal('FFFFFF');
106
- expect(itinerary2leg2.transportInfo?.directionName).equal('Antarès - Stade Marie Marvingt (Le Mans)');
107
-
108
- const itinerary2leg3 = itinerary2.legs[2];
109
- expect(itinerary2leg3.transitMode).equal('BUS');
110
- expect(itinerary2leg3.transportInfo).is.not.null;
111
- expect(itinerary2leg3.transportInfo?.name).equal('6');
112
- expect(itinerary2leg3.transportInfo?.routeColor).equal('C3057F');
113
- expect(itinerary2leg3.transportInfo?.routeTextColor).equal('FFFFFF');
114
- expect(itinerary2leg3.transportInfo?.directionName).equal('St-Martin (Le Mans)');
115
- });
116
- });