minotor 3.0.2 → 4.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.
@@ -1,6 +1,7 @@
1
1
  import assert from 'node:assert';
2
2
  import { describe, it } from 'node:test';
3
3
 
4
+ import { encodePickUpDropOffTypes } from '../../gtfs/trips.js';
4
5
  import {
5
6
  MUST_COORDINATE_WITH_DRIVER,
6
7
  MUST_PHONE_AGENCY,
@@ -29,23 +30,30 @@ describe('Route', () => {
29
30
  Time.fromHMS(10, 31, 0).toMinutes(),
30
31
  ]);
31
32
 
32
- const pickUpDropOffTypes = new Uint8Array([
33
- // Trip 0
34
- REGULAR,
35
- REGULAR,
36
- NOT_AVAILABLE,
37
- REGULAR,
38
- // Trip 1
39
- REGULAR,
40
- REGULAR,
41
- REGULAR,
42
- REGULAR,
43
- // Trip 2
44
- MUST_PHONE_AGENCY,
45
- REGULAR,
46
- MUST_COORDINATE_WITH_DRIVER,
47
- REGULAR,
48
- ]);
33
+ const pickUpDropOffTypes = encodePickUpDropOffTypes(
34
+ [
35
+ // Trip 0
36
+ REGULAR,
37
+ NOT_AVAILABLE,
38
+ // Trip 1
39
+ REGULAR,
40
+ REGULAR,
41
+ // Trip 2
42
+ MUST_PHONE_AGENCY,
43
+ MUST_COORDINATE_WITH_DRIVER,
44
+ ],
45
+ [
46
+ // Trip 0
47
+ REGULAR,
48
+ REGULAR,
49
+ // Trip 1
50
+ REGULAR,
51
+ REGULAR,
52
+ // Trip 2
53
+ REGULAR,
54
+ REGULAR,
55
+ ],
56
+ );
49
57
 
50
58
  const stops = new Uint32Array([1001, 1002]);
51
59
  const serviceRouteId = 'test-route-1';
@@ -1,6 +1,7 @@
1
1
  import assert from 'node:assert';
2
2
  import { describe, it } from 'node:test';
3
3
 
4
+ import { encodePickUpDropOffTypes } from '../../gtfs/trips.js';
4
5
  import { Duration } from '../duration.js';
5
6
  import { NOT_AVAILABLE, REGULAR, Route } from '../route.js';
6
7
  import { Time } from '../time.js';
@@ -42,6 +43,7 @@ describe('Timetable', () => {
42
43
  },
43
44
  ],
44
45
  ]);
46
+
45
47
  const route1 = new Route(
46
48
  new Uint16Array([
47
49
  Time.fromHMS(16, 40, 0).toMinutes(),
@@ -53,16 +55,10 @@ describe('Timetable', () => {
53
55
  Time.fromHMS(19, 0, 0).toMinutes(),
54
56
  Time.fromHMS(19, 10, 0).toMinutes(),
55
57
  ]),
56
- new Uint8Array([
57
- REGULAR,
58
- REGULAR,
59
- NOT_AVAILABLE,
60
- REGULAR,
61
- REGULAR,
62
- REGULAR,
63
- REGULAR,
64
- REGULAR,
65
- ]),
58
+ encodePickUpDropOffTypes(
59
+ [REGULAR, NOT_AVAILABLE, REGULAR, REGULAR],
60
+ [REGULAR, REGULAR, REGULAR, REGULAR],
61
+ ),
66
62
  new Uint32Array([1, 2]),
67
63
  'gtfs1',
68
64
  );
@@ -73,7 +69,7 @@ describe('Timetable', () => {
73
69
  Time.fromHMS(23, 20, 0).toMinutes(),
74
70
  Time.fromHMS(23, 30, 0).toMinutes(),
75
71
  ]),
76
- new Uint8Array([REGULAR, REGULAR, REGULAR, REGULAR]),
72
+ encodePickUpDropOffTypes([REGULAR, REGULAR], [REGULAR, REGULAR]),
77
73
  new Uint32Array([2, 1]),
78
74
  'gtfs2',
79
75
  );
@@ -15,7 +15,8 @@ message Route {
15
15
  * 1: NOT_AVAILABLE
16
16
  * 2: MUST_PHONE_AGENCY
17
17
  * 3: MUST_COORDINATE_WITH_DRIVER
18
- * Format: [pickupTypeStop1, dropOffTypeStop1, pickupTypeStop2, dropOffTypeStop2, etc.]
18
+ * Format: [drop_off_1][pickup_1][drop_off_0][pickup_0]
19
+ * 2 bits per value
19
20
  */
20
21
  bytes pickUpDropOffTypes = 2;
21
22
  /**
@@ -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: [pickupTypeStop1, dropOffTypeStop1, pickupTypeStop2, dropOffTypeStop2, etc.]
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
  /**
@@ -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 binary Uint8Array.
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
- * Format: [pickupTypeStop1, dropOffTypeStop1, pickupTypeStop2, dropOffTypeStop2, etc.]
75
- * TODO: Encode 4 values instead of 1 in 8 bits.
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 pickUpIndex =
229
- (tripIndex * this.stops.length + this.stopIndex(stopId)) * 2;
230
- const pickUpValue = this.pickUpDropOffTypes[pickUpIndex];
231
- if (pickUpValue === undefined) {
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 dropOffIndex =
248
- (tripIndex * this.stops.length + this.stopIndex(stopId)) * 2 + 1;
249
- const dropOffValue = this.pickUpDropOffTypes[dropOffIndex];
250
- if (dropOffValue === undefined) {
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
 
@@ -72,7 +72,7 @@ export const ALL_TRANSPORT_MODES: Set<RouteType> = new Set([
72
72
  'MONORAIL',
73
73
  ]);
74
74
 
75
- export const CURRENT_VERSION = '0.0.3';
75
+ export const CURRENT_VERSION = '0.0.4';
76
76
 
77
77
  /**
78
78
  * The internal transit timetable format.