-
Notifications
You must be signed in to change notification settings - Fork 3
/
compute-schedules.js
89 lines (76 loc) · 2.18 KB
/
compute-schedules.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
'use strict'
const shorthash = require('shorthash').unique
const inMemoryStore = require('./lib/in-memory-store')
const readStopTimes = require('./lib/read-stop-times')
const computeSchedules = async (readFile, filters = {}, opt = {}) => {
if ('function' !== typeof readFile) {
throw new Error('readFile must be a function.')
}
filters = {
trip: () => true,
stopTime: () => true,
frequenciesRow: () => true,
...filters,
}
if ('function' !== typeof filters.trip) {
throw new Error('filters.trip must be a function.')
}
if ('function' !== typeof filters.stopTime) {
throw new Error('filters.stopTime must be a function.')
}
if ('function' !== typeof filters.frequenciesRow) {
throw new Error('filters.frequenciesRow must be a function.')
}
const {
createStore,
computeSig,
} = {
createStore: inMemoryStore,
computeSig: data => shorthash(JSON.stringify(data)),
...opt,
}
const schedules = createStore() // by signature
for await (const _ of readStopTimes(readFile, filters)) {
const {
tripId,
stops, arrivals: absArrs, departures: absDeps,
headwayBasedStarts: hwStarts,
headwayBasedEnds: hwEnds,
headwayBasedHeadways: hwHeadways,
} = _
// make arrivals and departures relative to the first arrival,
// deduplicate/merge all schedules by signature
const t0 = absArrs[0]
const arrs = new Array(absArrs.length)
const deps = new Array(absDeps.length)
for (let i = 0; i < absArrs.length; i++) {
arrs[i] = absArrs[i] === null ? absArrs[i] : absArrs[i] - t0
deps[i] = absDeps[i] === null ? absDeps[i] : absDeps[i] - t0
}
const signature = computeSig([
stops, arrs, deps,
hwStarts || [],
hwEnds || [],
hwHeadways || [],
])
await schedules.map(signature, (schedule) => {
if (!schedule) { // make a new entry
return {
id: signature,
trips: [{tripId, start: t0}],
stops,
arrivals: arrs,
departures: deps,
headwayBasedStarts: hwStarts || [],
headwayBasedEnds: hwEnds || [],
headwayBasedHeadways: hwHeadways || [],
}
}
// merge into existing schedule
schedule.trips.push({tripId, start: t0})
return schedule
})
}
return schedules
}
module.exports = computeSchedules