minotor 5.0.1 → 7.0.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.
- package/CHANGELOG.md +8 -3
- package/dist/cli.mjs +282 -654
- package/dist/cli.mjs.map +1 -1
- package/dist/gtfs/parser.d.ts +4 -10
- package/dist/gtfs/routes.d.ts +16 -2
- package/dist/gtfs/stops.d.ts +3 -13
- package/dist/gtfs/transfers.d.ts +2 -2
- package/dist/gtfs/trips.d.ts +12 -8
- package/dist/parser.cjs.js +257 -644
- package/dist/parser.cjs.js.map +1 -1
- package/dist/parser.esm.js +257 -644
- package/dist/parser.esm.js.map +1 -1
- package/dist/router.cjs.js +1 -1
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.esm.js +1 -1
- package/dist/router.esm.js.map +1 -1
- package/dist/router.umd.js +1 -1
- package/dist/router.umd.js.map +1 -1
- package/dist/stops/io.d.ts +3 -3
- package/dist/stops/proto/stops.d.ts +1 -8
- package/dist/stops/stops.d.ts +0 -4
- package/dist/stops/stopsIndex.d.ts +3 -3
- package/dist/timetable/io.d.ts +6 -6
- package/dist/timetable/proto/timetable.d.ts +5 -27
- package/dist/timetable/route.d.ts +2 -11
- package/dist/timetable/timetable.d.ts +17 -9
- package/package.json +1 -1
- package/src/__e2e__/timetable/stops.bin +2 -2
- package/src/__e2e__/timetable/timetable.bin +2 -2
- package/src/cli/minotor.ts +3 -4
- package/src/gtfs/__tests__/parser.test.ts +5 -6
- package/src/gtfs/__tests__/routes.test.ts +0 -3
- package/src/gtfs/__tests__/stops.test.ts +1 -124
- package/src/gtfs/__tests__/transfers.test.ts +7 -7
- package/src/gtfs/__tests__/trips.test.ts +74 -45
- package/src/gtfs/parser.ts +32 -49
- package/src/gtfs/routes.ts +43 -5
- package/src/gtfs/stops.ts +2 -44
- package/src/gtfs/transfers.ts +2 -2
- package/src/gtfs/trips.ts +66 -43
- package/src/routing/__tests__/result.test.ts +48 -48
- package/src/routing/__tests__/router.test.ts +279 -363
- package/src/routing/router.ts +22 -8
- package/src/stops/__tests__/io.test.ts +25 -31
- package/src/stops/__tests__/stopFinder.test.ts +82 -103
- package/src/stops/io.ts +8 -17
- package/src/stops/proto/stops.proto +3 -3
- package/src/stops/proto/stops.ts +16 -120
- package/src/stops/stops.ts +0 -4
- package/src/stops/stopsIndex.ts +37 -41
- package/src/timetable/__tests__/io.test.ts +44 -54
- package/src/timetable/__tests__/route.test.ts +10 -29
- package/src/timetable/__tests__/timetable.test.ts +29 -37
- package/src/timetable/io.ts +66 -74
- package/src/timetable/proto/timetable.proto +7 -14
- package/src/timetable/proto/timetable.ts +49 -391
- package/src/timetable/route.ts +2 -32
- package/src/timetable/timetable.ts +51 -31
package/src/stops/stops.ts
CHANGED
package/src/stops/stopsIndex.ts
CHANGED
|
@@ -6,13 +6,7 @@ import { addAll, createIndex, search, SearchResult } from 'slimsearch';
|
|
|
6
6
|
import { generateAccentVariants } from './i18n.js';
|
|
7
7
|
import { deserializeStopsMap, serializeStopsMap } from './io.js';
|
|
8
8
|
import { StopsMap as ProtoStopsMap } from './proto/stops.js';
|
|
9
|
-
import {
|
|
10
|
-
SourceStopId,
|
|
11
|
-
SourceStopsMap,
|
|
12
|
-
Stop,
|
|
13
|
-
StopId,
|
|
14
|
-
StopsMap,
|
|
15
|
-
} from './stops.js';
|
|
9
|
+
import { SourceStopId, SourceStopsMap, Stop, StopId } from './stops.js';
|
|
16
10
|
|
|
17
11
|
type StopPoint = { id: StopId; lat: number; lon: number };
|
|
18
12
|
|
|
@@ -22,50 +16,52 @@ type StopPoint = { id: StopId; lat: number; lon: number };
|
|
|
22
16
|
* to efficiently find stops based on user queries.
|
|
23
17
|
*/
|
|
24
18
|
export class StopsIndex {
|
|
25
|
-
private readonly
|
|
19
|
+
private readonly stops: Stop[];
|
|
26
20
|
private readonly sourceStopsMap: SourceStopsMap;
|
|
27
21
|
private readonly textIndex;
|
|
28
22
|
private readonly geoIndex: KDTree;
|
|
29
23
|
private readonly stopPoints: StopPoint[];
|
|
30
24
|
|
|
31
|
-
constructor(
|
|
32
|
-
this.
|
|
25
|
+
constructor(stops: Stop[]) {
|
|
26
|
+
this.stops = stops;
|
|
33
27
|
this.sourceStopsMap = new Map<SourceStopId, StopId>();
|
|
34
|
-
for (const [id, stop] of stopsMap.entries()) {
|
|
35
|
-
this.sourceStopsMap.set(stop.sourceStopId, id);
|
|
36
|
-
}
|
|
37
|
-
this.textIndex = createIndex({
|
|
38
|
-
fields: ['name'],
|
|
39
|
-
storeFields: ['id'],
|
|
40
|
-
searchOptions: { prefix: true, fuzzy: 0.2 },
|
|
41
|
-
processTerm: generateAccentVariants,
|
|
42
|
-
});
|
|
43
28
|
const stopsSet = new Map<StopId, { id: StopId; name: string }>();
|
|
44
|
-
|
|
29
|
+
this.stopPoints = [];
|
|
30
|
+
for (let id = 0; id < stops.length; id++) {
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
32
|
+
const stop = stops[id]!;
|
|
33
|
+
|
|
34
|
+
this.sourceStopsMap.set(stop.sourceStopId, id);
|
|
35
|
+
|
|
45
36
|
const effectiveStopId = stop.parent ?? id;
|
|
46
37
|
if (!stopsSet.has(effectiveStopId)) {
|
|
47
38
|
stopsSet.set(effectiveStopId, {
|
|
48
39
|
id: effectiveStopId,
|
|
49
40
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
50
|
-
name: stop.parent ? this.
|
|
41
|
+
name: stop.parent ? this.stops[stop.parent]!.name : stop.name,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (stop.lat && stop.lon) {
|
|
46
|
+
this.stopPoints.push({
|
|
47
|
+
id: id,
|
|
48
|
+
lat: stop.lat,
|
|
49
|
+
lon: stop.lon,
|
|
51
50
|
});
|
|
52
51
|
}
|
|
53
52
|
}
|
|
53
|
+
this.textIndex = createIndex({
|
|
54
|
+
fields: ['name'],
|
|
55
|
+
storeFields: ['id'],
|
|
56
|
+
searchOptions: { prefix: true, fuzzy: 0.2 },
|
|
57
|
+
processTerm: generateAccentVariants,
|
|
58
|
+
});
|
|
54
59
|
const stopsArray = Array.from(stopsSet.values());
|
|
55
60
|
addAll(this.textIndex, stopsArray);
|
|
56
|
-
|
|
57
|
-
this.stopPoints = Array.from(this.stopsMap.entries())
|
|
58
|
-
.filter(([, stop]) => {
|
|
59
|
-
if (stop.lat && stop.lon) return true;
|
|
60
|
-
return false;
|
|
61
|
-
})
|
|
62
|
-
.map(([id, stop]) => ({
|
|
63
|
-
id: id,
|
|
64
|
-
lat: stop.lat as number,
|
|
65
|
-
lon: stop.lon as number,
|
|
66
|
-
}));
|
|
67
61
|
this.geoIndex = new KDTree(this.stopPoints.length);
|
|
68
|
-
for (
|
|
62
|
+
for (let i = 0; i < this.stopPoints.length; i++) {
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
64
|
+
const { lat, lon } = this.stopPoints[i]!;
|
|
69
65
|
this.geoIndex.add(lon, lat);
|
|
70
66
|
}
|
|
71
67
|
this.geoIndex.finish();
|
|
@@ -90,7 +86,7 @@ export class StopsIndex {
|
|
|
90
86
|
* @returns The serialized binary data.
|
|
91
87
|
*/
|
|
92
88
|
serialize(): Uint8Array {
|
|
93
|
-
const protoStopsMap: ProtoStopsMap = serializeStopsMap(this.
|
|
89
|
+
const protoStopsMap: ProtoStopsMap = serializeStopsMap(this.stops);
|
|
94
90
|
|
|
95
91
|
const writer = new BinaryWriter();
|
|
96
92
|
ProtoStopsMap.encode(protoStopsMap, writer);
|
|
@@ -103,7 +99,7 @@ export class StopsIndex {
|
|
|
103
99
|
* @returns The total number of stops.
|
|
104
100
|
*/
|
|
105
101
|
size(): number {
|
|
106
|
-
return this.
|
|
102
|
+
return this.stops.length;
|
|
107
103
|
}
|
|
108
104
|
|
|
109
105
|
/**
|
|
@@ -115,7 +111,7 @@ export class StopsIndex {
|
|
|
115
111
|
*/
|
|
116
112
|
findStopsByName(query: string, maxResults = 5): Stop[] {
|
|
117
113
|
const results = search(this.textIndex, query).map(
|
|
118
|
-
(result: SearchResult) => this.
|
|
114
|
+
(result: SearchResult) => this.stops[result.id as number] as Stop,
|
|
119
115
|
);
|
|
120
116
|
return results.slice(0, maxResults);
|
|
121
117
|
}
|
|
@@ -143,7 +139,7 @@ export class StopsIndex {
|
|
|
143
139
|
radius,
|
|
144
140
|
).map((id) => {
|
|
145
141
|
const stopPoint = this.stopPoints[id as number] as StopPoint;
|
|
146
|
-
return this.
|
|
142
|
+
return this.stops[stopPoint.id] as Stop;
|
|
147
143
|
});
|
|
148
144
|
return nearestStops;
|
|
149
145
|
}
|
|
@@ -155,7 +151,7 @@ export class StopsIndex {
|
|
|
155
151
|
* @returns The Stop object that matches the specified ID, or undefined if not found.
|
|
156
152
|
*/
|
|
157
153
|
findStopById(id: StopId): Stop | undefined {
|
|
158
|
-
return this.
|
|
154
|
+
return this.stops[id];
|
|
159
155
|
}
|
|
160
156
|
|
|
161
157
|
/**
|
|
@@ -180,15 +176,15 @@ export class StopsIndex {
|
|
|
180
176
|
if (id === undefined) {
|
|
181
177
|
return [];
|
|
182
178
|
}
|
|
183
|
-
const stop = this.
|
|
179
|
+
const stop = this.stops[id];
|
|
184
180
|
if (!stop) {
|
|
185
181
|
return [];
|
|
186
182
|
}
|
|
187
183
|
const equivalentStops = stop.parent
|
|
188
|
-
? (this.
|
|
184
|
+
? (this.stops[stop.parent]?.children ?? [])
|
|
189
185
|
: stop.children;
|
|
190
186
|
return Array.from(new Set([id, ...equivalentStops])).map(
|
|
191
|
-
(stopId) => this.
|
|
187
|
+
(stopId) => this.stops[stopId] as Stop,
|
|
192
188
|
);
|
|
193
189
|
}
|
|
194
190
|
}
|
|
@@ -12,31 +12,25 @@ import {
|
|
|
12
12
|
} from '../io.js';
|
|
13
13
|
import { REGULAR, Route } from '../route.js';
|
|
14
14
|
import { Time } from '../time.js';
|
|
15
|
-
import {
|
|
15
|
+
import { ServiceRoute, StopAdjacency } from '../timetable.js';
|
|
16
16
|
|
|
17
17
|
describe('Timetable IO', () => {
|
|
18
|
-
const stopsAdjacency:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
routes: [1],
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
]);
|
|
18
|
+
const stopsAdjacency: StopAdjacency[] = [
|
|
19
|
+
{
|
|
20
|
+
transfers: [{ destination: 2, type: 'RECOMMENDED' }],
|
|
21
|
+
routes: [0],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
transfers: [
|
|
25
|
+
{
|
|
26
|
+
destination: 1,
|
|
27
|
+
type: 'GUARANTEED',
|
|
28
|
+
minTransferTime: Duration.fromMinutes(3),
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
routes: [1],
|
|
32
|
+
},
|
|
33
|
+
];
|
|
40
34
|
const routesAdjacency = [
|
|
41
35
|
new Route(
|
|
42
36
|
new Uint16Array([
|
|
@@ -45,7 +39,7 @@ describe('Timetable IO', () => {
|
|
|
45
39
|
]),
|
|
46
40
|
new Uint8Array([REGULAR, REGULAR]),
|
|
47
41
|
new Uint32Array([1, 2]),
|
|
48
|
-
|
|
42
|
+
0,
|
|
49
43
|
),
|
|
50
44
|
new Route(
|
|
51
45
|
new Uint16Array([
|
|
@@ -54,31 +48,29 @@ describe('Timetable IO', () => {
|
|
|
54
48
|
]),
|
|
55
49
|
new Uint8Array([REGULAR, REGULAR]),
|
|
56
50
|
new Uint32Array([2, 1]),
|
|
57
|
-
|
|
51
|
+
1,
|
|
58
52
|
),
|
|
59
53
|
];
|
|
60
|
-
const routes:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
]
|
|
64
|
-
const stopsAdjacencyProto =
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
routes: [1],
|
|
79
|
-
},
|
|
54
|
+
const routes: ServiceRoute[] = [
|
|
55
|
+
{ type: 'RAIL', name: 'Route 1', routes: [0] },
|
|
56
|
+
{ type: 'RAIL', name: 'Route 2', routes: [1] },
|
|
57
|
+
];
|
|
58
|
+
const stopsAdjacencyProto = [
|
|
59
|
+
{
|
|
60
|
+
transfers: [{ destination: 2, type: 0 }],
|
|
61
|
+
routes: [0],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
transfers: [
|
|
65
|
+
{
|
|
66
|
+
destination: 1,
|
|
67
|
+
type: 1,
|
|
68
|
+
minTransferTime: 180,
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
routes: [1],
|
|
80
72
|
},
|
|
81
|
-
|
|
73
|
+
];
|
|
82
74
|
|
|
83
75
|
const routesAdjacencyProto = [
|
|
84
76
|
{
|
|
@@ -90,7 +82,7 @@ describe('Timetable IO', () => {
|
|
|
90
82
|
),
|
|
91
83
|
pickUpDropOffTypes: new Uint8Array([REGULAR, REGULAR]),
|
|
92
84
|
stops: new Uint8Array(new Uint32Array([1, 2]).buffer),
|
|
93
|
-
serviceRouteId:
|
|
85
|
+
serviceRouteId: 0,
|
|
94
86
|
},
|
|
95
87
|
{
|
|
96
88
|
stopTimes: new Uint8Array(
|
|
@@ -101,16 +93,14 @@ describe('Timetable IO', () => {
|
|
|
101
93
|
),
|
|
102
94
|
pickUpDropOffTypes: new Uint8Array([REGULAR, REGULAR]),
|
|
103
95
|
stops: new Uint8Array(new Uint32Array([2, 1]).buffer),
|
|
104
|
-
serviceRouteId:
|
|
96
|
+
serviceRouteId: 1,
|
|
105
97
|
},
|
|
106
98
|
];
|
|
107
99
|
|
|
108
|
-
const routesProto =
|
|
109
|
-
routes:
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
},
|
|
113
|
-
};
|
|
100
|
+
const routesProto = [
|
|
101
|
+
{ type: 2, name: 'Route 1', routes: [0] },
|
|
102
|
+
{ type: 2, name: 'Route 2', routes: [1] },
|
|
103
|
+
];
|
|
114
104
|
|
|
115
105
|
it('should serialize a stops adjacency matrix to a Uint8Array', () => {
|
|
116
106
|
const serializedData = serializeStopsAdjacency(stopsAdjacency);
|
|
@@ -56,7 +56,7 @@ describe('Route', () => {
|
|
|
56
56
|
);
|
|
57
57
|
|
|
58
58
|
const stops = new Uint32Array([1001, 1002]);
|
|
59
|
-
const serviceRouteId =
|
|
59
|
+
const serviceRouteId = 0;
|
|
60
60
|
|
|
61
61
|
const route = new Route(stopTimes, pickUpDropOffTypes, stops, serviceRouteId);
|
|
62
62
|
|
|
@@ -71,10 +71,10 @@ describe('Route', () => {
|
|
|
71
71
|
new Uint16Array([]),
|
|
72
72
|
new Uint8Array([]),
|
|
73
73
|
new Uint32Array([]),
|
|
74
|
-
|
|
74
|
+
1,
|
|
75
75
|
);
|
|
76
76
|
assert.strictEqual(emptyRoute.getNbStops(), 0);
|
|
77
|
-
assert.strictEqual(emptyRoute.serviceRoute(),
|
|
77
|
+
assert.strictEqual(emptyRoute.serviceRoute(), 1);
|
|
78
78
|
});
|
|
79
79
|
});
|
|
80
80
|
|
|
@@ -104,14 +104,14 @@ describe('Route', () => {
|
|
|
104
104
|
it('should throw error when stopA is not found', () => {
|
|
105
105
|
assert.throws(
|
|
106
106
|
() => route.isBefore(9999, 1002),
|
|
107
|
-
/Stop index undefined not found in route
|
|
107
|
+
/Stop index undefined not found in route 0/,
|
|
108
108
|
);
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
it('should throw error when stopB is not found', () => {
|
|
112
112
|
assert.throws(
|
|
113
113
|
() => route.isBefore(1001, 9999),
|
|
114
|
-
/Stop index undefined not found in route
|
|
114
|
+
/Stop index undefined not found in route 0/,
|
|
115
115
|
);
|
|
116
116
|
});
|
|
117
117
|
});
|
|
@@ -148,7 +148,7 @@ describe('Route', () => {
|
|
|
148
148
|
it('should throw error for invalid stop ID', () => {
|
|
149
149
|
assert.throws(
|
|
150
150
|
() => route.arrivalAt(9999, 0),
|
|
151
|
-
/Stop index for 9999 not found in route
|
|
151
|
+
/Stop index for 9999 not found in route 0/,
|
|
152
152
|
);
|
|
153
153
|
});
|
|
154
154
|
|
|
@@ -180,7 +180,7 @@ describe('Route', () => {
|
|
|
180
180
|
it('should throw error for invalid stop ID', () => {
|
|
181
181
|
assert.throws(
|
|
182
182
|
() => route.departureFrom(9999, 0),
|
|
183
|
-
/Stop index for 9999 not found in route
|
|
183
|
+
/Stop index for 9999 not found in route 0/,
|
|
184
184
|
);
|
|
185
185
|
});
|
|
186
186
|
|
|
@@ -211,7 +211,7 @@ describe('Route', () => {
|
|
|
211
211
|
it('should throw error for invalid stop ID', () => {
|
|
212
212
|
assert.throws(
|
|
213
213
|
() => route.pickUpTypeFrom(9999, 0),
|
|
214
|
-
/Stop index for 9999 not found in route
|
|
214
|
+
/Stop index for 9999 not found in route 0/,
|
|
215
215
|
);
|
|
216
216
|
});
|
|
217
217
|
|
|
@@ -237,7 +237,7 @@ describe('Route', () => {
|
|
|
237
237
|
it('should throw error for invalid stop ID', () => {
|
|
238
238
|
assert.throws(
|
|
239
239
|
() => route.dropOffTypeAt(9999, 0),
|
|
240
|
-
/Stop index for 9999 not found in route
|
|
240
|
+
/Stop index for 9999 not found in route 0/,
|
|
241
241
|
);
|
|
242
242
|
});
|
|
243
243
|
|
|
@@ -249,25 +249,6 @@ describe('Route', () => {
|
|
|
249
249
|
});
|
|
250
250
|
});
|
|
251
251
|
|
|
252
|
-
describe('stopsIterator', () => {
|
|
253
|
-
it('should iterate over all stops when no start stop is provided', () => {
|
|
254
|
-
const stopsList = Array.from(route.stopsIterator());
|
|
255
|
-
assert.deepStrictEqual(stopsList, [1001, 1002]);
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
it('should iterate from specified start stop', () => {
|
|
259
|
-
const stopsList = Array.from(route.stopsIterator(1002));
|
|
260
|
-
assert.deepStrictEqual(stopsList, [1002]);
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
it('should throw error for invalid start stop ID', () => {
|
|
264
|
-
assert.throws(
|
|
265
|
-
() => Array.from(route.stopsIterator(9999)),
|
|
266
|
-
/Start stop 9999 not found in route test-route-1/,
|
|
267
|
-
);
|
|
268
|
-
});
|
|
269
|
-
});
|
|
270
|
-
|
|
271
252
|
describe('findEarliestTrip', () => {
|
|
272
253
|
it('should find earliest trip without time constraint', () => {
|
|
273
254
|
const tripIndex = route.findEarliestTrip(1001);
|
|
@@ -318,7 +299,7 @@ describe('Route', () => {
|
|
|
318
299
|
it('should throw error for invalid stop ID', () => {
|
|
319
300
|
assert.throws(
|
|
320
301
|
() => route.findEarliestTrip(9999),
|
|
321
|
-
/Stop index for 9999 not found in route
|
|
302
|
+
/Stop index for 9999 not found in route 0/,
|
|
322
303
|
);
|
|
323
304
|
});
|
|
324
305
|
});
|
|
@@ -7,41 +7,33 @@ import { NOT_AVAILABLE, REGULAR, Route } from '../route.js';
|
|
|
7
7
|
import { Time } from '../time.js';
|
|
8
8
|
import {
|
|
9
9
|
RouteType,
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
ServiceRoute,
|
|
11
|
+
StopAdjacency,
|
|
12
12
|
Timetable,
|
|
13
13
|
} from '../timetable.js';
|
|
14
14
|
|
|
15
15
|
describe('Timetable', () => {
|
|
16
|
-
const stopsAdjacency:
|
|
17
|
-
[
|
|
18
|
-
|
|
19
|
-
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
[
|
|
38
|
-
3,
|
|
39
|
-
{
|
|
40
|
-
transfers: [],
|
|
41
|
-
routes: [],
|
|
42
|
-
},
|
|
43
|
-
],
|
|
44
|
-
]);
|
|
16
|
+
const stopsAdjacency: StopAdjacency[] = [
|
|
17
|
+
{ transfers: [], routes: [] },
|
|
18
|
+
{
|
|
19
|
+
transfers: [{ destination: 2, type: 'RECOMMENDED' }],
|
|
20
|
+
routes: [0, 1],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
transfers: [
|
|
24
|
+
{
|
|
25
|
+
destination: 1,
|
|
26
|
+
type: 'GUARANTEED',
|
|
27
|
+
minTransferTime: Duration.fromMinutes(3),
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
routes: [1, 0],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
transfers: [],
|
|
34
|
+
routes: [],
|
|
35
|
+
},
|
|
36
|
+
];
|
|
45
37
|
|
|
46
38
|
const route1 = new Route(
|
|
47
39
|
new Uint16Array([
|
|
@@ -59,7 +51,7 @@ describe('Timetable', () => {
|
|
|
59
51
|
[REGULAR, REGULAR, REGULAR, REGULAR],
|
|
60
52
|
),
|
|
61
53
|
new Uint32Array([1, 2]),
|
|
62
|
-
|
|
54
|
+
0,
|
|
63
55
|
);
|
|
64
56
|
const route2 = new Route(
|
|
65
57
|
new Uint16Array([
|
|
@@ -70,13 +62,13 @@ describe('Timetable', () => {
|
|
|
70
62
|
]),
|
|
71
63
|
encodePickUpDropOffTypes([REGULAR, REGULAR], [REGULAR, REGULAR]),
|
|
72
64
|
new Uint32Array([2, 1]),
|
|
73
|
-
|
|
65
|
+
1,
|
|
74
66
|
);
|
|
75
67
|
const routesAdjacency = [route1, route2];
|
|
76
|
-
const routes:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
]
|
|
68
|
+
const routes: ServiceRoute[] = [
|
|
69
|
+
{ type: 'RAIL', name: 'Route 1', routes: [0] },
|
|
70
|
+
{ type: 'RAIL', name: 'Route 2', routes: [1] },
|
|
71
|
+
];
|
|
80
72
|
|
|
81
73
|
const sampleTimetable: Timetable = new Timetable(
|
|
82
74
|
stopsAdjacency,
|