-
Notifications
You must be signed in to change notification settings - Fork 3
/
read-stops.js
116 lines (99 loc) · 2.29 KB
/
read-stops.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
'use strict'
const inMemoryStore = require('./lib/in-memory-store')
const {
STOP,
STATION,
ENTRANCE_EXIT,
BOARDING_AREA,
} = require('./lib/location-types')
const noFilter = () => true
const readStops = async (readFile, filters = {}, opt = {}) => {
if (typeof readFile !== 'function') {
throw new TypeError('readFile must be a function')
}
const {
stop: stopFilter,
} = {
stop: () => true,
...filters,
}
if (typeof stopFilter !== 'function') {
throw new TypeError('filters.stop must be a function')
}
const {
createStore,
} = {
createStore: inMemoryStore,
...opt,
}
const stops = createStore() // by stop_id
let firstCollect = true
let curParentStation = NaN
let curLocType = NaN
let childIds = []
for await (let s of await readFile('stops')) {
if (!stopFilter(s)) continue
const locType = s.location_type === '' || s.location_type === undefined
? STOP : s.location_type
// just insert stations & plain/orphan stops
if (locType === STATION) {
await stops.set(s.stop_id, {
...s,
stops: [],
entrances: [],
boardingAreas: [],
})
continue
}
if (locType === STOP && !s.parent_station) {
await stops.set(s.stop_id, s)
continue
}
if (!s.parent_station) continue
if (
locType !== STOP
&& locType !== ENTRANCE_EXIT
&& locType !== BOARDING_AREA
) continue
// collect all items of one kind for one station
if (s.parent_station !== curParentStation || locType !== curLocType) {
if (firstCollect) firstCollect = false
else {
await stops.map(curParentStation, (station) => {
if (!station) {
// todo: debug-log?
return;
}
const key = ({
[STOP]: 'stops',
[ENTRANCE_EXIT]: 'entrances',
[BOARDING_AREA]: 'boardingAreas',
})[curLocType]
station[key] = childIds
return station
})
}
curParentStation = s.parent_station
curLocType = locType
childIds = [s.stop_id]
} else {
childIds.push(s.stop_id)
}
}
// store pending child IDs
await stops.map(curParentStation, (station) => {
if (!station) {
// todo: debug-log?
return;
}
const key = ({
[STOP]: 'stops',
[ENTRANCE_EXIT]: 'entrances',
[BOARDING_AREA]: 'boardingAreas',
})[curLocType]
station[key] = childIds
return station
})
return stops
}
module.exports = readStops