@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.
Files changed (167) 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/src/ItineraryInfoManager.d.ts +31 -0
  7. package/dist/src/RoutingError.d.ts +24 -0
  8. package/{src/StatusCode.ts → dist/src/StatusCode.d.ts} +2 -3
  9. package/dist/src/Utils.d.ts +6 -0
  10. package/dist/src/graph/Edge.d.ts +32 -0
  11. package/dist/src/graph/Graph.d.ts +40 -0
  12. package/dist/src/graph/GraphProjection.d.ts +11 -0
  13. package/dist/src/graph/GraphProjectionOptions.d.ts +7 -0
  14. package/dist/src/graph/GraphRoute.d.ts +19 -0
  15. package/dist/src/graph/GraphRouter.d.ts +20 -0
  16. package/dist/src/graph/GraphRouterEngine.d.ts +77 -0
  17. package/{src/graph/GraphRouterOptions.ts → dist/src/graph/GraphRouterOptions.d.ts} +5 -7
  18. package/dist/src/graph/GraphRouterOptionsBuilder.d.ts +20 -0
  19. package/dist/src/graph/NoRouteFoundError.d.ts +12 -0
  20. package/dist/src/graph/Vertex.d.ts +19 -0
  21. package/dist/src/model/Itinerary.d.ts +81 -0
  22. package/dist/src/model/Leg.d.ts +66 -0
  23. package/dist/src/model/LevelChange.d.ts +7 -0
  24. package/dist/src/model/RouterRequest.d.ts +40 -0
  25. package/dist/src/model/Step.d.ts +42 -0
  26. package/dist/src/model/StepExtra.d.ts +3 -0
  27. package/dist/src/model/StepsBuilder.d.ts +16 -0
  28. package/dist/src/model/TransitMode.d.ts +5 -0
  29. package/{src/model/TravelMode.ts → dist/src/model/TravelMode.d.ts} +1 -2
  30. package/dist/src/model/generateSteps.d.ts +0 -0
  31. package/{src/remote/RemoteRouter.ts → dist/src/remote/RemoteRouter.d.ts} +2 -7
  32. package/dist/src/remote/RemoteRouterManager.d.ts +731 -0
  33. package/dist/src/remote/RemoteRouterUtils.d.ts +6 -0
  34. package/dist/src/remote/cityway/CitywayRemoteRouter.d.ts +109 -0
  35. package/dist/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.d.ts +31 -0
  36. package/dist/src/remote/geovelo/GeoveloRemoteRouter.d.ts +106 -0
  37. package/dist/src/remote/idfm/IdfmRemoteRouter.d.ts +123 -0
  38. package/dist/src/remote/navitia/NavitiaRemoteRouter.d.ts +34 -0
  39. package/dist/src/remote/navitia/types.d.ts +87 -0
  40. package/dist/src/remote/osrm/OsrmRemoteRouter.d.ts +70 -0
  41. package/dist/src/remote/otp/OtpRemoteRouter.d.ts +69 -0
  42. package/dist/src/remote/wemap-multi/WemapMultiRemoteRouter.d.ts +19 -0
  43. package/dist/src/types.d.ts +31 -0
  44. package/dist/src/wemap-multi/CustomGraphMap.d.ts +56 -0
  45. package/dist/src/wemap-multi/CustomGraphMapTester.d.ts +39 -0
  46. package/dist/src/wemap-multi/WemapMultiRouter.d.ts +14 -0
  47. package/dist/src/wemap-osm/OsmGraphUtils.d.ts +11 -0
  48. package/dist/tests/CommonTest.d.ts +8 -0
  49. package/package.json +11 -8
  50. package/assets/biocbon-bergere-rdc-network.osm +0 -163
  51. package/assets/bureaux-wemap-montpellier-network.osm +0 -174
  52. package/assets/components.osm +0 -146
  53. package/assets/elevator-models-4.osm +0 -89
  54. package/assets/elevator-models.osm +0 -354
  55. package/assets/exit-graph.osm +0 -25
  56. package/assets/gare-de-lest-network-pp-bounds.osm +0 -1613
  57. package/assets/gare-de-lyon-extract.osm +0 -174
  58. package/assets/geovelo-montpellier.json +0 -1144
  59. package/assets/horizontal-elevator.osm +0 -12
  60. package/assets/itinerary-deutsche-bahn-1.json +0 -368
  61. package/assets/itinerary-grenoble-otp-1.json +0 -1536
  62. package/assets/itinerary-grenoble-otp-2.json +0 -1092
  63. package/assets/itinerary-info-two-points-proj.osm +0 -39
  64. package/assets/itinerary-info-two-points.osm +0 -24
  65. package/assets/itinerary-lehavre-cityway-1.json +0 -6799
  66. package/assets/itinerary-lehavre-cityway-2.json +0 -2133
  67. package/assets/itinerary-lehavre-cityway-3.json +0 -12577
  68. package/assets/itinerary-lehavre-cityway-4.json +0 -1451
  69. package/assets/itinerary-lehavre-cityway-5.json +0 -5925
  70. package/assets/itinerary-lemans-navitia.json +0 -7768
  71. package/assets/itinerary-montpellier-osrm-3.json +0 -185
  72. package/assets/itinerary-montpellier-outdoor-without-steps.json +0 -110
  73. package/assets/itinerary-montpellier-outdoor.json +0 -513
  74. package/assets/itinerary-paris-idfm-2.json +0 -1838
  75. package/assets/itinerary-paris-idfm.json +0 -27727
  76. package/assets/itinerary-step-not-on-path-osrm.json +0 -457
  77. package/assets/itinerary-with-duplicate-nodes.json +0 -110
  78. package/assets/network-conveying-backward.osm +0 -74
  79. package/assets/network-elevator.osm +0 -48
  80. package/assets/network-escalators.osm +0 -50
  81. package/assets/network-simple.osm +0 -27
  82. package/assets/network-steps-same-level.osm +0 -283
  83. package/assets/network-with-modifiers.osm +0 -39
  84. package/assets/one-way.osm +0 -46
  85. package/assets/report-map-1.osm +0 -36
  86. package/assets/report-map-2.osm +0 -29
  87. package/assets/report-map-3.osm +0 -15
  88. package/assets/rr-wemap-multi-indoor-outdoor-indoor.json +0 -1352
  89. package/assets/rr-wemap-multi-indoor-outdoor.json +0 -145
  90. package/assets/rr-wemap-multi-multi-level.json +0 -262
  91. package/assets/rr-wemap-multi-outdoor-indoor.json +0 -145
  92. package/assets/rr-wemap-multi-outdoor-outdoor.json +0 -207
  93. package/assets/rr-wemap-multi-remote-indoor-indoor.json +0 -155
  94. package/assets/rr-wemap-multi-remote-indoor-outdoor-indoor.json +0 -668
  95. package/assets/rr-wemap-multi-remote-indoor-outdoor.json +0 -154
  96. package/assets/rr-wemap-multi-remote-outdoor-indoor.json +0 -179
  97. package/assets/rr-wemap-multi-remote-outdoor-outdoor.json +0 -109
  98. package/assets/stairs-and-exit.osm +0 -47
  99. package/helpers/InstructionManager.ts +0 -184
  100. package/helpers/InstructionManagerV1.ts +0 -95
  101. package/src/ItineraryInfoManager.spec.ts +0 -183
  102. package/src/ItineraryInfoManager.ts +0 -181
  103. package/src/RoutingError.ts +0 -60
  104. package/src/Utils.ts +0 -8
  105. package/src/graph/Edge.spec.ts +0 -32
  106. package/src/graph/Edge.ts +0 -64
  107. package/src/graph/Graph.spec.ts +0 -509
  108. package/src/graph/Graph.ts +0 -272
  109. package/src/graph/GraphProjection.ts +0 -15
  110. package/src/graph/GraphProjectionOptions.ts +0 -8
  111. package/src/graph/GraphRoute.spec.ts +0 -15
  112. package/src/graph/GraphRoute.ts +0 -43
  113. package/src/graph/GraphRouter.spec.ts +0 -317
  114. package/src/graph/GraphRouter.ts +0 -229
  115. package/src/graph/GraphRouterEngine.ts +0 -248
  116. package/src/graph/GraphRouterOptionsBuilder.ts +0 -98
  117. package/src/graph/NoRouteFoundError.ts +0 -39
  118. package/src/graph/Vertex.spec.ts +0 -42
  119. package/src/graph/Vertex.ts +0 -45
  120. package/src/model/Itinerary.spec.ts +0 -134
  121. package/src/model/Itinerary.ts +0 -370
  122. package/src/model/Leg.spec.ts +0 -107
  123. package/src/model/Leg.ts +0 -224
  124. package/src/model/LevelChange.spec.ts +0 -50
  125. package/src/model/LevelChange.ts +0 -14
  126. package/src/model/RouterRequest.ts +0 -33
  127. package/src/model/Step.spec.ts +0 -99
  128. package/src/model/Step.ts +0 -90
  129. package/src/model/StepExtra.ts +0 -1
  130. package/src/model/StepsBuilder.ts +0 -242
  131. package/src/model/TransitMode.spec.ts +0 -31
  132. package/src/model/TransitMode.ts +0 -28
  133. package/src/model/generateSteps.ts +0 -102
  134. package/src/remote/RemoteRouterManager.spec.ts +0 -178
  135. package/src/remote/RemoteRouterManager.ts +0 -72
  136. package/src/remote/RemoteRouterUtils.ts +0 -25
  137. package/src/remote/cityway/CitywayRemoteRouter.spec.ts +0 -122
  138. package/src/remote/cityway/CitywayRemoteRouter.ts +0 -435
  139. package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.spec.ts +0 -52
  140. package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.ts +0 -85
  141. package/src/remote/geovelo/GeoveloRemoteRouter.spec.ts +0 -54
  142. package/src/remote/geovelo/GeoveloRemoteRouter.ts +0 -293
  143. package/src/remote/idfm/IdfmRemoteRouter.spec.ts +0 -102
  144. package/src/remote/idfm/IdfmRemoteRouter.ts +0 -523
  145. package/src/remote/navitia/NavitiaRemoteRouter.spec.ts +0 -116
  146. package/src/remote/navitia/NavitiaRemoteRouter.ts +0 -445
  147. package/src/remote/navitia/types.ts +0 -73
  148. package/src/remote/osrm/OsrmRemoteRouter.spec.ts +0 -127
  149. package/src/remote/osrm/OsrmRemoteRouter.ts +0 -303
  150. package/src/remote/otp/OtpRemoteRouter.spec.ts +0 -103
  151. package/src/remote/otp/OtpRemoteRouter.ts +0 -223
  152. package/src/remote/wemap-multi/WemapMultiRemoteRouter.spec.ts +0 -103
  153. package/src/remote/wemap-multi/WemapMultiRemoteRouter.ts +0 -56
  154. package/src/types.ts +0 -32
  155. package/src/wemap-multi/CustomGraphMap.spec.ts +0 -40
  156. package/src/wemap-multi/CustomGraphMap.ts +0 -213
  157. package/src/wemap-multi/CustomGraphMapTester.spec.ts +0 -48
  158. package/src/wemap-multi/CustomGraphMapTester.ts +0 -90
  159. package/src/wemap-multi/WemapMultiRouter.spec.ts +0 -138
  160. package/src/wemap-multi/WemapMultiRouter.ts +0 -329
  161. package/src/wemap-osm/OsmGraphUtils.spec.ts +0 -165
  162. package/src/wemap-osm/OsmGraphUtils.ts +0 -173
  163. package/src/wemap-osm/OsmRouter.elevators.spec.ts +0 -106
  164. package/src/wemap-osm/OsmRouter.spec.ts +0 -292
  165. package/tests/CommonTest.ts +0 -78
  166. package/tsconfig.json +0 -3
  167. package/vite.config.ts +0 -4
@@ -1,272 +0,0 @@
1
- import { diffAngleLines } from '@wemap/maths';
2
- import { BoundingBox, Coordinates, Level, UserPosition, Level_t, Constants as GeoConstants } from '@wemap/geo';
3
-
4
- import Edge from './Edge.js';
5
- import GraphProjection from './GraphProjection.js';
6
- import Vertex from './Vertex.js';
7
- import { type CompressedGeoGraphJson, type GeoGraphJson } from '../types.js';
8
- import { type GraphProjectionOptions } from './GraphProjectionOptions.js';
9
-
10
-
11
- class Graph {
12
-
13
- /**
14
- * exitVertices are vertices that have at least one indoor edge and one outdoor edge
15
- * They are stored because the Level model cannot handle an indoor and outdoor state like [null, 1] or [null, [1,2]]
16
- * This vertices are used to cover the projection case:
17
- * - if projection origin is null, an exit vertex can be used
18
- * - if projection origin is not null, the intersection level with an exit vertex can be used
19
- */
20
- public readonly exitVertices: Set<Vertex>;
21
-
22
- constructor(public readonly vertices: Vertex[], public readonly edges: Edge[]) {
23
- const nullVertices = edges.filter(e => e.level === null).map(e => [e.vertex1, e.vertex2]).flat();
24
- const levelVertices = edges.filter(e => e.level !== null).map(e => [e.vertex1, e.vertex2]).flat();
25
- this.exitVertices = new Set(nullVertices.filter(v1 => levelVertices.includes(v1)));
26
- }
27
-
28
- getEdgeByVertices(vertex1: Vertex, vertex2: Vertex) {
29
- return Edge.getEdgeByVertices(this.edges, vertex1, vertex2);
30
- }
31
-
32
- getVertexByCoords(coords: Coordinates) {
33
- return Graph.getVertexByCoords(this.vertices, coords);
34
- }
35
-
36
- static getVertexByCoords(vertices: Vertex[], coords: Coordinates) {
37
- return vertices.find(vertex => vertex.coords.equals(coords));
38
- }
39
-
40
- getVertexByName(name: string) {
41
- return this.vertices.find(vertex => vertex.properties.name === name);
42
- }
43
-
44
- getEdgeByName(name: string) {
45
- return this.edges.find(edge => edge.properties.name === name);
46
- }
47
-
48
- getBoundingBox(extendedMeasure?: number) {
49
- if (!this.vertices.length) {
50
- return null;
51
- }
52
- const boundingBox = BoundingBox.fromCoordinates(this.vertices.map(vertex => vertex.coords)) as BoundingBox;
53
- if (extendedMeasure) {
54
- boundingBox.extendsWithMeasure(extendedMeasure);
55
- }
56
- return boundingBox;
57
- }
58
-
59
- getProjection<U extends (Coordinates | UserPosition)>(
60
- origin: U,
61
- options: GraphProjectionOptions = {}
62
- ): GraphProjection<U> | null {
63
-
64
- const useMaxDistance = 'maxDistance' in options;
65
- const maxDistance = options.maxDistance!
66
-
67
- const useMaxBearingAngle = 'maxBearingAngle' in options;
68
- if (useMaxBearingAngle && (!(origin instanceof UserPosition) || origin.bearing === null)) return null;
69
- const maxBearingAngle = options.maxBearingAngle!;
70
-
71
- const useAcceptEdgeFn = 'acceptEdgeFn' in options;
72
-
73
- const useMultiLevelSegments = !('useMultiLevelSegments' in options) || options.useMultiLevelSegments;
74
-
75
- let bestProjection: GraphProjection<U> | null = null;
76
-
77
- // (for as any) See. https://www.totaltypescript.com/any-considered-harmful#returning-conditional-types-from-generic-functions
78
- const adaptProjectionCoords = (projCoords: Coordinates): U => {
79
- if (!(origin instanceof UserPosition)) return projCoords as any;
80
- const p = origin.clone();
81
- p.lat = projCoords.lat;
82
- p.lng = projCoords.lng;
83
- p.level = projCoords.level;
84
- p.alt = projCoords.alt;
85
- p.heightFromFloor = projCoords.heightFromFloor;
86
- p.heightFromGround = projCoords.heightFromGround;
87
- return p as any;
88
- }
89
-
90
- this.edges.forEach(edge => {
91
-
92
- if (useAcceptEdgeFn && !options.acceptEdgeFn!(edge)) return;
93
- if (!useMultiLevelSegments && Level.isRange(edge.level)) return;
94
- if (!Level.intersect(edge.level, origin.level)) return;
95
-
96
- if (useMaxBearingAngle) {
97
- // Do not try to project if angle is greater than the threshold
98
- if (diffAngleLines(edge.bearing, (origin as UserPosition).bearing!) > maxBearingAngle) return;
99
- }
100
-
101
- const segmentProjection = origin.getSegmentProjection(edge.vertex1.coords, edge.vertex2.coords);
102
- if (!segmentProjection) return;
103
- const distanceToSegment = segmentProjection.distanceTo(origin);
104
-
105
- if (useMaxDistance && distanceToSegment > maxDistance) return;
106
-
107
- if (distanceToSegment < (bestProjection?.distanceFromNearestElement ?? Number.MAX_VALUE)) {
108
- bestProjection = new GraphProjection(origin, distanceToSegment, adaptProjectionCoords(segmentProjection), edge);
109
- }
110
- });
111
-
112
- // if mapmatching bearing is enabled do not use vertices matching
113
- if (useMaxBearingAngle) {
114
- return bestProjection;
115
- }
116
-
117
- this.vertices.forEach(vertex => {
118
- let vertexCoords = vertex.coords;
119
-
120
- // Specific case of io nodes that have a non-null level but can be matched to a null origin level
121
- if (this.exitVertices.has(vertex) && origin.level === null) {
122
- vertexCoords = vertex.coords.clone();
123
- vertexCoords.level = null;
124
- }
125
-
126
- if (!useMultiLevelSegments && Level.isRange(vertexCoords.level)) return;
127
- if (!Level.intersect(vertexCoords.level, origin.level)) return;
128
-
129
- const distanceToVertex = vertexCoords.distanceTo(origin);
130
-
131
- // If distance below epsilon consider it as best projection
132
- if (distanceToVertex < GeoConstants.EPS_MM) {
133
- bestProjection = new GraphProjection(origin, 0, adaptProjectionCoords(vertexCoords), vertex);
134
- return;
135
- }
136
-
137
- if (useMaxDistance && distanceToVertex > maxDistance) return;
138
-
139
- if (distanceToVertex < (bestProjection?.distanceFromNearestElement ?? Number.MAX_VALUE)) {
140
- bestProjection = new GraphProjection(origin, distanceToVertex, adaptProjectionCoords(vertexCoords), vertex);
141
- }
142
- });
143
-
144
- return bestProjection;
145
- }
146
-
147
-
148
- toJson(): GeoGraphJson {
149
- return {
150
- vertices: this.vertices.map(vertex => vertex.toJson()),
151
- edges: this.edges.map(edge => ({
152
- id: edge.id,
153
- vertex1Idx: this.vertices.indexOf(edge.vertex1),
154
- vertex2Idx: this.vertices.indexOf(edge.vertex2),
155
- ...(Object.keys(edge.properties).length > 0 && { properties: edge.properties })
156
- }))
157
- };
158
- }
159
-
160
- static fromJson(json: GeoGraphJson) {
161
-
162
- const vertices = json.vertices.map(vertex => Vertex.fromJson(vertex));
163
- const edges = json.edges.map(jsonEdge => new Edge(
164
- vertices[jsonEdge.vertex1Idx],
165
- vertices[jsonEdge.vertex2Idx],
166
- jsonEdge.properties,
167
- jsonEdge.id
168
- ));
169
-
170
- return new Graph(vertices, edges);
171
- }
172
-
173
- /** @deprecated */
174
- toCompressedJson(): CompressedGeoGraphJson {
175
- return {
176
- vertices: this.vertices.map(vertex => vertex.coords.toCompressedJson()),
177
- verticesIds: this.vertices.map(vertex => vertex.id),
178
- edges: this.edges.map(edge => {
179
- const vertex1Idx = this.vertices.indexOf(edge.vertex1);
180
- const vertex2Idx = this.vertices.indexOf(edge.vertex2);
181
- const edgeExtras = edge.properties;
182
- if (Object.keys(edgeExtras).length > 0) {
183
- return [vertex1Idx, vertex2Idx, edgeExtras];
184
- }
185
- return [vertex1Idx, vertex2Idx];
186
- })
187
- };
188
- }
189
-
190
- /** @deprecated */
191
- static fromCompressedJson(json: CompressedGeoGraphJson) {
192
- const vertices = json.vertices.map(vertex => new Vertex(Coordinates.fromCompressedJson(vertex)));
193
- const edges = json.edges.map(jsonEdge => new Edge(
194
- vertices[jsonEdge[0]],
195
- vertices[jsonEdge[1]],
196
- jsonEdge.length > 2 ? jsonEdge[2] : {}
197
- ));
198
-
199
- return new Graph(vertices, edges);
200
- }
201
-
202
-
203
- static fromCoordinatesSegments(segments: Coordinates[][]) {
204
-
205
- const vertices: Vertex[] = [];
206
- const edges: Edge[] = [];
207
-
208
- const getOrCreateVertex = (coords: Coordinates) => {
209
- const vertex = vertices.find(otherVertex => otherVertex.coords.equals(coords));
210
- if (vertex) {
211
- return vertex;
212
- }
213
- const newVertex = new Vertex(coords);
214
- vertices.push(newVertex);
215
- return newVertex;
216
- };
217
-
218
- for (const segment of segments) {
219
-
220
- let previousVertex = null;
221
- for (const coords of segment) {
222
- const currentVertex = getOrCreateVertex(coords);
223
-
224
- if (previousVertex) {
225
- edges.push(new Edge(currentVertex, previousVertex));
226
- }
227
-
228
- previousVertex = currentVertex;
229
- }
230
- }
231
-
232
- return new Graph(vertices, edges);
233
- }
234
-
235
- /**
236
- * Create edges From MultiLevel Itinerary for a given level
237
- * @param useMultiLevelEdges use segments which intersect both levels (stairs, elevators...)
238
- */
239
- getEdgesAtLevel(targetLevel: Level_t, useMultiLevelEdges = true) {
240
- return this.edges.filter(
241
- ({ level }) => useMultiLevelEdges
242
- ? Level.intersect(targetLevel, level)
243
- : Level.contains(targetLevel, level)
244
- );
245
- }
246
-
247
-
248
- toDetailedString() {
249
- let output
250
- = '--- Network ---\n'
251
- + `Vertices: ${this.vertices.length}\n`
252
- + `Edges: ${this.edges.length}\n`
253
- + '---\n'
254
- + 'Vertices\n';
255
- this.vertices.forEach(vertex => {
256
- output += vertex.id;
257
- const vertexProps = vertex.properties;
258
- if (Object.keys(vertexProps).length !== 0) { output += ` ${vertexProps}` }
259
- });
260
- output += '---\n'
261
- + 'Edges\n';
262
- this.edges.forEach(edge => {
263
- output += `${edge.id} - [v1: ${edge.vertex1.id}, v2: ${edge.vertex2.id}]`;
264
- const edgeProps = edge.properties;
265
- if (Object.keys(edgeProps).length !== 0) { output += ` ${edgeProps}` }
266
- });
267
- output += '---';
268
- return output;
269
- }
270
- }
271
-
272
- export default Graph;
@@ -1,15 +0,0 @@
1
- import { Coordinates, UserPosition } from '@wemap/geo';
2
-
3
- import Edge from './Edge.js';
4
- import Vertex from './Vertex.js';
5
-
6
- class GraphProjection<U extends Coordinates | UserPosition = Coordinates> {
7
- constructor(
8
- public readonly origin: U,
9
- public readonly distanceFromNearestElement: number,
10
- public readonly coords: U,
11
- public readonly nearestElement: Vertex | Edge
12
- ) { }
13
- }
14
-
15
- export default GraphProjection;
@@ -1,8 +0,0 @@
1
- import Edge from './Edge.js'
2
-
3
- export type GraphProjectionOptions = {
4
- maxDistance?: number,
5
- maxBearingAngle?: number,
6
- useMultiLevelSegments?: boolean,
7
- acceptEdgeFn?: (edge: Edge) => boolean
8
- }
@@ -1,15 +0,0 @@
1
- import chai from 'chai';
2
-
3
- import GraphRoute from './GraphRoute.js';
4
-
5
- const { expect } = chai;
6
-
7
- export function isReadable(itinerary: GraphRoute) {
8
- for (let i = 0; i < itinerary.vertices.length; i++) {
9
- const vertex = itinerary.vertices[i];
10
- if (i !== itinerary.vertices.length - 1) {
11
- expect(itinerary.edges[i].vertex1).equal(vertex);
12
- expect(itinerary.edges[i].vertex2).equal(itinerary.vertices[i + 1]);
13
- }
14
- }
15
- }
@@ -1,43 +0,0 @@
1
- import { Coordinates } from '@wemap/geo';
2
-
3
- import Graph from "./Graph.js";
4
- import Edge from './Edge.js';
5
- import Vertex from './Vertex.js';
6
- import { getDurationFromLength } from '../Utils.js';
7
-
8
-
9
- /**
10
- * GraphRoute is an oriented graph
11
- */
12
- class GraphRoute extends Graph {
13
- constructor(
14
- public start: Coordinates,
15
- public end: Coordinates,
16
- public vertices: Vertex[],
17
- public edges: Edge[],
18
- public edgesWeights: number[]
19
- ) {
20
- super(vertices, edges);
21
- }
22
-
23
- // /!\ Does not clone vertices
24
- // /!\ Create new Edges but does not deep clone properties
25
- // /!\ Does not revert edge oneway property
26
- reverse() {
27
- const vertices = this.vertices.slice().reverse();
28
- const edges = this.edges.slice().reverse();
29
- const edgesWeights = this.edgesWeights.slice().reverse();
30
- edges.map(oldEdge => new Edge(oldEdge.vertex2, oldEdge.vertex1, oldEdge.properties));
31
- return new GraphRoute(this.start, this.end, vertices, edges, edgesWeights);
32
- }
33
-
34
- static fromCoordinates(start: Coordinates, end: Coordinates, coordinates: Coordinates[]) {
35
- const graph = Graph.fromCoordinatesSegments([coordinates]);
36
- const edgesWeights = graph.edges.map(e => getDurationFromLength(e.length));
37
- return new GraphRoute(start, end, graph.vertices, graph.edges, edgesWeights);
38
- }
39
-
40
- get hasRoute() { return Boolean(this.vertices.length) }
41
- }
42
-
43
- export default GraphRoute;
@@ -1,317 +0,0 @@
1
- import chai from 'chai';
2
- import chaiAlmost from 'chai-almost';
3
-
4
- import { Coordinates, type Level_t } from '@wemap/geo';
5
-
6
- import Graph from './Graph.js';
7
- import Vertex from './Vertex.js';
8
- import Edge from './Edge.js';
9
-
10
- import GraphRouter from './GraphRouter.js';
11
- import GraphRoute from './GraphRoute.js';
12
- import { type GraphRouterOptions } from './GraphRouterOptions.js';
13
- import GraphRouterOptionsBuilder from './GraphRouterOptionsBuilder.js';
14
-
15
- const { expect } = chai;
16
- chai.use(chaiAlmost(1e-3));
17
-
18
- const networkDidNotChange = (
19
- networkAfter: Graph,
20
- verticesBefore: Vertex[],
21
- edgesBefore: Edge[]
22
- ) => {
23
-
24
- const isEdgeInArray = (edgeArray: Edge[], edge: Edge) => edgeArray.find(_edge =>
25
- edge.vertex1 === _edge.vertex1
26
- && edge.vertex2 === _edge.vertex2
27
- && edge.level === _edge.level
28
- );
29
- const areEdgeArrayEquals = (edgeArray1: Edge[], edgeArray2: Edge[]) => {
30
- if (edgeArray1.length !== edgeArray2.length) {
31
- return false;
32
- }
33
- for (let j = 0; j < edgeArray1.length; j++) {
34
- if (!isEdgeInArray(edgeArray2, edgeArray1[j])) {
35
- return false;
36
- }
37
- }
38
- for (let j = 0; j < edgeArray2.length; j++) {
39
- if (!isEdgeInArray(edgeArray1, edgeArray2[j])) {
40
- return false;
41
- }
42
- }
43
- return true;
44
- };
45
-
46
- expect(networkAfter.vertices.length).equals(verticesBefore.length);
47
- for (let i = 0; i < verticesBefore.length; i++) {
48
- const vertex = networkAfter.vertices[i];
49
- const vertexBefore = verticesBefore[i];
50
- expect(vertexBefore).equals(vertex);
51
- }
52
-
53
- expect(areEdgeArrayEquals(networkAfter.edges, edgesBefore)).true;
54
- };
55
-
56
- const getShortestRoutesByVertex = (
57
- _router: GraphRouter,
58
- _start: Vertex,
59
- _end: Vertex,
60
- _options?: GraphRouterOptions
61
- ) => {
62
- const { graph } = _router;
63
- const verticesBefore = graph.vertices.slice(0);
64
- const edgesBefore = graph.edges.slice(0);
65
- const output = _router.calculateShortestPathByVertex(_start, _end, _options);
66
- networkDidNotChange(graph, verticesBefore, edgesBefore);
67
- return output.routeVertices();
68
- };
69
-
70
- const getShortestRoute = (
71
- _router: GraphRouter,
72
- _start: Coordinates,
73
- _end: Coordinates,
74
- _options?: GraphRouterOptions
75
- ) => {
76
- const { graph } = _router;
77
- const verticesBefore = graph.vertices.slice(0);
78
- const edgesBefore = graph.edges.slice(0);
79
- const output = _router.calculateShortestPath(_start, _end, _options);
80
- networkDidNotChange(graph, verticesBefore, edgesBefore);
81
- return output.route();
82
- };
83
-
84
- class GraphEdgeWithExtra extends Edge {
85
- mood?: boolean;
86
- stairs?: boolean;
87
- }
88
-
89
- const createModel = (
90
- verticesLevel: [Level_t, Level_t, Level_t, Level_t] = [null, null, null, null]
91
- ) => {
92
-
93
- const vertices = [
94
- new Vertex(new Coordinates(43.6091194, 3.884099, null, verticesLevel[0]), { name: 'p0' }),
95
- new Vertex(new Coordinates(43.6093629, 3.8842777, null, verticesLevel[1]), { name: 'p1' }),
96
- new Vertex(new Coordinates(43.6092785, 3.8845052, null, verticesLevel[2]), { name: 'p2' }),
97
- new Vertex(new Coordinates(43.6094902, 3.8843416, null, verticesLevel[3]), { name: 'p3' })
98
- ];
99
-
100
- const edges = [
101
- new GraphEdgeWithExtra(vertices[0], vertices[1], { name: 'e0' }),
102
- new GraphEdgeWithExtra(vertices[2], vertices[1], { name: 'e1' }),
103
- new GraphEdgeWithExtra(vertices[1], vertices[3], { name: 'e2' }),
104
- new GraphEdgeWithExtra(vertices[2], vertices[3], { name: 'e3' })
105
- ];
106
-
107
- const graph = new Graph(vertices, edges);
108
-
109
- const start = new Coordinates(43.6091367, 3.8839298);
110
- const end = new Coordinates(43.6093154, 3.8846326);
111
-
112
- return {
113
- edges,
114
- end,
115
- vertices,
116
- graph,
117
- start
118
- };
119
- };
120
-
121
-
122
- const getVerticesNamesOfPath = (path: Vertex[]) => path.map(vertex => vertex.properties.name);
123
- const getVerticesNames = (_route: GraphRoute) => _route.vertices.map(vertex => vertex.properties.name);
124
-
125
-
126
- describe('GraphRouter', () => {
127
-
128
- const { graph, start, end, vertices } = createModel();
129
-
130
- const router = new GraphRouter(graph);
131
-
132
- it('returns shortest path - use vertices', () => {
133
- const path = getShortestRoutesByVertex(router, vertices[0], vertices[2]);
134
- expect(getVerticesNamesOfPath(path)).deep.equals(['p0', 'p1', 'p2']);
135
- });
136
-
137
- it('returns shortest path - use coords', () => {
138
- const route = getShortestRoute(router, start, end);
139
- expect(getVerticesNames(route)).deep.equals(['p0', 'p1', 'p2']);
140
- });
141
-
142
- it('returns shortest path - use vertices coords', () => {
143
- const route = getShortestRoute(router, vertices[0].coords, vertices[2].coords);
144
- expect(getVerticesNames(route)).deep.equals(['p0', 'p1', 'p2']);
145
- });
146
-
147
- it('use same vertex', () => {
148
- let route = getShortestRoute(router, start, vertices[0].coords);
149
- expect(getVerticesNames(route)).deep.equals(['p0']);
150
-
151
- route = getShortestRoute(router, vertices[0].coords, start);
152
- expect(getVerticesNames(route)).deep.equals(['p0']);
153
- });
154
-
155
- // it('errors', () => {
156
-
157
- // expect(() => getShortestRoute(router, new Coordinates(0, 0), end)).throw(NoRouteFoundError);
158
- // expect(() => getShortestRoute(router, start, new Coordinates(0, 0))).throw(NoRouteFoundError);
159
-
160
- // });
161
- });
162
-
163
- describe('GraphRouter - with level', () => {
164
-
165
- const {
166
- graph, start, end
167
- } = createModel([1, [1, 2], [1, 2], 2]);
168
-
169
- start.level = 1;
170
- end.level = 2;
171
-
172
- it('router returns shortest path', () => {
173
-
174
- const router = new GraphRouter(graph);
175
- const route = getShortestRoute(router, start, end);
176
- expect(getVerticesNames(route)).deep.equals(['p0', 'p1', 'p3']);
177
-
178
- });
179
- });
180
-
181
-
182
- describe('GraphRouter - Route without stairs', () => {
183
-
184
- const { graph, edges, start, end } = createModel();
185
- edges[1].stairs = true;
186
-
187
- it('no stairs found', () => {
188
-
189
- const router = new GraphRouter(graph);
190
- const route = getShortestRoute(router, start, end, GraphRouterOptionsBuilder.WITHOUT_STAIRS);
191
-
192
- expect(route.hasRoute).is.true;
193
- route.edges.forEach((edge: Edge) => expect(edge.properties.areStairs).not.true);
194
- });
195
- });
196
-
197
-
198
- describe('GraphRouter - Route one way', () => {
199
-
200
-
201
- it('do not use oneway segments', () => {
202
-
203
- const { edges, graph, start, end } = createModel();
204
- edges[1].properties.isOneway = true;
205
-
206
- const router = new GraphRouter(graph);
207
-
208
- let route = getShortestRoute(router, start, end);
209
- expect(route.hasRoute).is.true;
210
- expect(getVerticesNames(route)).deep.equals(['p0', 'p1', 'p3', 'p2']);
211
-
212
- // route other way
213
- route = getShortestRoute(router, end, start);
214
- expect(route.hasRoute).is.true;
215
- expect(getVerticesNames(route)).deep.equals(['p2', 'p1', 'p0']);
216
- });
217
-
218
-
219
- it('do not use oneway segments (2)', () => {
220
-
221
- const vertices = [
222
- new Vertex(new Coordinates(0, 0), { name: 'p0' }),
223
- new Vertex(new Coordinates(1, 0), { name: 'p1' }),
224
- new Vertex(new Coordinates(2, 0), { name: 'p2' })
225
- ];
226
-
227
- const edges = [
228
- new Edge(vertices[0], vertices[1], { name: 'e0', isOneway: true }),
229
- new Edge(vertices[1], vertices[2], { name: 'e1', isOneway: true })
230
- ];
231
-
232
- const network = new Graph(vertices, edges);
233
-
234
- const start = new Coordinates(0.5, 0);
235
- const end = new Coordinates(1.5, 0);
236
-
237
- const router = new GraphRouter(network);
238
-
239
- const route = getShortestRoute(router, start, end);
240
- expect(route.hasRoute).is.true;
241
- expect(route.vertices[1].properties.name).equals('p1');
242
-
243
- // Route other way
244
- expect(getShortestRoute(router, end, start).hasRoute).is.false;
245
- });
246
- });
247
-
248
-
249
- describe('GraphRouter - Route with weight', () => {
250
-
251
- const { edges, graph, start, end } = createModel();
252
- edges[1].mood = true;
253
-
254
- it('Verify weight', () => {
255
-
256
- const router = new GraphRouter(graph);
257
-
258
- const route = getShortestRoute(router, start, end);
259
- expect(route.hasRoute).is.true;
260
- expect(getVerticesNames(route)).deep.equals(['p0', 'p1', 'p2']);
261
- expect(route.edges.length).equals(2);
262
- expect(route.edgesWeights).deep.almost([27.62, 18.54], 1e-2);
263
- });
264
-
265
-
266
- it('take shortest path', () => {
267
-
268
- const router = new GraphRouter(graph);
269
- const options = new GraphRouterOptionsBuilder().build();
270
- options.weightEdgeFn = (edge: GraphEdgeWithExtra) => {
271
- let duration = edge.length;
272
- if (edge.mood) {
273
- duration *= 10;
274
- }
275
- return duration;
276
- };
277
-
278
- const route = getShortestRoute(router, start, end, options);
279
-
280
- expect(route.hasRoute).is.true;
281
- expect(getVerticesNames(route)).deep.equals(['p0', 'p1', 'p3', 'p2']);
282
- expect(route.edgesWeights).deep.almost([30.696, 15.078, 27.005], 1e-2);
283
-
284
- });
285
- });
286
-
287
-
288
- describe('GraphRouter - Start and End projection on the same edge', () => {
289
-
290
- const vertices = [
291
- new Vertex(new Coordinates(0, 0), { name: 'p0' }),
292
- new Vertex(new Coordinates(0, 3), { name: 'p1' })
293
- ];
294
-
295
- const edges = [
296
- new Edge(vertices[0], vertices[1], { name: 'e0', isOneway: true }),
297
- ];
298
-
299
- const graph = new Graph(vertices, edges);
300
-
301
- const start = new Coordinates(0.1, 1);
302
- const end = new Coordinates(0.1, 2);
303
-
304
- it('take shortest path', () => {
305
- const router = new GraphRouter(graph);
306
- const route = getShortestRoute(router, start, end);
307
- expect(route.hasRoute).is.true;
308
- expect(route.edges.length).equals(1)
309
- });
310
-
311
- it('take shortest path oneway reverse', () => {
312
- const router = new GraphRouter(graph);
313
- const route = getShortestRoute(router, end, start);
314
- expect(route.hasRoute).is.false;
315
- expect(route.edges.length).equals(0)
316
- });
317
- });