minotor 3.0.2 → 5.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 +9 -3
- package/README.md +1 -0
- package/dist/cli.mjs +294 -307
- package/dist/cli.mjs.map +1 -1
- package/dist/gtfs/trips.d.ts +12 -6
- package/dist/parser.cjs.js +290 -302
- package/dist/parser.cjs.js.map +1 -1
- package/dist/parser.esm.js +290 -302
- 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 +2 -2
- 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/route.d.ts +3 -3
- package/dist/timetable/io.d.ts +5 -4
- package/dist/timetable/proto/timetable.d.ts +7 -16
- package/dist/timetable/route.d.ts +7 -5
- package/dist/timetable/timetable.d.ts +7 -5
- package/package.json +1 -1
- package/src/__e2e__/timetable/timetable.bin +2 -2
- package/src/cli/repl.ts +0 -1
- package/src/gtfs/__tests__/parser.test.ts +2 -2
- package/src/gtfs/__tests__/routes.test.ts +3 -0
- package/src/gtfs/__tests__/trips.test.ts +123 -166
- package/src/gtfs/parser.ts +50 -9
- package/src/gtfs/routes.ts +1 -0
- package/src/gtfs/trips.ts +195 -112
- package/src/router.ts +2 -2
- package/src/routing/__tests__/route.test.ts +3 -3
- package/src/routing/__tests__/router.test.ts +186 -203
- package/src/routing/route.ts +3 -3
- package/src/routing/router.ts +1 -1
- package/src/timetable/__tests__/io.test.ts +52 -64
- package/src/timetable/__tests__/route.test.ts +25 -17
- package/src/timetable/__tests__/timetable.test.ts +16 -24
- package/src/timetable/io.ts +20 -19
- package/src/timetable/proto/timetable.proto +7 -9
- package/src/timetable/proto/timetable.ts +80 -202
- package/src/timetable/route.ts +27 -13
- package/src/timetable/timetable.ts +20 -16
|
@@ -148,7 +148,8 @@ export interface Route {
|
|
|
148
148
|
* 1: NOT_AVAILABLE
|
|
149
149
|
* 2: MUST_PHONE_AGENCY
|
|
150
150
|
* 3: MUST_COORDINATE_WITH_DRIVER
|
|
151
|
-
* Format: [
|
|
151
|
+
* Format: [drop_off_1][pickup_1][drop_off_0][pickup_0]
|
|
152
|
+
* 2 bits per value
|
|
152
153
|
*/
|
|
153
154
|
pickUpDropOffTypes: Uint8Array;
|
|
154
155
|
/**
|
|
@@ -159,15 +160,6 @@ export interface Route {
|
|
|
159
160
|
serviceRouteId: string;
|
|
160
161
|
}
|
|
161
162
|
|
|
162
|
-
export interface RoutesAdjacency {
|
|
163
|
-
routes: { [key: string]: Route };
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export interface RoutesAdjacency_RoutesEntry {
|
|
167
|
-
key: string;
|
|
168
|
-
value: Route | undefined;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
163
|
export interface Transfer {
|
|
172
164
|
destination: number;
|
|
173
165
|
type: TransferType;
|
|
@@ -175,22 +167,23 @@ export interface Transfer {
|
|
|
175
167
|
}
|
|
176
168
|
|
|
177
169
|
export interface StopsAdjacency {
|
|
178
|
-
stops: { [key:
|
|
170
|
+
stops: { [key: number]: StopsAdjacency_StopAdjacency };
|
|
179
171
|
}
|
|
180
172
|
|
|
181
173
|
export interface StopsAdjacency_StopAdjacency {
|
|
182
174
|
transfers: Transfer[];
|
|
183
|
-
routes:
|
|
175
|
+
routes: number[];
|
|
184
176
|
}
|
|
185
177
|
|
|
186
178
|
export interface StopsAdjacency_StopsEntry {
|
|
187
|
-
key:
|
|
179
|
+
key: number;
|
|
188
180
|
value: StopsAdjacency_StopAdjacency | undefined;
|
|
189
181
|
}
|
|
190
182
|
|
|
191
183
|
export interface ServiceRoute {
|
|
192
184
|
type: RouteType;
|
|
193
185
|
name: string;
|
|
186
|
+
routes: number[];
|
|
194
187
|
}
|
|
195
188
|
|
|
196
189
|
export interface ServiceRoutesMap {
|
|
@@ -205,7 +198,7 @@ export interface ServiceRoutesMap_RoutesEntry {
|
|
|
205
198
|
export interface Timetable {
|
|
206
199
|
version: string;
|
|
207
200
|
stopsAdjacency: StopsAdjacency | undefined;
|
|
208
|
-
routesAdjacency:
|
|
201
|
+
routesAdjacency: Route[];
|
|
209
202
|
routes: ServiceRoutesMap | undefined;
|
|
210
203
|
}
|
|
211
204
|
|
|
@@ -324,161 +317,6 @@ export const Route: MessageFns<Route> = {
|
|
|
324
317
|
},
|
|
325
318
|
};
|
|
326
319
|
|
|
327
|
-
function createBaseRoutesAdjacency(): RoutesAdjacency {
|
|
328
|
-
return { routes: {} };
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
export const RoutesAdjacency: MessageFns<RoutesAdjacency> = {
|
|
332
|
-
encode(message: RoutesAdjacency, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
|
333
|
-
Object.entries(message.routes).forEach(([key, value]) => {
|
|
334
|
-
RoutesAdjacency_RoutesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
|
335
|
-
});
|
|
336
|
-
return writer;
|
|
337
|
-
},
|
|
338
|
-
|
|
339
|
-
decode(input: BinaryReader | Uint8Array, length?: number): RoutesAdjacency {
|
|
340
|
-
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
341
|
-
const end = length === undefined ? reader.len : reader.pos + length;
|
|
342
|
-
const message = createBaseRoutesAdjacency();
|
|
343
|
-
while (reader.pos < end) {
|
|
344
|
-
const tag = reader.uint32();
|
|
345
|
-
switch (tag >>> 3) {
|
|
346
|
-
case 1: {
|
|
347
|
-
if (tag !== 10) {
|
|
348
|
-
break;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
const entry1 = RoutesAdjacency_RoutesEntry.decode(reader, reader.uint32());
|
|
352
|
-
if (entry1.value !== undefined) {
|
|
353
|
-
message.routes[entry1.key] = entry1.value;
|
|
354
|
-
}
|
|
355
|
-
continue;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
if ((tag & 7) === 4 || tag === 0) {
|
|
359
|
-
break;
|
|
360
|
-
}
|
|
361
|
-
reader.skip(tag & 7);
|
|
362
|
-
}
|
|
363
|
-
return message;
|
|
364
|
-
},
|
|
365
|
-
|
|
366
|
-
fromJSON(object: any): RoutesAdjacency {
|
|
367
|
-
return {
|
|
368
|
-
routes: isObject(object.routes)
|
|
369
|
-
? Object.entries(object.routes).reduce<{ [key: string]: Route }>((acc, [key, value]) => {
|
|
370
|
-
acc[key] = Route.fromJSON(value);
|
|
371
|
-
return acc;
|
|
372
|
-
}, {})
|
|
373
|
-
: {},
|
|
374
|
-
};
|
|
375
|
-
},
|
|
376
|
-
|
|
377
|
-
toJSON(message: RoutesAdjacency): unknown {
|
|
378
|
-
const obj: any = {};
|
|
379
|
-
if (message.routes) {
|
|
380
|
-
const entries = Object.entries(message.routes);
|
|
381
|
-
if (entries.length > 0) {
|
|
382
|
-
obj.routes = {};
|
|
383
|
-
entries.forEach(([k, v]) => {
|
|
384
|
-
obj.routes[k] = Route.toJSON(v);
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
return obj;
|
|
389
|
-
},
|
|
390
|
-
|
|
391
|
-
create<I extends Exact<DeepPartial<RoutesAdjacency>, I>>(base?: I): RoutesAdjacency {
|
|
392
|
-
return RoutesAdjacency.fromPartial(base ?? ({} as any));
|
|
393
|
-
},
|
|
394
|
-
fromPartial<I extends Exact<DeepPartial<RoutesAdjacency>, I>>(object: I): RoutesAdjacency {
|
|
395
|
-
const message = createBaseRoutesAdjacency();
|
|
396
|
-
message.routes = Object.entries(object.routes ?? {}).reduce<{ [key: string]: Route }>((acc, [key, value]) => {
|
|
397
|
-
if (value !== undefined) {
|
|
398
|
-
acc[key] = Route.fromPartial(value);
|
|
399
|
-
}
|
|
400
|
-
return acc;
|
|
401
|
-
}, {});
|
|
402
|
-
return message;
|
|
403
|
-
},
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
function createBaseRoutesAdjacency_RoutesEntry(): RoutesAdjacency_RoutesEntry {
|
|
407
|
-
return { key: "", value: undefined };
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
export const RoutesAdjacency_RoutesEntry: MessageFns<RoutesAdjacency_RoutesEntry> = {
|
|
411
|
-
encode(message: RoutesAdjacency_RoutesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
|
412
|
-
if (message.key !== "") {
|
|
413
|
-
writer.uint32(10).string(message.key);
|
|
414
|
-
}
|
|
415
|
-
if (message.value !== undefined) {
|
|
416
|
-
Route.encode(message.value, writer.uint32(18).fork()).join();
|
|
417
|
-
}
|
|
418
|
-
return writer;
|
|
419
|
-
},
|
|
420
|
-
|
|
421
|
-
decode(input: BinaryReader | Uint8Array, length?: number): RoutesAdjacency_RoutesEntry {
|
|
422
|
-
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
423
|
-
const end = length === undefined ? reader.len : reader.pos + length;
|
|
424
|
-
const message = createBaseRoutesAdjacency_RoutesEntry();
|
|
425
|
-
while (reader.pos < end) {
|
|
426
|
-
const tag = reader.uint32();
|
|
427
|
-
switch (tag >>> 3) {
|
|
428
|
-
case 1: {
|
|
429
|
-
if (tag !== 10) {
|
|
430
|
-
break;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
message.key = reader.string();
|
|
434
|
-
continue;
|
|
435
|
-
}
|
|
436
|
-
case 2: {
|
|
437
|
-
if (tag !== 18) {
|
|
438
|
-
break;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
message.value = Route.decode(reader, reader.uint32());
|
|
442
|
-
continue;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
if ((tag & 7) === 4 || tag === 0) {
|
|
446
|
-
break;
|
|
447
|
-
}
|
|
448
|
-
reader.skip(tag & 7);
|
|
449
|
-
}
|
|
450
|
-
return message;
|
|
451
|
-
},
|
|
452
|
-
|
|
453
|
-
fromJSON(object: any): RoutesAdjacency_RoutesEntry {
|
|
454
|
-
return {
|
|
455
|
-
key: isSet(object.key) ? globalThis.String(object.key) : "",
|
|
456
|
-
value: isSet(object.value) ? Route.fromJSON(object.value) : undefined,
|
|
457
|
-
};
|
|
458
|
-
},
|
|
459
|
-
|
|
460
|
-
toJSON(message: RoutesAdjacency_RoutesEntry): unknown {
|
|
461
|
-
const obj: any = {};
|
|
462
|
-
if (message.key !== "") {
|
|
463
|
-
obj.key = message.key;
|
|
464
|
-
}
|
|
465
|
-
if (message.value !== undefined) {
|
|
466
|
-
obj.value = Route.toJSON(message.value);
|
|
467
|
-
}
|
|
468
|
-
return obj;
|
|
469
|
-
},
|
|
470
|
-
|
|
471
|
-
create<I extends Exact<DeepPartial<RoutesAdjacency_RoutesEntry>, I>>(base?: I): RoutesAdjacency_RoutesEntry {
|
|
472
|
-
return RoutesAdjacency_RoutesEntry.fromPartial(base ?? ({} as any));
|
|
473
|
-
},
|
|
474
|
-
fromPartial<I extends Exact<DeepPartial<RoutesAdjacency_RoutesEntry>, I>>(object: I): RoutesAdjacency_RoutesEntry {
|
|
475
|
-
const message = createBaseRoutesAdjacency_RoutesEntry();
|
|
476
|
-
message.key = object.key ?? "";
|
|
477
|
-
message.value = (object.value !== undefined && object.value !== null) ? Route.fromPartial(object.value) : undefined;
|
|
478
|
-
return message;
|
|
479
|
-
},
|
|
480
|
-
};
|
|
481
|
-
|
|
482
320
|
function createBaseTransfer(): Transfer {
|
|
483
321
|
return { destination: 0, type: 0, minTransferTime: undefined };
|
|
484
322
|
}
|
|
@@ -492,7 +330,7 @@ export const Transfer: MessageFns<Transfer> = {
|
|
|
492
330
|
writer.uint32(16).int32(message.type);
|
|
493
331
|
}
|
|
494
332
|
if (message.minTransferTime !== undefined) {
|
|
495
|
-
writer.uint32(24).
|
|
333
|
+
writer.uint32(24).uint32(message.minTransferTime);
|
|
496
334
|
}
|
|
497
335
|
return writer;
|
|
498
336
|
},
|
|
@@ -525,7 +363,7 @@ export const Transfer: MessageFns<Transfer> = {
|
|
|
525
363
|
break;
|
|
526
364
|
}
|
|
527
365
|
|
|
528
|
-
message.minTransferTime = reader.
|
|
366
|
+
message.minTransferTime = reader.uint32();
|
|
529
367
|
continue;
|
|
530
368
|
}
|
|
531
369
|
}
|
|
@@ -613,8 +451,8 @@ export const StopsAdjacency: MessageFns<StopsAdjacency> = {
|
|
|
613
451
|
fromJSON(object: any): StopsAdjacency {
|
|
614
452
|
return {
|
|
615
453
|
stops: isObject(object.stops)
|
|
616
|
-
? Object.entries(object.stops).reduce<{ [key:
|
|
617
|
-
acc[key] = StopsAdjacency_StopAdjacency.fromJSON(value);
|
|
454
|
+
? Object.entries(object.stops).reduce<{ [key: number]: StopsAdjacency_StopAdjacency }>((acc, [key, value]) => {
|
|
455
|
+
acc[globalThis.Number(key)] = StopsAdjacency_StopAdjacency.fromJSON(value);
|
|
618
456
|
return acc;
|
|
619
457
|
}, {})
|
|
620
458
|
: {},
|
|
@@ -640,10 +478,10 @@ export const StopsAdjacency: MessageFns<StopsAdjacency> = {
|
|
|
640
478
|
},
|
|
641
479
|
fromPartial<I extends Exact<DeepPartial<StopsAdjacency>, I>>(object: I): StopsAdjacency {
|
|
642
480
|
const message = createBaseStopsAdjacency();
|
|
643
|
-
message.stops = Object.entries(object.stops ?? {}).reduce<{ [key:
|
|
481
|
+
message.stops = Object.entries(object.stops ?? {}).reduce<{ [key: number]: StopsAdjacency_StopAdjacency }>(
|
|
644
482
|
(acc, [key, value]) => {
|
|
645
483
|
if (value !== undefined) {
|
|
646
|
-
acc[key] = StopsAdjacency_StopAdjacency.fromPartial(value);
|
|
484
|
+
acc[globalThis.Number(key)] = StopsAdjacency_StopAdjacency.fromPartial(value);
|
|
647
485
|
}
|
|
648
486
|
return acc;
|
|
649
487
|
},
|
|
@@ -662,9 +500,11 @@ export const StopsAdjacency_StopAdjacency: MessageFns<StopsAdjacency_StopAdjacen
|
|
|
662
500
|
for (const v of message.transfers) {
|
|
663
501
|
Transfer.encode(v!, writer.uint32(10).fork()).join();
|
|
664
502
|
}
|
|
503
|
+
writer.uint32(18).fork();
|
|
665
504
|
for (const v of message.routes) {
|
|
666
|
-
writer.
|
|
505
|
+
writer.int32(v);
|
|
667
506
|
}
|
|
507
|
+
writer.join();
|
|
668
508
|
return writer;
|
|
669
509
|
},
|
|
670
510
|
|
|
@@ -684,12 +524,22 @@ export const StopsAdjacency_StopAdjacency: MessageFns<StopsAdjacency_StopAdjacen
|
|
|
684
524
|
continue;
|
|
685
525
|
}
|
|
686
526
|
case 2: {
|
|
687
|
-
if (tag
|
|
688
|
-
|
|
527
|
+
if (tag === 16) {
|
|
528
|
+
message.routes.push(reader.int32());
|
|
529
|
+
|
|
530
|
+
continue;
|
|
689
531
|
}
|
|
690
532
|
|
|
691
|
-
|
|
692
|
-
|
|
533
|
+
if (tag === 18) {
|
|
534
|
+
const end2 = reader.uint32() + reader.pos;
|
|
535
|
+
while (reader.pos < end2) {
|
|
536
|
+
message.routes.push(reader.int32());
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
break;
|
|
693
543
|
}
|
|
694
544
|
}
|
|
695
545
|
if ((tag & 7) === 4 || tag === 0) {
|
|
@@ -705,7 +555,7 @@ export const StopsAdjacency_StopAdjacency: MessageFns<StopsAdjacency_StopAdjacen
|
|
|
705
555
|
transfers: globalThis.Array.isArray(object?.transfers)
|
|
706
556
|
? object.transfers.map((e: any) => Transfer.fromJSON(e))
|
|
707
557
|
: [],
|
|
708
|
-
routes: globalThis.Array.isArray(object?.routes) ? object.routes.map((e: any) => globalThis.
|
|
558
|
+
routes: globalThis.Array.isArray(object?.routes) ? object.routes.map((e: any) => globalThis.Number(e)) : [],
|
|
709
559
|
};
|
|
710
560
|
},
|
|
711
561
|
|
|
@@ -715,7 +565,7 @@ export const StopsAdjacency_StopAdjacency: MessageFns<StopsAdjacency_StopAdjacen
|
|
|
715
565
|
obj.transfers = message.transfers.map((e) => Transfer.toJSON(e));
|
|
716
566
|
}
|
|
717
567
|
if (message.routes?.length) {
|
|
718
|
-
obj.routes = message.routes;
|
|
568
|
+
obj.routes = message.routes.map((e) => Math.round(e));
|
|
719
569
|
}
|
|
720
570
|
return obj;
|
|
721
571
|
},
|
|
@@ -732,13 +582,13 @@ export const StopsAdjacency_StopAdjacency: MessageFns<StopsAdjacency_StopAdjacen
|
|
|
732
582
|
};
|
|
733
583
|
|
|
734
584
|
function createBaseStopsAdjacency_StopsEntry(): StopsAdjacency_StopsEntry {
|
|
735
|
-
return { key:
|
|
585
|
+
return { key: 0, value: undefined };
|
|
736
586
|
}
|
|
737
587
|
|
|
738
588
|
export const StopsAdjacency_StopsEntry: MessageFns<StopsAdjacency_StopsEntry> = {
|
|
739
589
|
encode(message: StopsAdjacency_StopsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
|
740
|
-
if (message.key !==
|
|
741
|
-
writer.uint32(
|
|
590
|
+
if (message.key !== 0) {
|
|
591
|
+
writer.uint32(8).uint32(message.key);
|
|
742
592
|
}
|
|
743
593
|
if (message.value !== undefined) {
|
|
744
594
|
StopsAdjacency_StopAdjacency.encode(message.value, writer.uint32(18).fork()).join();
|
|
@@ -754,11 +604,11 @@ export const StopsAdjacency_StopsEntry: MessageFns<StopsAdjacency_StopsEntry> =
|
|
|
754
604
|
const tag = reader.uint32();
|
|
755
605
|
switch (tag >>> 3) {
|
|
756
606
|
case 1: {
|
|
757
|
-
if (tag !==
|
|
607
|
+
if (tag !== 8) {
|
|
758
608
|
break;
|
|
759
609
|
}
|
|
760
610
|
|
|
761
|
-
message.key = reader.
|
|
611
|
+
message.key = reader.uint32();
|
|
762
612
|
continue;
|
|
763
613
|
}
|
|
764
614
|
case 2: {
|
|
@@ -780,15 +630,15 @@ export const StopsAdjacency_StopsEntry: MessageFns<StopsAdjacency_StopsEntry> =
|
|
|
780
630
|
|
|
781
631
|
fromJSON(object: any): StopsAdjacency_StopsEntry {
|
|
782
632
|
return {
|
|
783
|
-
key: isSet(object.key) ? globalThis.
|
|
633
|
+
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
|
784
634
|
value: isSet(object.value) ? StopsAdjacency_StopAdjacency.fromJSON(object.value) : undefined,
|
|
785
635
|
};
|
|
786
636
|
},
|
|
787
637
|
|
|
788
638
|
toJSON(message: StopsAdjacency_StopsEntry): unknown {
|
|
789
639
|
const obj: any = {};
|
|
790
|
-
if (message.key !==
|
|
791
|
-
obj.key = message.key;
|
|
640
|
+
if (message.key !== 0) {
|
|
641
|
+
obj.key = Math.round(message.key);
|
|
792
642
|
}
|
|
793
643
|
if (message.value !== undefined) {
|
|
794
644
|
obj.value = StopsAdjacency_StopAdjacency.toJSON(message.value);
|
|
@@ -801,7 +651,7 @@ export const StopsAdjacency_StopsEntry: MessageFns<StopsAdjacency_StopsEntry> =
|
|
|
801
651
|
},
|
|
802
652
|
fromPartial<I extends Exact<DeepPartial<StopsAdjacency_StopsEntry>, I>>(object: I): StopsAdjacency_StopsEntry {
|
|
803
653
|
const message = createBaseStopsAdjacency_StopsEntry();
|
|
804
|
-
message.key = object.key ??
|
|
654
|
+
message.key = object.key ?? 0;
|
|
805
655
|
message.value = (object.value !== undefined && object.value !== null)
|
|
806
656
|
? StopsAdjacency_StopAdjacency.fromPartial(object.value)
|
|
807
657
|
: undefined;
|
|
@@ -810,7 +660,7 @@ export const StopsAdjacency_StopsEntry: MessageFns<StopsAdjacency_StopsEntry> =
|
|
|
810
660
|
};
|
|
811
661
|
|
|
812
662
|
function createBaseServiceRoute(): ServiceRoute {
|
|
813
|
-
return { type: 0, name: "" };
|
|
663
|
+
return { type: 0, name: "", routes: [] };
|
|
814
664
|
}
|
|
815
665
|
|
|
816
666
|
export const ServiceRoute: MessageFns<ServiceRoute> = {
|
|
@@ -821,6 +671,11 @@ export const ServiceRoute: MessageFns<ServiceRoute> = {
|
|
|
821
671
|
if (message.name !== "") {
|
|
822
672
|
writer.uint32(18).string(message.name);
|
|
823
673
|
}
|
|
674
|
+
writer.uint32(26).fork();
|
|
675
|
+
for (const v of message.routes) {
|
|
676
|
+
writer.int32(v);
|
|
677
|
+
}
|
|
678
|
+
writer.join();
|
|
824
679
|
return writer;
|
|
825
680
|
},
|
|
826
681
|
|
|
@@ -847,6 +702,24 @@ export const ServiceRoute: MessageFns<ServiceRoute> = {
|
|
|
847
702
|
message.name = reader.string();
|
|
848
703
|
continue;
|
|
849
704
|
}
|
|
705
|
+
case 3: {
|
|
706
|
+
if (tag === 24) {
|
|
707
|
+
message.routes.push(reader.int32());
|
|
708
|
+
|
|
709
|
+
continue;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
if (tag === 26) {
|
|
713
|
+
const end2 = reader.uint32() + reader.pos;
|
|
714
|
+
while (reader.pos < end2) {
|
|
715
|
+
message.routes.push(reader.int32());
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
break;
|
|
722
|
+
}
|
|
850
723
|
}
|
|
851
724
|
if ((tag & 7) === 4 || tag === 0) {
|
|
852
725
|
break;
|
|
@@ -860,6 +733,7 @@ export const ServiceRoute: MessageFns<ServiceRoute> = {
|
|
|
860
733
|
return {
|
|
861
734
|
type: isSet(object.type) ? routeTypeFromJSON(object.type) : 0,
|
|
862
735
|
name: isSet(object.name) ? globalThis.String(object.name) : "",
|
|
736
|
+
routes: globalThis.Array.isArray(object?.routes) ? object.routes.map((e: any) => globalThis.Number(e)) : [],
|
|
863
737
|
};
|
|
864
738
|
},
|
|
865
739
|
|
|
@@ -871,6 +745,9 @@ export const ServiceRoute: MessageFns<ServiceRoute> = {
|
|
|
871
745
|
if (message.name !== "") {
|
|
872
746
|
obj.name = message.name;
|
|
873
747
|
}
|
|
748
|
+
if (message.routes?.length) {
|
|
749
|
+
obj.routes = message.routes.map((e) => Math.round(e));
|
|
750
|
+
}
|
|
874
751
|
return obj;
|
|
875
752
|
},
|
|
876
753
|
|
|
@@ -881,6 +758,7 @@ export const ServiceRoute: MessageFns<ServiceRoute> = {
|
|
|
881
758
|
const message = createBaseServiceRoute();
|
|
882
759
|
message.type = object.type ?? 0;
|
|
883
760
|
message.name = object.name ?? "";
|
|
761
|
+
message.routes = object.routes?.map((e) => e) || [];
|
|
884
762
|
return message;
|
|
885
763
|
},
|
|
886
764
|
};
|
|
@@ -1046,7 +924,7 @@ export const ServiceRoutesMap_RoutesEntry: MessageFns<ServiceRoutesMap_RoutesEnt
|
|
|
1046
924
|
};
|
|
1047
925
|
|
|
1048
926
|
function createBaseTimetable(): Timetable {
|
|
1049
|
-
return { version: "", stopsAdjacency: undefined, routesAdjacency:
|
|
927
|
+
return { version: "", stopsAdjacency: undefined, routesAdjacency: [], routes: undefined };
|
|
1050
928
|
}
|
|
1051
929
|
|
|
1052
930
|
export const Timetable: MessageFns<Timetable> = {
|
|
@@ -1057,8 +935,8 @@ export const Timetable: MessageFns<Timetable> = {
|
|
|
1057
935
|
if (message.stopsAdjacency !== undefined) {
|
|
1058
936
|
StopsAdjacency.encode(message.stopsAdjacency, writer.uint32(18).fork()).join();
|
|
1059
937
|
}
|
|
1060
|
-
|
|
1061
|
-
|
|
938
|
+
for (const v of message.routesAdjacency) {
|
|
939
|
+
Route.encode(v!, writer.uint32(26).fork()).join();
|
|
1062
940
|
}
|
|
1063
941
|
if (message.routes !== undefined) {
|
|
1064
942
|
ServiceRoutesMap.encode(message.routes, writer.uint32(34).fork()).join();
|
|
@@ -1094,7 +972,7 @@ export const Timetable: MessageFns<Timetable> = {
|
|
|
1094
972
|
break;
|
|
1095
973
|
}
|
|
1096
974
|
|
|
1097
|
-
message.routesAdjacency
|
|
975
|
+
message.routesAdjacency.push(Route.decode(reader, reader.uint32()));
|
|
1098
976
|
continue;
|
|
1099
977
|
}
|
|
1100
978
|
case 4: {
|
|
@@ -1118,7 +996,9 @@ export const Timetable: MessageFns<Timetable> = {
|
|
|
1118
996
|
return {
|
|
1119
997
|
version: isSet(object.version) ? globalThis.String(object.version) : "",
|
|
1120
998
|
stopsAdjacency: isSet(object.stopsAdjacency) ? StopsAdjacency.fromJSON(object.stopsAdjacency) : undefined,
|
|
1121
|
-
routesAdjacency:
|
|
999
|
+
routesAdjacency: globalThis.Array.isArray(object?.routesAdjacency)
|
|
1000
|
+
? object.routesAdjacency.map((e: any) => Route.fromJSON(e))
|
|
1001
|
+
: [],
|
|
1122
1002
|
routes: isSet(object.routes) ? ServiceRoutesMap.fromJSON(object.routes) : undefined,
|
|
1123
1003
|
};
|
|
1124
1004
|
},
|
|
@@ -1131,8 +1011,8 @@ export const Timetable: MessageFns<Timetable> = {
|
|
|
1131
1011
|
if (message.stopsAdjacency !== undefined) {
|
|
1132
1012
|
obj.stopsAdjacency = StopsAdjacency.toJSON(message.stopsAdjacency);
|
|
1133
1013
|
}
|
|
1134
|
-
if (message.routesAdjacency
|
|
1135
|
-
obj.routesAdjacency =
|
|
1014
|
+
if (message.routesAdjacency?.length) {
|
|
1015
|
+
obj.routesAdjacency = message.routesAdjacency.map((e) => Route.toJSON(e));
|
|
1136
1016
|
}
|
|
1137
1017
|
if (message.routes !== undefined) {
|
|
1138
1018
|
obj.routes = ServiceRoutesMap.toJSON(message.routes);
|
|
@@ -1149,9 +1029,7 @@ export const Timetable: MessageFns<Timetable> = {
|
|
|
1149
1029
|
message.stopsAdjacency = (object.stopsAdjacency !== undefined && object.stopsAdjacency !== null)
|
|
1150
1030
|
? StopsAdjacency.fromPartial(object.stopsAdjacency)
|
|
1151
1031
|
: undefined;
|
|
1152
|
-
message.routesAdjacency =
|
|
1153
|
-
? RoutesAdjacency.fromPartial(object.routesAdjacency)
|
|
1154
|
-
: undefined;
|
|
1032
|
+
message.routesAdjacency = object.routesAdjacency?.map((e) => Route.fromPartial(e)) || [];
|
|
1155
1033
|
message.routes = (object.routes !== undefined && object.routes !== null)
|
|
1156
1034
|
? ServiceRoutesMap.fromPartial(object.routes)
|
|
1157
1035
|
: undefined;
|
package/src/timetable/route.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { ServiceRouteId } from './timetable.js';
|
|
|
9
9
|
* This one is used for identifying groups of trips
|
|
10
10
|
* from a service route sharing the same list of stops.
|
|
11
11
|
*/
|
|
12
|
-
export type RouteId =
|
|
12
|
+
export type RouteId = number;
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Details about the pickup and drop-off modalities at each stop in each trip of a route.
|
|
@@ -65,14 +65,16 @@ export class Route {
|
|
|
65
65
|
*/
|
|
66
66
|
private readonly stopTimes: Uint16Array;
|
|
67
67
|
/**
|
|
68
|
-
* PickUp and DropOff types represented as a
|
|
69
|
-
* Values:
|
|
68
|
+
* PickUp and DropOff types represented as a 2-bit encoded Uint8Array.
|
|
69
|
+
* Values (2 bits each):
|
|
70
70
|
* 0: REGULAR
|
|
71
71
|
* 1: NOT_AVAILABLE
|
|
72
72
|
* 2: MUST_PHONE_AGENCY
|
|
73
73
|
* 3: MUST_COORDINATE_WITH_DRIVER
|
|
74
|
-
*
|
|
75
|
-
*
|
|
74
|
+
*
|
|
75
|
+
* Encoding format: Each byte contains 2 pickup/drop-off pairs (4 bits each)
|
|
76
|
+
* Bit layout per byte: [pickup_1 (2 bits)][drop_off_1 (2 bits)][pickup_0 (2 bits)][drop_off_0 (2 bits)]
|
|
77
|
+
* Example: For stops 0 and 1 in a trip, one byte encodes all 4 values
|
|
76
78
|
*/
|
|
77
79
|
private readonly pickUpDropOffTypes: Uint8Array;
|
|
78
80
|
/**
|
|
@@ -225,14 +227,20 @@ export class Route {
|
|
|
225
227
|
* @returns The pick-up type at the specified stop and trip.
|
|
226
228
|
*/
|
|
227
229
|
pickUpTypeFrom(stopId: StopId, tripIndex: TripIndex): PickUpDropOffType {
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
const
|
|
231
|
-
|
|
230
|
+
const globalIndex = tripIndex * this.stops.length + this.stopIndex(stopId);
|
|
231
|
+
const byteIndex = Math.floor(globalIndex / 2);
|
|
232
|
+
const isSecondPair = globalIndex % 2 === 1;
|
|
233
|
+
|
|
234
|
+
const byte = this.pickUpDropOffTypes[byteIndex];
|
|
235
|
+
if (byte === undefined) {
|
|
232
236
|
throw new Error(
|
|
233
237
|
`Pick up type not found for stop ${stopId} at trip index ${tripIndex} in route ${this.serviceRouteId}`,
|
|
234
238
|
);
|
|
235
239
|
}
|
|
240
|
+
|
|
241
|
+
const pickUpValue = isSecondPair
|
|
242
|
+
? (byte >> 6) & 0x03 // Upper 2 bits for second pair
|
|
243
|
+
: (byte >> 2) & 0x03; // Bits 2-3 for first pair
|
|
236
244
|
return toPickupDropOffType(pickUpValue);
|
|
237
245
|
}
|
|
238
246
|
|
|
@@ -244,14 +252,20 @@ export class Route {
|
|
|
244
252
|
* @returns The drop-off type at the specified stop and trip.
|
|
245
253
|
*/
|
|
246
254
|
dropOffTypeAt(stopId: StopId, tripIndex: TripIndex): PickUpDropOffType {
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
const
|
|
250
|
-
|
|
255
|
+
const globalIndex = tripIndex * this.stops.length + this.stopIndex(stopId);
|
|
256
|
+
const byteIndex = Math.floor(globalIndex / 2);
|
|
257
|
+
const isSecondPair = globalIndex % 2 === 1;
|
|
258
|
+
|
|
259
|
+
const byte = this.pickUpDropOffTypes[byteIndex];
|
|
260
|
+
if (byte === undefined) {
|
|
251
261
|
throw new Error(
|
|
252
262
|
`Drop off type not found for stop ${stopId} at trip index ${tripIndex} in route ${this.serviceRouteId}`,
|
|
253
263
|
);
|
|
254
264
|
}
|
|
265
|
+
|
|
266
|
+
const dropOffValue = isSecondPair
|
|
267
|
+
? (byte >> 4) & 0x03 // Bits 4-5 for second pair
|
|
268
|
+
: byte & 0x03; // Lower 2 bits for first pair
|
|
255
269
|
return toPickupDropOffType(dropOffValue);
|
|
256
270
|
}
|
|
257
271
|
|
|
@@ -13,8 +13,6 @@ import {
|
|
|
13
13
|
import { Timetable as ProtoTimetable } from './proto/timetable.js';
|
|
14
14
|
import { Route, RouteId } from './route.js';
|
|
15
15
|
|
|
16
|
-
export type RoutesAdjacency = Map<RouteId, Route>;
|
|
17
|
-
|
|
18
16
|
export type TransferType =
|
|
19
17
|
| 'RECOMMENDED'
|
|
20
18
|
| 'GUARANTEED'
|
|
@@ -49,10 +47,12 @@ export type RouteType =
|
|
|
49
47
|
| 'TROLLEYBUS'
|
|
50
48
|
| 'MONORAIL';
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
type ServiceRoute = {
|
|
53
51
|
type: RouteType;
|
|
54
52
|
name: string;
|
|
53
|
+
routes: RouteId[];
|
|
55
54
|
};
|
|
55
|
+
export type ServiceRouteInfo = Omit<ServiceRoute, 'routes'>;
|
|
56
56
|
|
|
57
57
|
// A service refers to a collection of trips that are displayed to riders as a single service.
|
|
58
58
|
// As opposed to a route which consists of the subset of trips from a service which shares the same list of stops.
|
|
@@ -72,19 +72,19 @@ export const ALL_TRANSPORT_MODES: Set<RouteType> = new Set([
|
|
|
72
72
|
'MONORAIL',
|
|
73
73
|
]);
|
|
74
74
|
|
|
75
|
-
export const CURRENT_VERSION = '0.0.
|
|
75
|
+
export const CURRENT_VERSION = '0.0.5';
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
78
|
* The internal transit timetable format.
|
|
79
79
|
*/
|
|
80
80
|
export class Timetable {
|
|
81
81
|
private readonly stopsAdjacency: StopsAdjacency;
|
|
82
|
-
private readonly routesAdjacency:
|
|
82
|
+
private readonly routesAdjacency: Route[];
|
|
83
83
|
private readonly routes: ServiceRoutesMap;
|
|
84
84
|
|
|
85
85
|
constructor(
|
|
86
86
|
stopsAdjacency: StopsAdjacency,
|
|
87
|
-
routesAdjacency:
|
|
87
|
+
routesAdjacency: Route[],
|
|
88
88
|
routes: ServiceRoutesMap,
|
|
89
89
|
) {
|
|
90
90
|
this.stopsAdjacency = stopsAdjacency;
|
|
@@ -126,10 +126,7 @@ export class Timetable {
|
|
|
126
126
|
return new Timetable(
|
|
127
127
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
128
128
|
deserializeStopsAdjacency(protoTimetable.stopsAdjacency!),
|
|
129
|
-
deserializeRoutesAdjacency(
|
|
130
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
131
|
-
protoTimetable.routesAdjacency!,
|
|
132
|
-
),
|
|
129
|
+
deserializeRoutesAdjacency(protoTimetable.routesAdjacency),
|
|
133
130
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
134
131
|
deserializeServiceRoutesMap(protoTimetable.routes!),
|
|
135
132
|
);
|
|
@@ -143,7 +140,7 @@ export class Timetable {
|
|
|
143
140
|
* or undefined if no such route exists.
|
|
144
141
|
*/
|
|
145
142
|
getRoute(routeId: RouteId): Route | undefined {
|
|
146
|
-
return this.routesAdjacency
|
|
143
|
+
return this.routesAdjacency[routeId];
|
|
147
144
|
}
|
|
148
145
|
|
|
149
146
|
/**
|
|
@@ -164,9 +161,16 @@ export class Timetable {
|
|
|
164
161
|
* @param route - The route for which the service route is to be retrieved.
|
|
165
162
|
* @returns The service route corresponding to the provided route.
|
|
166
163
|
*/
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
164
|
+
getServiceRouteInfo(route: Route): ServiceRouteInfo {
|
|
165
|
+
const serviceRoute = this.routes.get(route.serviceRoute());
|
|
166
|
+
if (!serviceRoute) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
`Service route not found for route ID: ${route.serviceRoute()}`,
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
172
|
+
const { routes, ...serviceRouteInfo } = serviceRoute;
|
|
173
|
+
return serviceRouteInfo;
|
|
170
174
|
}
|
|
171
175
|
|
|
172
176
|
/**
|
|
@@ -182,7 +186,7 @@ export class Timetable {
|
|
|
182
186
|
}
|
|
183
187
|
const routes: Route[] = [];
|
|
184
188
|
for (const routeId of stopData.routes) {
|
|
185
|
-
const route = this.routesAdjacency
|
|
189
|
+
const route = this.routesAdjacency[routeId];
|
|
186
190
|
if (route) {
|
|
187
191
|
routes.push(route);
|
|
188
192
|
}
|
|
@@ -207,7 +211,7 @@ export class Timetable {
|
|
|
207
211
|
for (const originStop of fromStops) {
|
|
208
212
|
const validRoutes = this.routesPassingThrough(originStop).filter(
|
|
209
213
|
(route) => {
|
|
210
|
-
const serviceRoute = this.
|
|
214
|
+
const serviceRoute = this.getServiceRouteInfo(route);
|
|
211
215
|
return transportModes.has(serviceRoute.type);
|
|
212
216
|
},
|
|
213
217
|
);
|