-
Notifications
You must be signed in to change notification settings - Fork 0
/
find-stop.js
100 lines (87 loc) · 2.41 KB
/
find-stop.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
'use strict'
const _distance = require('@turf/distance').default
const {point} = require('@turf/helpers')
const debug = require('debug')('find-hafas-data-in-another-hafas:find-stop')
const createMatchStopOrStation = require('./match-stop-or-station')
const distance = (lA, lB) => {
return _distance(
point([lA.longitude, lA.latitude]),
point([lB.longitude, lB.latitude]),
{units: 'kilometers'}
)
}
const createFindStop = (A, B) => {
const {
endpointName: endpNameA,
normalizeStopName: normalizeStopNameA,
} = A
const {
endpointName: endpNameB,
client: clientB,
normalizeStopName: normalizeStopNameB,
} = B
const matchStopOrStation = createMatchStopOrStation(A, B)
const findStopByName = async (stopA) => {
debug('findStopByName', stopA.id, stopA.name)
const nearby = await clientB.nearby(stopA.location, {
poi: false,
results: 10,
subStops: false, entrances: false, linesOfStops: false,
})
debug('clientB.nearby()', stopA.location, nearby.map(loc => [loc.id, loc.name]))
const matchA = matchStopOrStation(stopA)
return nearby.find(matchA) || null
// todo
// const fuzzy = await clientB.locations(stopA.name, {
// addresses: false, poi: false
// })
}
const findStopById = async (stopA) => {
debug('findStopById', stopA.id, stopA.ids || {}, stopA.name)
const idsA = stopA.ids || {}
const idA = (
idsA[endpNameB] ||
idsA[endpNameB.toLowerCase()] ||
idsA[endpNameB.toUpperCase()] ||
stopA.id
)
try {
const exact = await clientB.stop(idA)
return distance(exact.location, stopA.location) < .2 ? exact : null
} catch (err) {
if (err && err.isHafasError) return null
throw err
}
}
const findStop = async (sA) => {
debug('findStop', sA.id, sA.name)
let sB = await findStopById(sA)
if (sB) {
debug('matched by stop ID with', endpNameB, sB.id, sB.ids || {}, sB.name)
return sB
}
if (sA.station) {
sB = await findStopById(sA.station)
if (sB) {
debug('matched by station ID with', endpNameB, sB.id, sB.ids || {}, sB.name)
return sB
}
}
sB = await findStopByName(sA)
if (sB) {
debug('matched by name with', endpNameB, sB.id, sB.name)
return sB
}
if (sA.station) {
sB = await findStopByName(sA.station)
if (sB) {
debug('matched by station name with', endpNameB, sB.id, sB.name)
return sB
}
}
debug('not matched :(', sA.id, sA.name)
return null
}
return findStop
}
module.exports = createFindStop