@wemap/routers 12.10.8 → 12.10.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/helpers/InstructionManager.d.ts +20 -0
- package/dist/helpers/InstructionManagerV1.d.ts +7 -0
- package/{index.ts → dist/index.d.ts} +1 -11
- package/dist/index.js +1 -5099
- package/dist/index.js.map +1 -1
- package/dist/src/ItineraryInfoManager.d.ts +31 -0
- package/dist/src/RoutingError.d.ts +24 -0
- package/{src/StatusCode.ts → dist/src/StatusCode.d.ts} +2 -3
- package/dist/src/Utils.d.ts +6 -0
- package/dist/src/graph/Edge.d.ts +32 -0
- package/dist/src/graph/Graph.d.ts +40 -0
- package/dist/src/graph/GraphProjection.d.ts +11 -0
- package/dist/src/graph/GraphProjectionOptions.d.ts +7 -0
- package/dist/src/graph/GraphRoute.d.ts +19 -0
- package/dist/src/graph/GraphRouter.d.ts +20 -0
- package/dist/src/graph/GraphRouterEngine.d.ts +77 -0
- package/{src/graph/GraphRouterOptions.ts → dist/src/graph/GraphRouterOptions.d.ts} +5 -7
- package/dist/src/graph/GraphRouterOptionsBuilder.d.ts +20 -0
- package/dist/src/graph/NoRouteFoundError.d.ts +12 -0
- package/dist/src/graph/Vertex.d.ts +19 -0
- package/dist/src/model/Itinerary.d.ts +81 -0
- package/dist/src/model/Leg.d.ts +66 -0
- package/dist/src/model/LevelChange.d.ts +7 -0
- package/dist/src/model/RouterRequest.d.ts +40 -0
- package/dist/src/model/Step.d.ts +42 -0
- package/dist/src/model/StepExtra.d.ts +3 -0
- package/dist/src/model/StepsBuilder.d.ts +16 -0
- package/dist/src/model/TransitMode.d.ts +5 -0
- package/{src/model/TravelMode.ts → dist/src/model/TravelMode.d.ts} +1 -2
- package/dist/src/model/generateSteps.d.ts +0 -0
- package/{src/remote/RemoteRouter.ts → dist/src/remote/RemoteRouter.d.ts} +2 -7
- package/dist/src/remote/RemoteRouterManager.d.ts +731 -0
- package/dist/src/remote/RemoteRouterUtils.d.ts +6 -0
- package/dist/src/remote/cityway/CitywayRemoteRouter.d.ts +109 -0
- package/dist/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.d.ts +31 -0
- package/dist/src/remote/geovelo/GeoveloRemoteRouter.d.ts +106 -0
- package/dist/src/remote/idfm/IdfmRemoteRouter.d.ts +123 -0
- package/dist/src/remote/navitia/NavitiaRemoteRouter.d.ts +34 -0
- package/dist/src/remote/navitia/types.d.ts +87 -0
- package/dist/src/remote/osrm/OsrmRemoteRouter.d.ts +70 -0
- package/dist/src/remote/otp/OtpRemoteRouter.d.ts +69 -0
- package/dist/src/remote/wemap-multi/WemapMultiRemoteRouter.d.ts +19 -0
- package/dist/src/types.d.ts +31 -0
- package/dist/src/wemap-multi/CustomGraphMap.d.ts +56 -0
- package/dist/src/wemap-multi/CustomGraphMapTester.d.ts +39 -0
- package/dist/src/wemap-multi/WemapMultiRouter.d.ts +14 -0
- package/dist/src/wemap-osm/OsmGraphUtils.d.ts +11 -0
- package/dist/tests/CommonTest.d.ts +8 -0
- package/package.json +11 -8
- package/assets/biocbon-bergere-rdc-network.osm +0 -163
- package/assets/bureaux-wemap-montpellier-network.osm +0 -174
- package/assets/components.osm +0 -146
- package/assets/elevator-models-4.osm +0 -89
- package/assets/elevator-models.osm +0 -354
- package/assets/exit-graph.osm +0 -25
- package/assets/gare-de-lest-network-pp-bounds.osm +0 -1613
- package/assets/gare-de-lyon-extract.osm +0 -174
- package/assets/geovelo-montpellier.json +0 -1144
- package/assets/horizontal-elevator.osm +0 -12
- package/assets/itinerary-deutsche-bahn-1.json +0 -368
- package/assets/itinerary-grenoble-otp-1.json +0 -1536
- package/assets/itinerary-grenoble-otp-2.json +0 -1092
- package/assets/itinerary-info-two-points-proj.osm +0 -39
- package/assets/itinerary-info-two-points.osm +0 -24
- package/assets/itinerary-lehavre-cityway-1.json +0 -6799
- package/assets/itinerary-lehavre-cityway-2.json +0 -2133
- package/assets/itinerary-lehavre-cityway-3.json +0 -12577
- package/assets/itinerary-lehavre-cityway-4.json +0 -1451
- package/assets/itinerary-lehavre-cityway-5.json +0 -5925
- package/assets/itinerary-lemans-navitia.json +0 -7768
- package/assets/itinerary-montpellier-osrm-3.json +0 -185
- package/assets/itinerary-montpellier-outdoor-without-steps.json +0 -110
- package/assets/itinerary-montpellier-outdoor.json +0 -513
- package/assets/itinerary-paris-idfm-2.json +0 -1838
- package/assets/itinerary-paris-idfm.json +0 -27727
- package/assets/itinerary-step-not-on-path-osrm.json +0 -457
- package/assets/itinerary-with-duplicate-nodes.json +0 -110
- package/assets/network-conveying-backward.osm +0 -74
- package/assets/network-elevator.osm +0 -48
- package/assets/network-escalators.osm +0 -50
- package/assets/network-simple.osm +0 -27
- package/assets/network-steps-same-level.osm +0 -283
- package/assets/network-with-modifiers.osm +0 -39
- package/assets/one-way.osm +0 -46
- package/assets/report-map-1.osm +0 -36
- package/assets/report-map-2.osm +0 -29
- package/assets/report-map-3.osm +0 -15
- package/assets/rr-wemap-multi-indoor-outdoor-indoor.json +0 -1352
- package/assets/rr-wemap-multi-indoor-outdoor.json +0 -145
- package/assets/rr-wemap-multi-multi-level.json +0 -262
- package/assets/rr-wemap-multi-outdoor-indoor.json +0 -145
- package/assets/rr-wemap-multi-outdoor-outdoor.json +0 -207
- package/assets/rr-wemap-multi-remote-indoor-indoor.json +0 -155
- package/assets/rr-wemap-multi-remote-indoor-outdoor-indoor.json +0 -668
- package/assets/rr-wemap-multi-remote-indoor-outdoor.json +0 -154
- package/assets/rr-wemap-multi-remote-outdoor-indoor.json +0 -179
- package/assets/rr-wemap-multi-remote-outdoor-outdoor.json +0 -109
- package/assets/stairs-and-exit.osm +0 -47
- package/helpers/InstructionManager.ts +0 -184
- package/helpers/InstructionManagerV1.ts +0 -95
- package/src/ItineraryInfoManager.spec.ts +0 -183
- package/src/ItineraryInfoManager.ts +0 -181
- package/src/RoutingError.ts +0 -60
- package/src/Utils.ts +0 -8
- package/src/graph/Edge.spec.ts +0 -32
- package/src/graph/Edge.ts +0 -64
- package/src/graph/Graph.spec.ts +0 -509
- package/src/graph/Graph.ts +0 -272
- package/src/graph/GraphProjection.ts +0 -15
- package/src/graph/GraphProjectionOptions.ts +0 -8
- package/src/graph/GraphRoute.spec.ts +0 -15
- package/src/graph/GraphRoute.ts +0 -43
- package/src/graph/GraphRouter.spec.ts +0 -317
- package/src/graph/GraphRouter.ts +0 -229
- package/src/graph/GraphRouterEngine.ts +0 -248
- package/src/graph/GraphRouterOptionsBuilder.ts +0 -98
- package/src/graph/NoRouteFoundError.ts +0 -39
- package/src/graph/Vertex.spec.ts +0 -42
- package/src/graph/Vertex.ts +0 -45
- package/src/model/Itinerary.spec.ts +0 -134
- package/src/model/Itinerary.ts +0 -370
- package/src/model/Leg.spec.ts +0 -107
- package/src/model/Leg.ts +0 -224
- package/src/model/LevelChange.spec.ts +0 -50
- package/src/model/LevelChange.ts +0 -14
- package/src/model/RouterRequest.ts +0 -33
- package/src/model/Step.spec.ts +0 -99
- package/src/model/Step.ts +0 -90
- package/src/model/StepExtra.ts +0 -1
- package/src/model/StepsBuilder.ts +0 -242
- package/src/model/TransitMode.spec.ts +0 -31
- package/src/model/TransitMode.ts +0 -28
- package/src/model/generateSteps.ts +0 -102
- package/src/remote/RemoteRouterManager.spec.ts +0 -178
- package/src/remote/RemoteRouterManager.ts +0 -72
- package/src/remote/RemoteRouterUtils.ts +0 -25
- package/src/remote/cityway/CitywayRemoteRouter.spec.ts +0 -122
- package/src/remote/cityway/CitywayRemoteRouter.ts +0 -435
- package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.spec.ts +0 -52
- package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.ts +0 -85
- package/src/remote/geovelo/GeoveloRemoteRouter.spec.ts +0 -54
- package/src/remote/geovelo/GeoveloRemoteRouter.ts +0 -293
- package/src/remote/idfm/IdfmRemoteRouter.spec.ts +0 -102
- package/src/remote/idfm/IdfmRemoteRouter.ts +0 -523
- package/src/remote/navitia/NavitiaRemoteRouter.spec.ts +0 -116
- package/src/remote/navitia/NavitiaRemoteRouter.ts +0 -445
- package/src/remote/navitia/types.ts +0 -73
- package/src/remote/osrm/OsrmRemoteRouter.spec.ts +0 -127
- package/src/remote/osrm/OsrmRemoteRouter.ts +0 -303
- package/src/remote/otp/OtpRemoteRouter.spec.ts +0 -103
- package/src/remote/otp/OtpRemoteRouter.ts +0 -223
- package/src/remote/wemap-multi/WemapMultiRemoteRouter.spec.ts +0 -103
- package/src/remote/wemap-multi/WemapMultiRemoteRouter.ts +0 -56
- package/src/types.ts +0 -32
- package/src/wemap-multi/CustomGraphMap.spec.ts +0 -40
- package/src/wemap-multi/CustomGraphMap.ts +0 -213
- package/src/wemap-multi/CustomGraphMapTester.spec.ts +0 -48
- package/src/wemap-multi/CustomGraphMapTester.ts +0 -90
- package/src/wemap-multi/WemapMultiRouter.spec.ts +0 -138
- package/src/wemap-multi/WemapMultiRouter.ts +0 -329
- package/src/wemap-osm/OsmGraphUtils.spec.ts +0 -165
- package/src/wemap-osm/OsmGraphUtils.ts +0 -173
- package/src/wemap-osm/OsmRouter.elevators.spec.ts +0 -106
- package/src/wemap-osm/OsmRouter.spec.ts +0 -292
- package/tests/CommonTest.ts +0 -78
- package/tsconfig.json +0 -3
- package/vite.config.ts +0 -4
package/src/graph/Graph.ts
DELETED
|
@@ -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,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
|
-
}
|
package/src/graph/GraphRoute.ts
DELETED
|
@@ -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
|
-
});
|