minotor 1.0.7 → 2.0.1
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 +2 -2
- package/README.md +3 -2
- package/dist/cli.mjs +604 -531
- package/dist/cli.mjs.map +1 -1
- package/dist/gtfs/stops.d.ts +19 -5
- package/dist/gtfs/transfers.d.ts +5 -4
- package/dist/gtfs/trips.d.ts +7 -5
- package/dist/gtfs/utils.d.ts +7 -8
- package/dist/parser.cjs.js +569 -501
- package/dist/parser.cjs.js.map +1 -1
- package/dist/parser.esm.js +569 -501
- 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.d.ts +3 -3
- 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/routing/__tests__/route.test.d.ts +1 -0
- package/dist/routing/query.d.ts +7 -7
- package/dist/routing/result.d.ts +3 -3
- package/dist/routing/route.d.ts +1 -0
- package/dist/stops/proto/stops.d.ts +5 -4
- package/dist/stops/stops.d.ts +10 -1
- package/dist/stops/stopsIndex.d.ts +21 -4
- package/dist/timetable/proto/timetable.d.ts +21 -18
- package/dist/timetable/timetable.d.ts +38 -14
- package/package.json +4 -3
- package/src/cli/repl.ts +13 -10
- package/src/gtfs/__tests__/parser.test.ts +50 -579
- package/src/gtfs/__tests__/stops.test.ts +181 -112
- package/src/gtfs/__tests__/transfers.test.ts +170 -12
- package/src/gtfs/__tests__/trips.test.ts +212 -141
- package/src/gtfs/__tests__/utils.test.ts +4 -4
- package/src/gtfs/parser.ts +22 -13
- package/src/gtfs/stops.ts +63 -28
- package/src/gtfs/transfers.ts +14 -6
- package/src/gtfs/trips.ts +110 -47
- package/src/gtfs/utils.ts +11 -11
- package/src/router.ts +2 -3
- package/src/routing/__tests__/route.test.ts +112 -0
- package/src/routing/__tests__/router.test.ts +234 -244
- package/src/routing/query.ts +7 -7
- package/src/routing/result.ts +9 -6
- package/src/routing/route.ts +11 -0
- package/src/routing/router.ts +26 -24
- package/src/stops/__tests__/io.test.ts +9 -8
- package/src/stops/__tests__/stopFinder.test.ts +45 -36
- package/src/stops/io.ts +8 -5
- package/src/stops/proto/stops.proto +8 -7
- package/src/stops/proto/stops.ts +68 -38
- package/src/stops/stops.ts +13 -1
- package/src/stops/stopsIndex.ts +50 -7
- package/src/timetable/__tests__/io.test.ts +40 -49
- package/src/timetable/__tests__/timetable.test.ts +50 -58
- package/src/timetable/io.ts +69 -56
- package/src/timetable/proto/timetable.proto +22 -17
- package/src/timetable/proto/timetable.ts +94 -184
- package/src/timetable/timetable.ts +62 -29
|
@@ -9,45 +9,6 @@ import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
|
|
9
9
|
|
|
10
10
|
export const protobufPackage = "minotor.timetable";
|
|
11
11
|
|
|
12
|
-
export enum PickUpDropOffType {
|
|
13
|
-
NOT_AVAILABLE = 0,
|
|
14
|
-
MUST_PHONE_AGENCY = 1,
|
|
15
|
-
MUST_COORDINATE_WITH_DRIVER = 2,
|
|
16
|
-
UNRECOGNIZED = -1,
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function pickUpDropOffTypeFromJSON(object: any): PickUpDropOffType {
|
|
20
|
-
switch (object) {
|
|
21
|
-
case 0:
|
|
22
|
-
case "NOT_AVAILABLE":
|
|
23
|
-
return PickUpDropOffType.NOT_AVAILABLE;
|
|
24
|
-
case 1:
|
|
25
|
-
case "MUST_PHONE_AGENCY":
|
|
26
|
-
return PickUpDropOffType.MUST_PHONE_AGENCY;
|
|
27
|
-
case 2:
|
|
28
|
-
case "MUST_COORDINATE_WITH_DRIVER":
|
|
29
|
-
return PickUpDropOffType.MUST_COORDINATE_WITH_DRIVER;
|
|
30
|
-
case -1:
|
|
31
|
-
case "UNRECOGNIZED":
|
|
32
|
-
default:
|
|
33
|
-
return PickUpDropOffType.UNRECOGNIZED;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function pickUpDropOffTypeToJSON(object: PickUpDropOffType): string {
|
|
38
|
-
switch (object) {
|
|
39
|
-
case PickUpDropOffType.NOT_AVAILABLE:
|
|
40
|
-
return "NOT_AVAILABLE";
|
|
41
|
-
case PickUpDropOffType.MUST_PHONE_AGENCY:
|
|
42
|
-
return "MUST_PHONE_AGENCY";
|
|
43
|
-
case PickUpDropOffType.MUST_COORDINATE_WITH_DRIVER:
|
|
44
|
-
return "MUST_COORDINATE_WITH_DRIVER";
|
|
45
|
-
case PickUpDropOffType.UNRECOGNIZED:
|
|
46
|
-
default:
|
|
47
|
-
return "UNRECOGNIZED";
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
12
|
export enum TransferType {
|
|
52
13
|
RECOMMENDED_TRANSFER_POINT = 0,
|
|
53
14
|
TIMED_TRANSFER = 1,
|
|
@@ -174,16 +135,27 @@ export function routeTypeToJSON(object: RouteType): string {
|
|
|
174
135
|
}
|
|
175
136
|
}
|
|
176
137
|
|
|
177
|
-
export interface StopTimes {
|
|
178
|
-
arrival: number;
|
|
179
|
-
departure: number;
|
|
180
|
-
pickUpType?: PickUpDropOffType | undefined;
|
|
181
|
-
dropOffType?: PickUpDropOffType | undefined;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
138
|
export interface Route {
|
|
185
|
-
|
|
186
|
-
|
|
139
|
+
/**
|
|
140
|
+
* Arrivals and departures encoded as a 32 bit uint array.
|
|
141
|
+
* Format: [arrival1, departure1, arrival2, departure2, etc.]
|
|
142
|
+
*/
|
|
143
|
+
stopTimes: Uint8Array;
|
|
144
|
+
/**
|
|
145
|
+
* PickUp and DropOff types represented as an 8 bit uint array.
|
|
146
|
+
* Values:
|
|
147
|
+
* 0: REGULAR
|
|
148
|
+
* 1: NOT_AVAILABLE
|
|
149
|
+
* 2: MUST_PHONE_AGENCY
|
|
150
|
+
* 3: MUST_COORDINATE_WITH_DRIVER
|
|
151
|
+
* Format: [pickupTypeStop1, dropOffTypeStop1, pickupTypeStop2, dropOffTypeStop2, etc.]
|
|
152
|
+
*/
|
|
153
|
+
pickUpDropOffTypes: Uint8Array;
|
|
154
|
+
/**
|
|
155
|
+
* Stops encoded as a 32 bit uint array.
|
|
156
|
+
* Format: [stop1, stop2, stop3, etc.]
|
|
157
|
+
*/
|
|
158
|
+
stops: Uint8Array;
|
|
187
159
|
serviceRouteId: string;
|
|
188
160
|
}
|
|
189
161
|
|
|
@@ -197,7 +169,7 @@ export interface RoutesAdjacency_RoutesEntry {
|
|
|
197
169
|
}
|
|
198
170
|
|
|
199
171
|
export interface Transfer {
|
|
200
|
-
destination:
|
|
172
|
+
destination: number;
|
|
201
173
|
type: TransferType;
|
|
202
174
|
minTransferTime?: number | undefined;
|
|
203
175
|
}
|
|
@@ -237,128 +209,28 @@ export interface Timetable {
|
|
|
237
209
|
routes: ServiceRoutesMap | undefined;
|
|
238
210
|
}
|
|
239
211
|
|
|
240
|
-
function createBaseStopTimes(): StopTimes {
|
|
241
|
-
return { arrival: 0, departure: 0, pickUpType: undefined, dropOffType: undefined };
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export const StopTimes: MessageFns<StopTimes> = {
|
|
245
|
-
encode(message: StopTimes, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
|
246
|
-
if (message.arrival !== 0) {
|
|
247
|
-
writer.uint32(8).int32(message.arrival);
|
|
248
|
-
}
|
|
249
|
-
if (message.departure !== 0) {
|
|
250
|
-
writer.uint32(16).int32(message.departure);
|
|
251
|
-
}
|
|
252
|
-
if (message.pickUpType !== undefined) {
|
|
253
|
-
writer.uint32(24).int32(message.pickUpType);
|
|
254
|
-
}
|
|
255
|
-
if (message.dropOffType !== undefined) {
|
|
256
|
-
writer.uint32(32).int32(message.dropOffType);
|
|
257
|
-
}
|
|
258
|
-
return writer;
|
|
259
|
-
},
|
|
260
|
-
|
|
261
|
-
decode(input: BinaryReader | Uint8Array, length?: number): StopTimes {
|
|
262
|
-
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
263
|
-
let end = length === undefined ? reader.len : reader.pos + length;
|
|
264
|
-
const message = createBaseStopTimes();
|
|
265
|
-
while (reader.pos < end) {
|
|
266
|
-
const tag = reader.uint32();
|
|
267
|
-
switch (tag >>> 3) {
|
|
268
|
-
case 1: {
|
|
269
|
-
if (tag !== 8) {
|
|
270
|
-
break;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
message.arrival = reader.int32();
|
|
274
|
-
continue;
|
|
275
|
-
}
|
|
276
|
-
case 2: {
|
|
277
|
-
if (tag !== 16) {
|
|
278
|
-
break;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
message.departure = reader.int32();
|
|
282
|
-
continue;
|
|
283
|
-
}
|
|
284
|
-
case 3: {
|
|
285
|
-
if (tag !== 24) {
|
|
286
|
-
break;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
message.pickUpType = reader.int32() as any;
|
|
290
|
-
continue;
|
|
291
|
-
}
|
|
292
|
-
case 4: {
|
|
293
|
-
if (tag !== 32) {
|
|
294
|
-
break;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
message.dropOffType = reader.int32() as any;
|
|
298
|
-
continue;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
if ((tag & 7) === 4 || tag === 0) {
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
reader.skip(tag & 7);
|
|
305
|
-
}
|
|
306
|
-
return message;
|
|
307
|
-
},
|
|
308
|
-
|
|
309
|
-
fromJSON(object: any): StopTimes {
|
|
310
|
-
return {
|
|
311
|
-
arrival: isSet(object.arrival) ? globalThis.Number(object.arrival) : 0,
|
|
312
|
-
departure: isSet(object.departure) ? globalThis.Number(object.departure) : 0,
|
|
313
|
-
pickUpType: isSet(object.pickUpType) ? pickUpDropOffTypeFromJSON(object.pickUpType) : undefined,
|
|
314
|
-
dropOffType: isSet(object.dropOffType) ? pickUpDropOffTypeFromJSON(object.dropOffType) : undefined,
|
|
315
|
-
};
|
|
316
|
-
},
|
|
317
|
-
|
|
318
|
-
toJSON(message: StopTimes): unknown {
|
|
319
|
-
const obj: any = {};
|
|
320
|
-
if (message.arrival !== 0) {
|
|
321
|
-
obj.arrival = Math.round(message.arrival);
|
|
322
|
-
}
|
|
323
|
-
if (message.departure !== 0) {
|
|
324
|
-
obj.departure = Math.round(message.departure);
|
|
325
|
-
}
|
|
326
|
-
if (message.pickUpType !== undefined) {
|
|
327
|
-
obj.pickUpType = pickUpDropOffTypeToJSON(message.pickUpType);
|
|
328
|
-
}
|
|
329
|
-
if (message.dropOffType !== undefined) {
|
|
330
|
-
obj.dropOffType = pickUpDropOffTypeToJSON(message.dropOffType);
|
|
331
|
-
}
|
|
332
|
-
return obj;
|
|
333
|
-
},
|
|
334
|
-
|
|
335
|
-
create<I extends Exact<DeepPartial<StopTimes>, I>>(base?: I): StopTimes {
|
|
336
|
-
return StopTimes.fromPartial(base ?? ({} as any));
|
|
337
|
-
},
|
|
338
|
-
fromPartial<I extends Exact<DeepPartial<StopTimes>, I>>(object: I): StopTimes {
|
|
339
|
-
const message = createBaseStopTimes();
|
|
340
|
-
message.arrival = object.arrival ?? 0;
|
|
341
|
-
message.departure = object.departure ?? 0;
|
|
342
|
-
message.pickUpType = object.pickUpType ?? undefined;
|
|
343
|
-
message.dropOffType = object.dropOffType ?? undefined;
|
|
344
|
-
return message;
|
|
345
|
-
},
|
|
346
|
-
};
|
|
347
|
-
|
|
348
212
|
function createBaseRoute(): Route {
|
|
349
|
-
return {
|
|
213
|
+
return {
|
|
214
|
+
stopTimes: new Uint8Array(0),
|
|
215
|
+
pickUpDropOffTypes: new Uint8Array(0),
|
|
216
|
+
stops: new Uint8Array(0),
|
|
217
|
+
serviceRouteId: "",
|
|
218
|
+
};
|
|
350
219
|
}
|
|
351
220
|
|
|
352
221
|
export const Route: MessageFns<Route> = {
|
|
353
222
|
encode(message: Route, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
|
354
|
-
|
|
355
|
-
|
|
223
|
+
if (message.stopTimes.length !== 0) {
|
|
224
|
+
writer.uint32(10).bytes(message.stopTimes);
|
|
356
225
|
}
|
|
357
|
-
|
|
358
|
-
writer.uint32(18).
|
|
226
|
+
if (message.pickUpDropOffTypes.length !== 0) {
|
|
227
|
+
writer.uint32(18).bytes(message.pickUpDropOffTypes);
|
|
228
|
+
}
|
|
229
|
+
if (message.stops.length !== 0) {
|
|
230
|
+
writer.uint32(26).bytes(message.stops);
|
|
359
231
|
}
|
|
360
232
|
if (message.serviceRouteId !== "") {
|
|
361
|
-
writer.uint32(
|
|
233
|
+
writer.uint32(34).string(message.serviceRouteId);
|
|
362
234
|
}
|
|
363
235
|
return writer;
|
|
364
236
|
},
|
|
@@ -375,7 +247,7 @@ export const Route: MessageFns<Route> = {
|
|
|
375
247
|
break;
|
|
376
248
|
}
|
|
377
249
|
|
|
378
|
-
message.stopTimes
|
|
250
|
+
message.stopTimes = reader.bytes();
|
|
379
251
|
continue;
|
|
380
252
|
}
|
|
381
253
|
case 2: {
|
|
@@ -383,7 +255,7 @@ export const Route: MessageFns<Route> = {
|
|
|
383
255
|
break;
|
|
384
256
|
}
|
|
385
257
|
|
|
386
|
-
message.
|
|
258
|
+
message.pickUpDropOffTypes = reader.bytes();
|
|
387
259
|
continue;
|
|
388
260
|
}
|
|
389
261
|
case 3: {
|
|
@@ -391,6 +263,14 @@ export const Route: MessageFns<Route> = {
|
|
|
391
263
|
break;
|
|
392
264
|
}
|
|
393
265
|
|
|
266
|
+
message.stops = reader.bytes();
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
case 4: {
|
|
270
|
+
if (tag !== 34) {
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
|
|
394
274
|
message.serviceRouteId = reader.string();
|
|
395
275
|
continue;
|
|
396
276
|
}
|
|
@@ -405,21 +285,25 @@ export const Route: MessageFns<Route> = {
|
|
|
405
285
|
|
|
406
286
|
fromJSON(object: any): Route {
|
|
407
287
|
return {
|
|
408
|
-
stopTimes:
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
288
|
+
stopTimes: isSet(object.stopTimes) ? bytesFromBase64(object.stopTimes) : new Uint8Array(0),
|
|
289
|
+
pickUpDropOffTypes: isSet(object.pickUpDropOffTypes)
|
|
290
|
+
? bytesFromBase64(object.pickUpDropOffTypes)
|
|
291
|
+
: new Uint8Array(0),
|
|
292
|
+
stops: isSet(object.stops) ? bytesFromBase64(object.stops) : new Uint8Array(0),
|
|
412
293
|
serviceRouteId: isSet(object.serviceRouteId) ? globalThis.String(object.serviceRouteId) : "",
|
|
413
294
|
};
|
|
414
295
|
},
|
|
415
296
|
|
|
416
297
|
toJSON(message: Route): unknown {
|
|
417
298
|
const obj: any = {};
|
|
418
|
-
if (message.stopTimes
|
|
419
|
-
obj.stopTimes = message.stopTimes
|
|
299
|
+
if (message.stopTimes.length !== 0) {
|
|
300
|
+
obj.stopTimes = base64FromBytes(message.stopTimes);
|
|
420
301
|
}
|
|
421
|
-
if (message.
|
|
422
|
-
obj.
|
|
302
|
+
if (message.pickUpDropOffTypes.length !== 0) {
|
|
303
|
+
obj.pickUpDropOffTypes = base64FromBytes(message.pickUpDropOffTypes);
|
|
304
|
+
}
|
|
305
|
+
if (message.stops.length !== 0) {
|
|
306
|
+
obj.stops = base64FromBytes(message.stops);
|
|
423
307
|
}
|
|
424
308
|
if (message.serviceRouteId !== "") {
|
|
425
309
|
obj.serviceRouteId = message.serviceRouteId;
|
|
@@ -432,8 +316,9 @@ export const Route: MessageFns<Route> = {
|
|
|
432
316
|
},
|
|
433
317
|
fromPartial<I extends Exact<DeepPartial<Route>, I>>(object: I): Route {
|
|
434
318
|
const message = createBaseRoute();
|
|
435
|
-
message.stopTimes = object.stopTimes
|
|
436
|
-
message.
|
|
319
|
+
message.stopTimes = object.stopTimes ?? new Uint8Array(0);
|
|
320
|
+
message.pickUpDropOffTypes = object.pickUpDropOffTypes ?? new Uint8Array(0);
|
|
321
|
+
message.stops = object.stops ?? new Uint8Array(0);
|
|
437
322
|
message.serviceRouteId = object.serviceRouteId ?? "";
|
|
438
323
|
return message;
|
|
439
324
|
},
|
|
@@ -595,13 +480,13 @@ export const RoutesAdjacency_RoutesEntry: MessageFns<RoutesAdjacency_RoutesEntry
|
|
|
595
480
|
};
|
|
596
481
|
|
|
597
482
|
function createBaseTransfer(): Transfer {
|
|
598
|
-
return { destination:
|
|
483
|
+
return { destination: 0, type: 0, minTransferTime: undefined };
|
|
599
484
|
}
|
|
600
485
|
|
|
601
486
|
export const Transfer: MessageFns<Transfer> = {
|
|
602
487
|
encode(message: Transfer, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
|
603
|
-
if (message.destination !==
|
|
604
|
-
writer.uint32(
|
|
488
|
+
if (message.destination !== 0) {
|
|
489
|
+
writer.uint32(8).uint32(message.destination);
|
|
605
490
|
}
|
|
606
491
|
if (message.type !== 0) {
|
|
607
492
|
writer.uint32(16).int32(message.type);
|
|
@@ -620,11 +505,11 @@ export const Transfer: MessageFns<Transfer> = {
|
|
|
620
505
|
const tag = reader.uint32();
|
|
621
506
|
switch (tag >>> 3) {
|
|
622
507
|
case 1: {
|
|
623
|
-
if (tag !==
|
|
508
|
+
if (tag !== 8) {
|
|
624
509
|
break;
|
|
625
510
|
}
|
|
626
511
|
|
|
627
|
-
message.destination = reader.
|
|
512
|
+
message.destination = reader.uint32();
|
|
628
513
|
continue;
|
|
629
514
|
}
|
|
630
515
|
case 2: {
|
|
@@ -654,7 +539,7 @@ export const Transfer: MessageFns<Transfer> = {
|
|
|
654
539
|
|
|
655
540
|
fromJSON(object: any): Transfer {
|
|
656
541
|
return {
|
|
657
|
-
destination: isSet(object.destination) ? globalThis.
|
|
542
|
+
destination: isSet(object.destination) ? globalThis.Number(object.destination) : 0,
|
|
658
543
|
type: isSet(object.type) ? transferTypeFromJSON(object.type) : 0,
|
|
659
544
|
minTransferTime: isSet(object.minTransferTime) ? globalThis.Number(object.minTransferTime) : undefined,
|
|
660
545
|
};
|
|
@@ -662,8 +547,8 @@ export const Transfer: MessageFns<Transfer> = {
|
|
|
662
547
|
|
|
663
548
|
toJSON(message: Transfer): unknown {
|
|
664
549
|
const obj: any = {};
|
|
665
|
-
if (message.destination !==
|
|
666
|
-
obj.destination = message.destination;
|
|
550
|
+
if (message.destination !== 0) {
|
|
551
|
+
obj.destination = Math.round(message.destination);
|
|
667
552
|
}
|
|
668
553
|
if (message.type !== 0) {
|
|
669
554
|
obj.type = transferTypeToJSON(message.type);
|
|
@@ -679,7 +564,7 @@ export const Transfer: MessageFns<Transfer> = {
|
|
|
679
564
|
},
|
|
680
565
|
fromPartial<I extends Exact<DeepPartial<Transfer>, I>>(object: I): Transfer {
|
|
681
566
|
const message = createBaseTransfer();
|
|
682
|
-
message.destination = object.destination ??
|
|
567
|
+
message.destination = object.destination ?? 0;
|
|
683
568
|
message.type = object.type ?? 0;
|
|
684
569
|
message.minTransferTime = object.minTransferTime ?? undefined;
|
|
685
570
|
return message;
|
|
@@ -1274,6 +1159,31 @@ export const Timetable: MessageFns<Timetable> = {
|
|
|
1274
1159
|
},
|
|
1275
1160
|
};
|
|
1276
1161
|
|
|
1162
|
+
function bytesFromBase64(b64: string): Uint8Array {
|
|
1163
|
+
if ((globalThis as any).Buffer) {
|
|
1164
|
+
return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
|
|
1165
|
+
} else {
|
|
1166
|
+
const bin = globalThis.atob(b64);
|
|
1167
|
+
const arr = new Uint8Array(bin.length);
|
|
1168
|
+
for (let i = 0; i < bin.length; ++i) {
|
|
1169
|
+
arr[i] = bin.charCodeAt(i);
|
|
1170
|
+
}
|
|
1171
|
+
return arr;
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
function base64FromBytes(arr: Uint8Array): string {
|
|
1176
|
+
if ((globalThis as any).Buffer) {
|
|
1177
|
+
return globalThis.Buffer.from(arr).toString("base64");
|
|
1178
|
+
} else {
|
|
1179
|
+
const bin: string[] = [];
|
|
1180
|
+
arr.forEach((byte) => {
|
|
1181
|
+
bin.push(globalThis.String.fromCharCode(byte));
|
|
1182
|
+
});
|
|
1183
|
+
return globalThis.btoa(bin.join(""));
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1277
1187
|
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
1278
1188
|
|
|
1279
1189
|
export type DeepPartial<T> = T extends Builtin ? T
|
|
@@ -13,29 +13,55 @@ import {
|
|
|
13
13
|
import { Timetable as ProtoTimetable } from './proto/timetable.js';
|
|
14
14
|
import { Time } from './time.js';
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
| 'REGULAR'
|
|
18
|
-
| 'NOT_AVAILABLE'
|
|
19
|
-
| 'MUST_PHONE_AGENCY'
|
|
20
|
-
| 'MUST_COORDINATE_WITH_DRIVER';
|
|
21
|
-
|
|
22
|
-
export type StopTimes = {
|
|
23
|
-
arrival: Time;
|
|
24
|
-
departure: Time;
|
|
25
|
-
pickUpType: PickUpDropOffType;
|
|
26
|
-
dropOffType: PickUpDropOffType;
|
|
27
|
-
};
|
|
16
|
+
// Identifies all trips of a given service route sharing the same list of stops.
|
|
28
17
|
export type RouteId = string;
|
|
29
18
|
|
|
30
|
-
export
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
19
|
+
export const REGULAR = 0;
|
|
20
|
+
export const NOT_AVAILABLE = 1;
|
|
21
|
+
export const MUST_PHONE_AGENCY = 2;
|
|
22
|
+
export const MUST_COORDINATE_WITH_DRIVER = 3;
|
|
23
|
+
|
|
24
|
+
export type PickUpDropOffType =
|
|
25
|
+
| 0 // REGULAR
|
|
26
|
+
| 1 // NOT_AVAILABLE
|
|
27
|
+
| 2 // MUST_PHONE_AGENCY
|
|
28
|
+
| 3; // MUST_COORDINATE_WITH_DRIVER
|
|
29
|
+
|
|
34
30
|
export type Route = {
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Arrivals and departures encoded as a binary array.
|
|
33
|
+
* Format: [arrival1, departure1, arrival2, departure2, etc.]
|
|
34
|
+
*/
|
|
35
|
+
stopTimes: Uint32Array;
|
|
36
|
+
/**
|
|
37
|
+
* PickUp and DropOff types represented as a binary Uint8Array.
|
|
38
|
+
* Values:
|
|
39
|
+
* 0: REGULAR
|
|
40
|
+
* 1: NOT_AVAILABLE
|
|
41
|
+
* 2: MUST_PHONE_AGENCY
|
|
42
|
+
* 3: MUST_COORDINATE_WITH_DRIVER
|
|
43
|
+
* Format: [pickupTypeStop1, dropOffTypeStop1, pickupTypeStop2, dropOffTypeStop2, etc.]
|
|
44
|
+
*/
|
|
45
|
+
pickUpDropOffTypes: Uint8Array;
|
|
46
|
+
/**
|
|
47
|
+
* A binary array of stopIds in the route.
|
|
48
|
+
* [stop1, stop2, stop3,...]
|
|
49
|
+
*/
|
|
50
|
+
stops: Uint32Array;
|
|
51
|
+
/**
|
|
52
|
+
* A reverse mapping of each stop with their index in the route:
|
|
53
|
+
* {
|
|
54
|
+
* 4: 0,
|
|
55
|
+
* 5: 1,
|
|
56
|
+
* ...
|
|
57
|
+
* }
|
|
58
|
+
*/
|
|
37
59
|
stopIndices: Map<StopId, number>;
|
|
60
|
+
/**
|
|
61
|
+
* The identifier of the route as a service shown to users.
|
|
62
|
+
*/
|
|
38
63
|
serviceRouteId: ServiceRouteId;
|
|
64
|
+
// TODO Add tripIds for real-time support
|
|
39
65
|
};
|
|
40
66
|
export type RoutesAdjacency = Map<RouteId, Route>;
|
|
41
67
|
|
|
@@ -101,7 +127,7 @@ export const ALL_TRANSPORT_MODES: RouteType[] = [
|
|
|
101
127
|
'MONORAIL',
|
|
102
128
|
];
|
|
103
129
|
|
|
104
|
-
export const CURRENT_VERSION = '0.0.
|
|
130
|
+
export const CURRENT_VERSION = '0.0.2';
|
|
105
131
|
|
|
106
132
|
/**
|
|
107
133
|
* The internal transit timetable format
|
|
@@ -165,6 +191,14 @@ export class Timetable {
|
|
|
165
191
|
);
|
|
166
192
|
}
|
|
167
193
|
|
|
194
|
+
getRoutesThroughStop(stopId: StopId): RouteId[] {
|
|
195
|
+
const stopAdjacency = this.stopsAdjacency.get(stopId);
|
|
196
|
+
if (!stopAdjacency) {
|
|
197
|
+
return [];
|
|
198
|
+
}
|
|
199
|
+
return stopAdjacency.routes;
|
|
200
|
+
}
|
|
201
|
+
|
|
168
202
|
getRoute(routeId: RouteId): Route | undefined {
|
|
169
203
|
return this.routesAdjacency.get(routeId);
|
|
170
204
|
}
|
|
@@ -249,11 +283,9 @@ export class Timetable {
|
|
|
249
283
|
tripIndex++
|
|
250
284
|
) {
|
|
251
285
|
const stopTimeIndex = tripIndex * stopsNumber + stopIndex;
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
stopTime.pickUpType !== 'NOT_AVAILABLE'
|
|
256
|
-
) {
|
|
286
|
+
const departure = route.stopTimes[stopTimeIndex * 2 + 1]!;
|
|
287
|
+
const pickUpType = route.pickUpDropOffTypes[stopTimeIndex * 2]!;
|
|
288
|
+
if (departure >= after.toSeconds() && pickUpType !== NOT_AVAILABLE) {
|
|
257
289
|
return tripIndex;
|
|
258
290
|
}
|
|
259
291
|
}
|
|
@@ -267,17 +299,18 @@ export class Timetable {
|
|
|
267
299
|
tripIndex--
|
|
268
300
|
) {
|
|
269
301
|
const stopTimeIndex = tripIndex * stopsNumber + stopIndex;
|
|
270
|
-
const
|
|
271
|
-
|
|
302
|
+
const departure = route.stopTimes[stopTimeIndex * 2 + 1]!;
|
|
303
|
+
const pickUpType = route.pickUpDropOffTypes[stopTimeIndex * 2]!;
|
|
304
|
+
if (departure < after.toSeconds()) {
|
|
272
305
|
break;
|
|
273
306
|
}
|
|
274
307
|
if (
|
|
275
|
-
|
|
308
|
+
pickUpType !== NOT_AVAILABLE &&
|
|
276
309
|
(earliestDeparture === undefined ||
|
|
277
|
-
|
|
310
|
+
departure < earliestDeparture.toSeconds())
|
|
278
311
|
) {
|
|
279
312
|
earliestTripIndex = tripIndex;
|
|
280
|
-
earliestDeparture =
|
|
313
|
+
earliestDeparture = Time.fromSeconds(departure);
|
|
281
314
|
}
|
|
282
315
|
}
|
|
283
316
|
return earliestTripIndex;
|