@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,122 +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 CitywayRemoteRouter from './CitywayRemoteRouter.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('CitywayRemoteRouter - parseResponse', () => {
19
-
20
- it('Itineraries - 1', () => {
21
-
22
- const filePath = path.resolve(assetsPath, 'itinerary-lehavre-cityway-1.json');
23
- const fileString = fs.readFileSync(filePath, 'utf8');
24
- const json = JSON.parse(fileString);
25
-
26
- const itineraries = CitywayRemoteRouter.parseResponse(json);
27
- itineraries.forEach(verifyStepsCoherence);
28
-
29
- expect(itineraries.length).equal(3);
30
-
31
- const itinerary1 = itineraries[0];
32
- expect(itinerary1.origin.equals(new Coordinates(49.515093882362159, 0.093417496193663158))).true;
33
- expect(itinerary1.destination.equals(new Coordinates(49.5067090188444, 0.16948421154178309))).true;
34
- expect(itinerary1.distance).to.be.closeTo(6887, 1);
35
- expect(itinerary1.duration).equal(2379);
36
- expect(itinerary1.transitMode).equal('BUS');
37
- // Do not work because of the input time format
38
- expect(itinerary1.startTime).equal(1620659156000);
39
- expect(itinerary1.endTime).equal(1620661535000);
40
- expect(itinerary1.legs.length).equal(5);
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(1620659156000);
47
- expect(itinerary1leg1.endTime).equal(1620659340000);
48
- expect(itinerary1leg1.distance).to.be.closeTo(200.14, 0.1);
49
- expect(itinerary1leg1.transitMode).equal('WALK');
50
- expect(itinerary1leg1.transportInfo).is.null;
51
- expect(itinerary1leg1.start.name).equal('RUE DU QUARTIER NEUF');
52
- expect(itinerary1leg1.start.coords.equals(new Coordinates(49.515093882362159, 0.093417496193663158))).true;
53
- expect(itinerary1leg1.end.name).equal('T. Gautier');
54
- expect(itinerary1leg1.end.coords.equals(new Coordinates(49.5147550229, 0.0911025378))).true;
55
-
56
- const itinerary1leg2 = itinerary1.legs[1];
57
- expect(itinerary1leg2.transitMode).equal('BUS');
58
- expect(itinerary1leg2.transportInfo).is.not.null;
59
- expect(itinerary1leg2.transportInfo?.name).equal('03');
60
- expect(itinerary1leg2.transportInfo?.routeColor).equal('3FA435');
61
- expect(itinerary1leg2.transportInfo?.routeTextColor).is.null;
62
- expect(itinerary1leg2.transportInfo?.directionName).equal('Graville');
63
- });
64
-
65
- it('Itineraries - 2', () => {
66
- const filePath = path.resolve(assetsPath, 'itinerary-lehavre-cityway-2.json');
67
- const fileString = fs.readFileSync(filePath, 'utf8');
68
- const json = JSON.parse(fileString);
69
-
70
- const itineraries = CitywayRemoteRouter.parseResponse(json);
71
- itineraries.forEach(verifyStepsCoherence);
72
-
73
- expect(itineraries.length).equal(1);
74
- expect(itineraries[0].transitMode).equal('WALK');
75
- expect(areTransitAndTravelModeConsistent(itineraries[0].transitMode, 'WALK')).is.true;
76
-
77
- });
78
-
79
- it('Itineraries - 3', () => {
80
- const filePath = path.resolve(assetsPath, 'itinerary-lehavre-cityway-3.json');
81
- const fileString = fs.readFileSync(filePath, 'utf8');
82
- const json = JSON.parse(fileString);
83
-
84
- const itineraries = CitywayRemoteRouter.parseResponse(json);
85
- itineraries.forEach(verifyStepsCoherence);
86
-
87
- expect(itineraries[0].transitMode).equal('FUNICULAR');
88
- expect(itineraries[0].legs[1].transitMode).equal('FUNICULAR');
89
- expect(areTransitAndTravelModeConsistent(itineraries[0].transitMode, 'TRANSIT')).is.true;
90
-
91
- });
92
-
93
- it('Itineraries - 4', () => {
94
- const filePath = path.resolve(assetsPath, 'itinerary-lehavre-cityway-4.json');
95
- const fileString = fs.readFileSync(filePath, 'utf8');
96
- const json = JSON.parse(fileString);
97
-
98
- const itineraries = CitywayRemoteRouter.parseResponse(json);
99
- itineraries.forEach(verifyStepsCoherence);
100
-
101
- expect(itineraries[0].transitMode).equal('BIKE');
102
- expect(itineraries[0].legs[0].transitMode).equal('BIKE');
103
- expect(areTransitAndTravelModeConsistent(itineraries[0].transitMode, 'BIKE')).is.true;
104
- });
105
-
106
- it('Itineraries - 5', () => {
107
- const filePath = path.resolve(assetsPath, 'itinerary-lehavre-cityway-5.json');
108
- const fileString = fs.readFileSync(filePath, 'utf8');
109
- const json = JSON.parse(fileString);
110
-
111
- const itineraries = CitywayRemoteRouter.parseResponse(json);
112
- itineraries.forEach(verifyStepsCoherence);
113
-
114
- expect(itineraries[1].transitMode).equal('TRAM');
115
- expect(areTransitAndTravelModeConsistent(itineraries[1].transitMode, 'TRANSIT')).is.true;
116
-
117
- expect(itineraries[1].legs[1].transitMode).equal('TRAM');
118
- expect(itineraries[1].legs[1].transportInfo?.name).equal('B');
119
- });
120
-
121
- });
122
-
@@ -1,435 +0,0 @@
1
- import { Coordinates } from '@wemap/geo';
2
- import Logger from '@wemap/logger';
3
-
4
- import RemoteRouter from '../RemoteRouter.js';
5
- import Itinerary from '../../model/Itinerary.js';
6
- import Leg, { TransportInfo } from '../../model/Leg.js';
7
- import { dateWithTimeZone } from '../RemoteRouterUtils.js';
8
- import { TransitMode, isTransitModePublicTransport } from '../../model/TransitMode.js';
9
- import StepsBuilder from '../../model/StepsBuilder.js';
10
- import { type TravelMode } from '../../model/TravelMode.js';
11
- import { type RouterRequest } from '../../model/RouterRequest.js';
12
- import { RemoteRoutingError } from '../../RoutingError.js';
13
-
14
- type CitywayCoordinates = { Lat: number, Long: number };
15
- type CitywayLeg = {
16
- TransportMode: string,
17
- Duration: string,
18
- Departure: {
19
- Time: string,
20
- Site: {
21
- Name: string,
22
- Position: CitywayCoordinates
23
- },
24
- StopPlace: {
25
- Name: string,
26
- Position: CitywayCoordinates
27
- }
28
- },
29
- Arrival: {
30
- Time: string,
31
- Site: {
32
- Name: string,
33
- Position: CitywayCoordinates
34
- },
35
- StopPlace: {
36
- Name: string,
37
- Position: CitywayCoordinates
38
- }
39
- },
40
- Line: {
41
- Name: string,
42
- Number: string,
43
- Color: string,
44
- TextColor: string,
45
- },
46
- Destination: string,
47
- Distance: number,
48
- steps: {
49
- Step: {
50
- Geometry: string
51
- }[]
52
- },
53
- pathLinks: {
54
- PathLink: {
55
- Departure: {
56
- Site: {
57
- Name: string
58
- }
59
- },
60
- Distance: number,
61
- Geometry: string | 'Null'
62
- }[]
63
- }
64
- };
65
- type CitywayJson = {
66
- StatusCode: number,
67
- Message: string,
68
- Data: {
69
- response: {
70
- trips: {
71
- Trip: {
72
- Duration: string,
73
- Departure: {
74
- Time: string,
75
- Site: {
76
- Position: CitywayCoordinates
77
- }
78
- },
79
- Arrival: {
80
- Time: string,
81
- Site: {
82
- Position: CitywayCoordinates
83
- }
84
- },
85
- sections: {
86
- Section: {
87
- Leg?: CitywayLeg,
88
- PTRide: CitywayLeg
89
- }[]
90
- }
91
- }[]
92
- }
93
- },
94
- PlanTripType?: string
95
- }[],
96
- };
97
-
98
-
99
-
100
- function jsonToCoordinates(json: CitywayCoordinates) {
101
- return new Coordinates(json.Lat, json.Long);
102
- }
103
-
104
- function jsonDateToTimestamp(jsonDate: string) {
105
- const [dateStr, timeStr] = jsonDate.split(' ');
106
- const [dayStr, monthStr, yearStr] = dateStr.split('/');
107
- const [hoursStr, minutesStr, secondsStr] = timeStr.split(':');
108
-
109
- return dateWithTimeZone(
110
- Number(yearStr),
111
- Number(monthStr) - 1,
112
- Number(dayStr),
113
- Number(hoursStr),
114
- Number(minutesStr),
115
- Number(secondsStr)
116
- ).getTime();
117
- }
118
-
119
- /**
120
- * Input mode correspondance
121
- */
122
- const inputModeCorrespondance = new Map<TravelMode, string>();
123
- inputModeCorrespondance.set('CAR', 'Car');
124
- inputModeCorrespondance.set('WALK', 'Walk');
125
- inputModeCorrespondance.set('BIKE', 'Bike');
126
- inputModeCorrespondance.set('TRANSIT', 'PT');
127
-
128
-
129
- /**
130
- * List of all routing modes supported by the API
131
- */
132
- const transitModeCorrespondance = new Map<string, TransitMode>();
133
- transitModeCorrespondance.set('WALK', 'WALK');
134
- transitModeCorrespondance.set('BICYCLE', 'BIKE');
135
- transitModeCorrespondance.set('TRAMWAY', 'TRAM');
136
- transitModeCorrespondance.set('METRO', 'METRO');
137
- transitModeCorrespondance.set('FUNICULAR', 'FUNICULAR');
138
- transitModeCorrespondance.set('BUS', 'BUS');
139
- transitModeCorrespondance.set('COACH', 'BUS');
140
- transitModeCorrespondance.set('SCHOOL', 'BUS');
141
- transitModeCorrespondance.set('BUS_PMR', 'BUS');
142
- transitModeCorrespondance.set('MINIBUS', 'BUS');
143
- transitModeCorrespondance.set('TROLLEY_BUS', 'BUS');
144
- transitModeCorrespondance.set('TAXIBUS', 'BUS');
145
- transitModeCorrespondance.set('SHUTTLE', 'BUS');
146
- transitModeCorrespondance.set('TRAIN', 'TRAIN');
147
- transitModeCorrespondance.set('HST', 'TRAIN');
148
- transitModeCorrespondance.set('LOCAL_TRAIN', 'TRAIN');
149
- transitModeCorrespondance.set('AIR', 'AIRPLANE');
150
- transitModeCorrespondance.set('FERRY', 'BOAT');
151
- transitModeCorrespondance.set('TAXI', 'UNKNOWN');
152
- transitModeCorrespondance.set('CAR_POOL', 'UNKNOWN');
153
- transitModeCorrespondance.set('PRIVATE_VEHICLE', 'CAR');
154
- transitModeCorrespondance.set('SCOOTER', 'MOTO');
155
-
156
- /**
157
- * List of all plan trip supported by the API
158
- * Routing mode UNKNOWN means that the itinerary will not be parsed by the router
159
- */
160
- const planTripType = new Map();
161
- planTripType.set(0, 'BUS');
162
- planTripType.set(1, 'WALK');
163
- planTripType.set(2, 'BIKE');
164
- planTripType.set(3, 'CAR');
165
- planTripType.set(4, 'UNKNOWN');
166
- planTripType.set(5, 'UNKNOWN');
167
- planTripType.set(6, 'UNKNOWN');
168
- planTripType.set(7, 'UNKNOWN');
169
- planTripType.set(8, 'UNKNOWN');
170
- planTripType.set(9, 'UNKNOWN');
171
- planTripType.set(10, 'UNKNOWN');
172
- planTripType.set(11, 'UNKNOWN');
173
- planTripType.set(12, 'UNKNOWN');
174
- planTripType.set(13, 'UNKNOWN');
175
- planTripType.set(14, 'UNKNOWN');
176
-
177
- function parseWKTGeometry(wktGeometry: string) {
178
- const tmpCoordsStr = wktGeometry.match(/LINESTRING ?\((.*)\)/i);
179
- const tmpCoordsPt = wktGeometry.match(/POINT ?\((.*)\)/i);
180
-
181
- if (tmpCoordsPt) {
182
- const [lng, lat] = tmpCoordsPt[1].split(' ');
183
- return [new Coordinates(Number(lat), Number(lng))];
184
- }
185
-
186
- return (tmpCoordsStr as RegExpMatchArray)[1].split(',').map(str => {
187
- const sp = str.trim().split(' ');
188
- return new Coordinates(Number(sp[1]), Number(sp[0]));
189
- });
190
- }
191
-
192
- /**
193
- * Singleton.
194
- */
195
- class CitywayRemoteRouter extends RemoteRouter {
196
-
197
- get rname() { return 'cityway' as const; }
198
-
199
- async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {
200
- const url = this.getURL(endpointUrl, routerRequest);
201
- const res = await (fetch(url).catch(() => {
202
- throw RemoteRoutingError.unreachableServer(this.rname, url);
203
- }));
204
-
205
- const jsonResponse = await res.json().catch(() => {
206
- throw RemoteRoutingError.responseNotParsing(this.rname, url);
207
- });
208
- return this.parseResponse(jsonResponse);
209
- }
210
-
211
-
212
- getURL(endpointUrl: string, routerRequest: RouterRequest) {
213
-
214
- const { origin, destination, travelMode, waypoints } = routerRequest;
215
- const citywayMode = inputModeCorrespondance.get(travelMode);
216
- if (!citywayMode) {
217
- throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);
218
- }
219
-
220
- if ((waypoints || []).length > 0) {
221
- Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints?.length})`);
222
- }
223
-
224
- const fromPlace = `DepartureLatitude=${origin.latitude}&DepartureLongitude=${origin.longitude}`;
225
- const toPlace = `ArrivalLatitude=${destination.latitude}&ArrivalLongitude=${destination.longitude}`;
226
- const queryMode = `TripModes=${citywayMode}`;
227
-
228
- const url = new URL(endpointUrl);
229
- let { search } = url;
230
- search = (search ? `${search}&` : '?') + `${fromPlace}&${toPlace}&${queryMode}`;
231
-
232
- return `${url.origin}${url.pathname}${search}`;
233
- }
234
-
235
- /**
236
- * Generate multi itineraries from Cityway JSON
237
- * @example https://preprod.api.lia2.cityway.fr/journeyplanner/api/opt/PlanTrips/json?DepartureLatitude=49.51509388236216&DepartureLongitude=0.09341749619366316&ArrivalLatitude=49.5067090188444&ArrivalLongitude=0.1694842115417831&DepartureType=COORDINATES&ArrivalType=COORDINATES
238
- */
239
- parseResponse(json: CitywayJson) {
240
-
241
- if (json.StatusCode !== 200 || !json.Data || !json.Data.length) {
242
- throw RemoteRoutingError.notFound(this.rname, json.Message);
243
- }
244
-
245
- const itineraries = [];
246
-
247
- const allJsonTrips = json.Data.map(dataObj =>
248
- dataObj.response.trips.Trip.map(trip => ({
249
- ...trip,
250
- ...(dataObj.hasOwnProperty('PlanTripType') && { PlanTripType: dataObj.PlanTripType })
251
- }))
252
- ).flat();
253
-
254
- // eslint-disable-next-line no-labels
255
- itineraryLoop:
256
- for (const trip of allJsonTrips) {
257
-
258
- if (trip.hasOwnProperty('PlanTripType') && planTripType.get(trip.PlanTripType) === 'UNKNOWN') {
259
- continue;
260
- }
261
-
262
- const legs = []
263
- for (const jsonSection of trip.sections.Section) {
264
-
265
- const jsonLeg = jsonSection.Leg ? jsonSection.Leg : jsonSection.PTRide;
266
-
267
- const legMode = transitModeCorrespondance.get(jsonLeg.TransportMode)!;
268
- const legCoords: Coordinates[] = [];
269
- let legStart, legEnd;
270
- let transportInfo: TransportInfo | undefined;
271
- const stepsBuilder = new StepsBuilder();
272
-
273
- if (legMode === 'UNKNOWN') {
274
- // eslint-disable-next-line
275
- continue itineraryLoop;
276
- }
277
-
278
- if (legMode === 'WALK'
279
- || legMode === 'BIKE'
280
- || legMode === 'CAR') {
281
-
282
- legStart = {
283
- name: jsonLeg.Departure.Site.Name,
284
- coords: jsonToCoordinates(jsonLeg.Departure.Site.Position)
285
- };
286
- legEnd = {
287
- name: jsonLeg.Arrival.Site.Name,
288
- coords: jsonToCoordinates(jsonLeg.Arrival.Site.Position)
289
- };
290
-
291
- for (const jsonPathLink of jsonLeg.pathLinks.PathLink) {
292
- let stepCoords;
293
- // jsonPathLink.Geometry is either a POINT or a LINESTRING
294
- // or it can also be 'Null' as string
295
- if (jsonPathLink.Geometry && jsonPathLink.Geometry !== 'Null') {
296
- stepCoords = parseWKTGeometry(jsonPathLink.Geometry);
297
- } else {
298
- stepCoords = [legStart.coords, legEnd.coords];
299
- }
300
-
301
- stepCoords.forEach((coords, idx) => {
302
- if (
303
- idx !== 0
304
- || legCoords.length === 0
305
- || !legCoords[legCoords.length - 1].equals(coords)
306
- ) {
307
- legCoords.push(coords);
308
- }
309
- });
310
-
311
- stepsBuilder.addStepInfo({
312
- coords: stepCoords[0],
313
- distance: jsonPathLink.Distance,
314
- name: jsonPathLink.Departure.Site.Name
315
- });
316
- }
317
-
318
- // If it's last leg, create a last step because cityway doesn't use the end of itinerary as step
319
- if (jsonSection === trip.sections.Section[trip.sections.Section.length - 1]) {
320
- stepsBuilder.addStepInfo({
321
- coords: legCoords[legCoords.length - 1]
322
- });
323
- }
324
-
325
- } else if (isTransitModePublicTransport(legMode)) {
326
-
327
- legStart = {
328
- name: jsonLeg.Departure.StopPlace.Name,
329
- coords: jsonToCoordinates(jsonLeg.Departure.StopPlace.Position)
330
- };
331
- legEnd = {
332
- name: jsonLeg.Arrival.StopPlace.Name,
333
- coords: jsonToCoordinates(jsonLeg.Arrival.StopPlace.Position)
334
- };
335
-
336
- let transportName = jsonLeg.Line.Number;
337
- if (legMode === 'TRAM' && transportName.toLowerCase().includes('tram')) {
338
- // In order to remove the "TRAM " prefix.
339
- transportName = transportName.substr(5);
340
- }
341
-
342
- transportInfo = {
343
- name: transportName,
344
- routeColor: jsonLeg.Line.Color,
345
- routeTextColor: jsonLeg.Line.TextColor,
346
- directionName: jsonLeg.Destination
347
- };
348
-
349
- for (const jsonStep of jsonLeg.steps.Step) {
350
- const stepCoords = parseWKTGeometry(jsonStep.Geometry);
351
- stepCoords.forEach((coords, idx) => {
352
- if (
353
- idx !== 0
354
- || legCoords.length === 0
355
- || !legCoords[legCoords.length - 1].equals(coords)
356
- ) {
357
- legCoords.push(coords);
358
- }
359
- });
360
- }
361
-
362
- stepsBuilder.addStepInfo({
363
- coords: legCoords[0],
364
- name: jsonLeg.Line.Name,
365
- distance: jsonLeg.Distance,
366
- });
367
- } else {
368
- Logger.warn(`[CitywayParser] Unknown leg mode: ${jsonLeg.TransportMode}`);
369
- continue;
370
- }
371
-
372
- stepsBuilder.setStart(legStart.coords);
373
- stepsBuilder.setEnd(legEnd.coords);
374
- stepsBuilder.setPathCoords(legCoords);
375
-
376
- const leg = new Leg({
377
- transitMode: legMode,
378
- duration: this.parseDuration(jsonLeg.Duration),
379
- startTime: jsonDateToTimestamp(jsonLeg.Departure.Time),
380
- endTime: jsonDateToTimestamp(jsonLeg.Arrival.Time),
381
- coords: legCoords,
382
- start: legStart,
383
- end: legEnd,
384
- transportInfo,
385
- steps: stepsBuilder.build()
386
- });
387
-
388
- legs.push(leg);
389
- }
390
-
391
- const itinerary = new Itinerary({
392
- duration: this.parseDuration(trip.Duration),
393
- startTime: jsonDateToTimestamp(trip.Departure.Time),
394
- origin: jsonToCoordinates(trip.Departure.Site.Position),
395
- endTime: jsonDateToTimestamp(trip.Arrival.Time),
396
- destination: jsonToCoordinates(trip.Arrival.Site.Position),
397
- legs
398
- });
399
-
400
- itineraries.push(itinerary);
401
- }
402
-
403
- return itineraries;
404
- }
405
-
406
-
407
- /**
408
- * @param {string} iso8601Duration
409
- * @see https://stackoverflow.com/a/29153059/2239938
410
- */
411
- parseDuration(iso8601Duration: string) {
412
- const iso8601DurationRegex = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/;
413
-
414
- const matches = iso8601Duration.match(iso8601DurationRegex)!;
415
-
416
- // const sign = typeof matches[1] === 'undefined' ? '+' : '-',
417
- const years = typeof matches[2] === 'undefined' ? 0 : Number(matches[2]);
418
- const months = typeof matches[3] === 'undefined' ? 0 : Number(matches[3]);
419
- const weeks = typeof matches[4] === 'undefined' ? 0 : Number(matches[4]);
420
- const days = typeof matches[5] === 'undefined' ? 0 : Number(matches[5]);
421
- const hours = typeof matches[6] === 'undefined' ? 0 : Number(matches[6]);
422
- const minutes = typeof matches[7] === 'undefined' ? 0 : Number(matches[7]);
423
- const seconds = typeof matches[8] === 'undefined' ? 0 : Number(matches[8]);
424
-
425
- return seconds
426
- + minutes * 60
427
- + hours * 3600
428
- + days * 86400
429
- + weeks * (86400 * 7)
430
- + months * (86400 * 30)
431
- + years * (86400 * 365.25);
432
- }
433
- }
434
-
435
- export default new CitywayRemoteRouter();
@@ -1,52 +0,0 @@
1
- /* eslint-disable max-statements */
2
- import chai from 'chai';
3
- import chaiAlmost from 'chai-almost';
4
- import fs from 'fs';
5
- import path from 'path';
6
- import { fileURLToPath } from 'url';
7
-
8
- import { Coordinates } from '@wemap/geo';
9
-
10
- import DeutscheBahnRemoteRouter from './DeutscheBahnRemoteRouter.js';
11
- import { verifyStepsCoherence } from '../../model/Itinerary.spec.js';
12
-
13
- const { expect } = chai;
14
- chai.use(chaiAlmost(0.1));
15
-
16
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
17
- const assetsPath = path.resolve(__dirname, '../../../assets');
18
-
19
- describe('DeutscheBahnRemoteRouter - parseResponse', () => {
20
-
21
- it('Itineraries - 1', () => {
22
-
23
- const filePath = path.resolve(assetsPath, 'itinerary-deutsche-bahn-1.json');
24
- const fileString = fs.readFileSync(filePath, 'utf8');
25
- const json = JSON.parse(fileString);
26
-
27
- const origin = new Coordinates(52.5258473, 13.3683657, null, -10);
28
- const destination = new Coordinates(52.52499085853664, 13.369467296949914, null, 0);
29
-
30
- const itineraries = DeutscheBahnRemoteRouter.parseResponse(json, origin, destination);
31
- itineraries.forEach(verifyStepsCoherence);
32
-
33
- expect(itineraries.length).equal(1);
34
-
35
- const itinerary1 = itineraries[0];
36
- expect(itinerary1.origin.equals(origin)).true;
37
- expect(itinerary1.destination.equals(destination)).true;
38
- expect(itinerary1.coords.length).equal(77);
39
- expect(itinerary1.distance).closeTo(130, 1);
40
- expect(itinerary1.duration).closeTo(94, 1);
41
- expect(itinerary1.transitMode).equal('WALK');
42
-
43
- const itinerary1leg1 = itinerary1.legs[0];
44
- expect(itinerary1leg1.distance).closeTo(34.3, 0.1);
45
- expect(itinerary1leg1.transitMode).equal('WALK');
46
- expect(itinerary1leg1.start.name).is.null;
47
- // expect(itinerary1leg1.start.coords.equals(from)).true;
48
- expect(itinerary1leg1.end.name).is.null;
49
- // expect(itinerary1leg1.end.coords.equals(to)).true;
50
- });
51
-
52
- });
@@ -1,85 +0,0 @@
1
- import { Coordinates, Level } from '@wemap/geo';
2
-
3
- import RemoteRouter from '../RemoteRouter.js';
4
- import Itinerary from '../../model/Itinerary.js';
5
- import Leg from '../../model/Leg.js';
6
- import { type RouterRequest } from '../../model/RouterRequest.js';
7
- import { RemoteRoutingError } from '../../RoutingError.js';
8
-
9
- type DBJson = {
10
- segments: {
11
- fromLevel: number,
12
- toLevel: number,
13
- polyline: {
14
- lat: number,
15
- lon: number
16
- }[]
17
- }[]
18
- };
19
-
20
- /**
21
- * Singleton.
22
- */
23
- class DeutscheBahnRemoteRouter extends RemoteRouter {
24
-
25
- /**
26
- * @override
27
- */
28
- get rname() { return 'deutsche-bahn' as const; }
29
-
30
- /**
31
- * @override
32
- */
33
- async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {
34
- const url = this.getURL(endpointUrl, routerRequest);
35
- const res = await (fetch(url).catch(() => {
36
- throw RemoteRoutingError.unreachableServer(this.rname, url);
37
- }));
38
-
39
- const jsonResponse = await res.json().catch(() => {
40
- throw RemoteRoutingError.responseNotParsing(this.rname, url);
41
- });
42
- return this.parseResponse(jsonResponse, routerRequest.origin, routerRequest.destination);
43
- }
44
-
45
- getURL(endpointUrl: string, routerRequest: RouterRequest) {
46
- let url = endpointUrl + '/route/v1/walking/';
47
- const waypoints = [routerRequest.origin, ...routerRequest.waypoints || [], routerRequest.destination];
48
-
49
- url += waypoints.map(waypoint => {
50
- if (waypoint.level !== null) {
51
- const altitude = Level.isRange(waypoint.level) ? waypoint.level[0] : waypoint.level;
52
- return waypoint.longitude + ',' + waypoint.latitude + ',' + altitude;
53
- }
54
- return waypoint.longitude + ',' + waypoint.latitude;
55
- }).join(';');
56
-
57
- url += '?geometries=geojson&overview=full&steps=true';
58
-
59
- return url;
60
- }
61
-
62
- parseResponse(json: DBJson, origin: Coordinates, destination: Coordinates) {
63
-
64
- if (!json.segments) {
65
- throw RemoteRoutingError.notFound(this.rname);
66
- }
67
-
68
- const legs = json.segments.map(segment => {
69
- const level = Level.union(segment.fromLevel, segment.toLevel);
70
- const coords = segment.polyline.map(({ lon, lat }) =>
71
- new Coordinates(lat, lon, null, level)
72
- );
73
- return new Leg({
74
- transitMode: 'WALK',
75
- coords,
76
- start: { coords: coords[0] },
77
- end: { coords: coords[coords.length - 1] },
78
- })
79
- });
80
-
81
- return [new Itinerary({ origin, destination, legs })];
82
- }
83
- }
84
-
85
- export default new DeutscheBahnRemoteRouter();