mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-02-23 07:09:35 +02:00
split parse.js
This commit is contained in:
parent
fd0dec26a5
commit
79db55d99c
14 changed files with 337 additions and 235 deletions
23
index.js
23
index.js
|
@ -4,7 +4,10 @@ const Promise = require('pinkie-promise')
|
||||||
const {fetch} = require('fetch-ponyfill')({Promise})
|
const {fetch} = require('fetch-ponyfill')({Promise})
|
||||||
const {stringify} = require('query-string')
|
const {stringify} = require('query-string')
|
||||||
|
|
||||||
const parse = require('./parse')
|
const parseLocation = require('./parse/location')
|
||||||
|
const parseLine = require('./parse/line')
|
||||||
|
const parseRemark = require('./parse/remark')
|
||||||
|
const parseOperator = require('./parse/operator')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,14 +15,12 @@ const id = (x) => x
|
||||||
const defaults = {
|
const defaults = {
|
||||||
onBody: id,
|
onBody: id,
|
||||||
onReq: id,
|
onReq: id,
|
||||||
onLocation: parse.location,
|
parseLocation: parseLocation,
|
||||||
onLine: parse.line,
|
parseLine: parseLine,
|
||||||
onRemark: parse.remark,
|
parseRemark: parseRemark,
|
||||||
onOperator: parse.operator
|
parseOperator: parseOperator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const hafasError = (err) => {
|
const hafasError = (err) => {
|
||||||
err.isHafasError = true
|
err.isHafasError = true
|
||||||
return err
|
return err
|
||||||
|
@ -60,10 +61,10 @@ const createRequest = (opt) => {
|
||||||
const d = b.svcResL[0].res
|
const d = b.svcResL[0].res
|
||||||
const c = d.common || {}
|
const c = d.common || {}
|
||||||
|
|
||||||
if (Array.isArray(c.locL)) d.locations = c.locL.map(opt.onLocation)
|
if (Array.isArray(c.locL)) d.locations = c.locL.map(opt.parseLocation)
|
||||||
if (Array.isArray(c.prodL)) d.lines = c.prodL.map(opt.onLine)
|
if (Array.isArray(c.prodL)) d.lines = c.prodL.map(opt.parseLine)
|
||||||
if (Array.isArray(c.remL)) d.remarks = c.remL.map(opt.onRemark)
|
if (Array.isArray(c.remL)) d.remarks = c.remL.map(opt.parseRemark)
|
||||||
if (Array.isArray(c.opL)) d.operators = c.opL.map(opt.onOperator)
|
if (Array.isArray(c.opL)) d.operators = c.opL.map(opt.parseOperator)
|
||||||
return d
|
return d
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"files": [
|
"files": [
|
||||||
"index.js",
|
"index.js",
|
||||||
"parse.js",
|
"parse",
|
||||||
"stringify.js"
|
"stringify.js"
|
||||||
],
|
],
|
||||||
"author": "Jannis R <mail@jannisr.de>",
|
"author": "Jannis R <mail@jannisr.de>",
|
||||||
|
|
223
parse.js
223
parse.js
|
@ -1,223 +0,0 @@
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const moment = require('moment-timezone')
|
|
||||||
const slugg = require('slugg')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const dateTime = (tz, date, time) => {
|
|
||||||
let offset = 0 // in days
|
|
||||||
if (time.length > 6) {
|
|
||||||
offset = +time.slice(0, -6)
|
|
||||||
time = time.slice(-6)
|
|
||||||
}
|
|
||||||
return moment.tz(date + 'T' + time, tz)
|
|
||||||
.add(offset, 'days')
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const types = {P: 'poi', S: 'station', A: 'address'}
|
|
||||||
// todo: what is s.rRefL?
|
|
||||||
const location = (l) => {
|
|
||||||
const type = types[l.type] || 'unknown'
|
|
||||||
const result = {
|
|
||||||
type,
|
|
||||||
name: l.name,
|
|
||||||
coordinates: l.crd ? {
|
|
||||||
latitude: l.crd.y / 1000000,
|
|
||||||
longitude: l.crd.x / 1000000
|
|
||||||
} : null
|
|
||||||
}
|
|
||||||
if (type === 'poi' || type === 'station') result.id = l.extId
|
|
||||||
if ('pCls' in l) result.products = l.pCls
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// todo: what is p.number vs p.line?
|
|
||||||
// todo: what is p.icoX?
|
|
||||||
// todo: what is p.oprX?
|
|
||||||
const line = (p) => {
|
|
||||||
if (!p) return null
|
|
||||||
const result = {type: 'line', name: p.line || p.name}
|
|
||||||
if (p.cls) result.class = p.cls
|
|
||||||
if (p.prodCtx) {
|
|
||||||
result.productCode = +p.prodCtx.catCode
|
|
||||||
result.productName = p.prodCtx.catOutS
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const remark = (r) => null // todo
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const operator = (a) => ({
|
|
||||||
type: 'operator',
|
|
||||||
id: slugg(a.name),
|
|
||||||
name: a.name
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// s = stations, ln = lines, r = remarks, c = connection
|
|
||||||
const stopover = (tz, s, ln, r, c) => (st) => {
|
|
||||||
const result = {station: s[parseInt(st.locX)]}
|
|
||||||
if (st.aTimeR || st.aTimeS) {
|
|
||||||
result.arrival = dateTime(tz, c.date, st.aTimeR || st.aTimeS).format()
|
|
||||||
}
|
|
||||||
if (st.dTimeR || st.dTimeS) {
|
|
||||||
result.departure = dateTime(tz, c.date, st.dTimeR || st.dTimeS).format()
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: finish parseRemark first
|
|
||||||
// s = stations, ln = lines, r = remarks, c = connection
|
|
||||||
const applyRemark = (s, ln, r, c) => (rm) => null
|
|
||||||
|
|
||||||
// todo: pt.sDays
|
|
||||||
// todo: pt.dep.dProgType, pt.arr.dProgType
|
|
||||||
// todo: what is pt.jny.dirFlg?
|
|
||||||
// todo: how does pt.freq work?
|
|
||||||
// tz = timezone, s = stations, ln = lines, r = remarks, c = connection
|
|
||||||
const part = (tz, s, ln, r, c) => (pt) => {
|
|
||||||
const result = {
|
|
||||||
origin: Object.assign({}, s[parseInt(pt.dep.locX)])
|
|
||||||
, destination: Object.assign({}, s[parseInt(pt.arr.locX)])
|
|
||||||
, departure: dateTime(tz, c.date, pt.dep.dTimeR || pt.dep.dTimeS).format()
|
|
||||||
, arrival: dateTime(tz, c.date, pt.arr.aTimeR || pt.arr.aTimeS).format()
|
|
||||||
}
|
|
||||||
if (pt.dep.dTimeR && pt.dep.dTimeS) {
|
|
||||||
const realtime = dateTime(tz, c.date, pt.dep.dTimeR)
|
|
||||||
const planned = dateTime(tz, c.date, pt.dep.dTimeS)
|
|
||||||
result.delay = Math.round((realtime - planned) / 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pt.type === 'WALK') result.mode = 'walking'
|
|
||||||
else if (pt.type === 'JNY') {
|
|
||||||
result.id = pt.jny.jid
|
|
||||||
result.line = ln[parseInt(pt.jny.prodX)]
|
|
||||||
result.direction = pt.jny.dirTxt // todo: parse this
|
|
||||||
|
|
||||||
if (pt.dep.dPlatfS) result.departurePlatform = pt.dep.dPlatfS
|
|
||||||
if (pt.arr.aPlatfS) result.arrivalPlatform = pt.arr.aPlatfS
|
|
||||||
|
|
||||||
if (pt.jny.stopL) result.passed = pt.jny.stopL.map(stopover(tz, s, ln, r, c))
|
|
||||||
if (Array.isArray(pt.jny.remL))
|
|
||||||
pt.jny.remL.forEach(applyRemark(s, ln, r, c))
|
|
||||||
|
|
||||||
if (pt.jny.freq && pt.jny.freq.jnyL)
|
|
||||||
result.alternatives = pt.jny.freq.jnyL
|
|
||||||
.filter((a) => a.stopL[0].locX === pt.dep.locX)
|
|
||||||
.map((a) => ({
|
|
||||||
line: ln[parseInt(a.prodX)],
|
|
||||||
when: dateTime(tz, c.date, a.stopL[0].dTimeS).format()
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: c.sDays
|
|
||||||
// todo: c.dep.dProgType, c.arr.dProgType
|
|
||||||
// todo: c.conSubscr
|
|
||||||
// todo: c.trfRes x vbb-parse-ticket
|
|
||||||
// todo: use computed information from part
|
|
||||||
// s = stations, ln = lines, r = remarks, p = parsePart
|
|
||||||
const journey = (tz, s, ln, r, p = part) => (c) => {
|
|
||||||
const parts = c.secL.map(p(tz, s, ln, r, c))
|
|
||||||
return {
|
|
||||||
parts
|
|
||||||
, origin: parts[0].origin
|
|
||||||
, destination: parts[parts.length - 1].destination
|
|
||||||
, departure: parts[0].departure
|
|
||||||
, arrival: parts[parts.length - 1].arrival
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// todos from derhuerst/hafas-client#2
|
|
||||||
// - stdStop.dCncl
|
|
||||||
// - stdStop.dPlatfS, stdStop.dPlatfR
|
|
||||||
// todo: what is d.jny.dirFlg?
|
|
||||||
// todo: d.stbStop.dProgType
|
|
||||||
// tz = timezone, s = stations, ln = lines, r = remarks
|
|
||||||
const departure = (tz, s, ln, r) => (d) => {
|
|
||||||
const result = {
|
|
||||||
ref: d.jid
|
|
||||||
, station: s[parseInt(d.stbStop.locX)]
|
|
||||||
, when: dateTime(tz, d.date, d.stbStop.dTimeR || d.stbStop.dTimeS).format()
|
|
||||||
, direction: d.dirTxt
|
|
||||||
, line: ln[parseInt(d.prodX)]
|
|
||||||
, remarks: d.remL ? d.remL.map((rm) => r[parseInt(rm.remX)]) : null
|
|
||||||
, trip: +d.jid.split('|')[1]
|
|
||||||
}
|
|
||||||
if (d.stbStop.dTimeR && d.stbStop.dTimeS) {
|
|
||||||
const realtime = dateTime(tz, d.date, d.stbStop.dTimeR)
|
|
||||||
const planned = dateTime(tz, d.date, d.stbStop.dTimeS)
|
|
||||||
result.delay = Math.round((realtime - planned) / 1000)
|
|
||||||
} else result.delay = null
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: remarks
|
|
||||||
// todo: lines
|
|
||||||
// todo: what is s.pCls?
|
|
||||||
// todo: what is s.wt?
|
|
||||||
// todo: what is s.dur?
|
|
||||||
const nearby = (n) => {
|
|
||||||
const result = location(n)
|
|
||||||
result.distance = n.dist
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: what is m.dirGeo? maybe the speed?
|
|
||||||
// todo: what is m.stopL?
|
|
||||||
// todo: what is m.proc? wut?
|
|
||||||
// todo: what is m.pos?
|
|
||||||
// todo: what is m.ani.dirGeo[n]? maybe the speed?
|
|
||||||
// todo: what is m.ani.proc[n]? wut?
|
|
||||||
// todo: how does m.ani.poly work?
|
|
||||||
// tz = timezone, l = locations, ln = lines, r = remarks
|
|
||||||
const movement = (tz, l, ln, r) => (m) => {
|
|
||||||
const result = {
|
|
||||||
direction: m.dirTxt
|
|
||||||
, line: ln[m.prodX]
|
|
||||||
, coordinates: m.pos ? {
|
|
||||||
latitude: m.pos.y / 1000000,
|
|
||||||
longitude: m.pos.x / 1000000
|
|
||||||
} : null
|
|
||||||
, nextStops: m.stopL.map((s) => ({
|
|
||||||
station: l[s.locX]
|
|
||||||
, departure: s.dTimeR || s.dTimeS
|
|
||||||
? dateTime(tz, m.date, s.dTimeR || s.dTimeS).format()
|
|
||||||
: null
|
|
||||||
, arrival: s.aTimeR || s.aTimeS
|
|
||||||
? dateTime(tz, m.date, s.aTimeR || s.aTimeS).format()
|
|
||||||
: null
|
|
||||||
}))
|
|
||||||
, frames: []
|
|
||||||
}
|
|
||||||
if (m.ani && Array.isArray(m.ani.mSec))
|
|
||||||
for (let i = 0; i < m.ani.mSec.length; i++)
|
|
||||||
result.frames.push({
|
|
||||||
origin: l[m.ani.fLocX[i]],
|
|
||||||
destination: l[m.ani.tLocX[i]],
|
|
||||||
t: m.ani.mSec[i]
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
dateTime,
|
|
||||||
location, line, remark, operator,
|
|
||||||
stopover, applyRemark, part, journey,
|
|
||||||
departure,
|
|
||||||
nearby,
|
|
||||||
movement
|
|
||||||
}
|
|
16
parse/date-time.js
Normal file
16
parse/date-time.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const moment = require('moment-timezone')
|
||||||
|
|
||||||
|
const parseDateTime = (tz, date, time) => {
|
||||||
|
let offset = 0 // in days
|
||||||
|
if (time.length > 6) {
|
||||||
|
offset = +time.slice(0, -6)
|
||||||
|
time = time.slice(-6)
|
||||||
|
}
|
||||||
|
|
||||||
|
return moment.tz(date + 'T' + time, tz)
|
||||||
|
.add(offset, 'days')
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = parseDateTime
|
37
parse/departure.js
Normal file
37
parse/departure.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const parseDateTime = require('./date-time')
|
||||||
|
|
||||||
|
// todos from derhuerst/hafas-client#2
|
||||||
|
// - stdStop.dCncl
|
||||||
|
// - stdStop.dPlatfS, stdStop.dPlatfR
|
||||||
|
// todo: what is d.jny.dirFlg?
|
||||||
|
// todo: d.stbStop.dProgType
|
||||||
|
|
||||||
|
// tz = timezone, s = stations, ln = lines, r = remarks
|
||||||
|
const createParseDeparture = (tz, s, ln, r) => {
|
||||||
|
const parseDeparture = (d) => {
|
||||||
|
const when = parseDateTime(tz, d.date, d.stbStop.dTimeR || d.stbStop.dTimeS)
|
||||||
|
const result = {
|
||||||
|
ref: d.jid
|
||||||
|
, station: s[parseInt(d.stbStop.locX)]
|
||||||
|
, when: when.format()
|
||||||
|
, direction: d.dirTxt
|
||||||
|
, line: ln[parseInt(d.prodX)]
|
||||||
|
, remarks: d.remL ? d.remL.map((rm) => r[parseInt(rm.remX)]) : null
|
||||||
|
, trip: +d.jid.split('|')[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d.stbStop.dTimeR && d.stbStop.dTimeS) {
|
||||||
|
const realtime = parseDateTime(tz, d.date, d.stbStop.dTimeR)
|
||||||
|
const planned = parseDateTime(tz, d.date, d.stbStop.dTimeS)
|
||||||
|
result.delay = Math.round((realtime - planned) / 1000)
|
||||||
|
} else result.delay = null
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseDeparture
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = createParseDeparture
|
13
parse/index.js
Normal file
13
parse/index.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
dateTime: require('./date-time'),
|
||||||
|
location: require('./location'),
|
||||||
|
line: require('./line'),
|
||||||
|
remark: require('./remark'),
|
||||||
|
operator: require('./operator'),
|
||||||
|
stopover: require('./stopover'),
|
||||||
|
journey: require('./journey'),
|
||||||
|
nearby: require('./nearby'),
|
||||||
|
movement: require('./movement')
|
||||||
|
}
|
108
parse/journey.js
Normal file
108
parse/journey.js
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const parseDateTime = require('./date-time')
|
||||||
|
|
||||||
|
// s = stations, ln = lines, r = remarks, c = connection
|
||||||
|
const createParseStopover = (tz, s, ln, r, c) => {
|
||||||
|
const parseStopover = (st) => {
|
||||||
|
const res = {
|
||||||
|
station: s[parseInt(st.locX)]
|
||||||
|
}
|
||||||
|
if (st.aTimeR || st.aTimeS) {
|
||||||
|
const arr = parseDateTime(tz, c.date, st.aTimeR || st.aTimeS)
|
||||||
|
res.arrival = arr.format()
|
||||||
|
}
|
||||||
|
if (st.dTimeR || st.dTimeS) {
|
||||||
|
const dep = parseDateTime(tz, c.date, st.dTimeR || st.dTimeS)
|
||||||
|
res.departure = dep.format()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseStopover
|
||||||
|
}
|
||||||
|
|
||||||
|
// s = stations, ln = lines, r = remarks, c = connection
|
||||||
|
const createApplyRemark = (s, ln, r, c) => {
|
||||||
|
// todo: finish parse/remark.js first
|
||||||
|
const applyRemark = (rm) => {}
|
||||||
|
return applyRemark
|
||||||
|
}
|
||||||
|
|
||||||
|
// tz = timezone, s = stations, ln = lines, r = remarks, c = connection
|
||||||
|
const createParsePart = (tz, s, ln, r, c) => {
|
||||||
|
// todo: pt.sDays
|
||||||
|
// todo: pt.dep.dProgType, pt.arr.dProgType
|
||||||
|
// todo: what is pt.jny.dirFlg?
|
||||||
|
// todo: how does pt.freq work?
|
||||||
|
const parsePart = (pt) => {
|
||||||
|
const dep = parseDateTime(tz, c.date, pt.dep.dTimeR || pt.dep.dTimeS)
|
||||||
|
const arr = parseDateTime(tz, c.date, pt.arr.aTimeR || pt.arr.aTimeS)
|
||||||
|
const res = {
|
||||||
|
origin: Object.assign({}, s[parseInt(pt.dep.locX)]) // todo: what about null?
|
||||||
|
, destination: Object.assign({}, s[parseInt(pt.arr.locX)]) // todo: what about null?
|
||||||
|
, departure: dep.format()
|
||||||
|
, arrival: dep.format()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pt.dep.dTimeR && pt.dep.dTimeS) {
|
||||||
|
const realtime = parseDateTime(tz, c.date, pt.dep.dTimeR)
|
||||||
|
const planned = parseDateTime(tz, c.date, pt.dep.dTimeS)
|
||||||
|
res.delay = Math.round((realtime - planned) / 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pt.type === 'WALK') {
|
||||||
|
res.mode = 'walking'
|
||||||
|
} else if (pt.type === 'JNY') {
|
||||||
|
res.id = pt.jny.jid
|
||||||
|
res.line = ln[parseInt(pt.jny.prodX)] // todo: default null
|
||||||
|
res.direction = pt.jny.dirTxt // todo: parse this
|
||||||
|
|
||||||
|
if (pt.dep.dPlatfS) res.departurePlatform = pt.dep.dPlatfS
|
||||||
|
if (pt.arr.aPlatfS) res.arrivalPlatform = pt.arr.aPlatfS
|
||||||
|
|
||||||
|
if (pt.jny.stopL) {
|
||||||
|
res.passed = pt.jny.stopL.map(createParseStopover(tz, s, ln, r, c))
|
||||||
|
}
|
||||||
|
if (Array.isArray(pt.jny.remL)) {
|
||||||
|
pt.jny.remL.forEach(createApplyRemark(s, ln, r, c))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pt.jny.freq && pt.jny.freq.jnyL) {
|
||||||
|
const parseAlternative = (a) => ({
|
||||||
|
line: ln[parseInt(a.prodX)], // todo: default null
|
||||||
|
when: parseDateTime(tz, c.date, a.stopL[0].dTimeS).format() // todo: realtime
|
||||||
|
})
|
||||||
|
res.alternatives = pt.jny.freq.jnyL
|
||||||
|
.filter((a) => a.stopL[0].locX === pt.dep.locX)
|
||||||
|
.map(parseAlternative)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
return parsePart
|
||||||
|
}
|
||||||
|
|
||||||
|
// s = stations, ln = lines, r = remarks, p = createParsePart
|
||||||
|
const createParseJourney = (tz, s, ln, r, p = createParsePart) => {
|
||||||
|
// todo: c.sDays
|
||||||
|
// todo: c.dep.dProgType, c.arr.dProgType
|
||||||
|
// todo: c.conSubscr
|
||||||
|
// todo: c.trfRes x vbb-parse-ticket
|
||||||
|
// todo: use computed information from part
|
||||||
|
const parseJourney = (c) => {
|
||||||
|
const parts = c.secL.map(p(tz, s, ln, r, c))
|
||||||
|
return {
|
||||||
|
parts
|
||||||
|
, origin: parts[0].origin
|
||||||
|
, destination: parts[parts.length - 1].destination
|
||||||
|
, departure: parts[0].departure
|
||||||
|
, arrival: parts[parts.length - 1].arrival
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseJourney
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = createParseJourney
|
18
parse/line.js
Normal file
18
parse/line.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
// todo: what is p.number vs p.line?
|
||||||
|
// todo: what is p.icoX?
|
||||||
|
// todo: what is p.oprX?
|
||||||
|
const parseLine = (p) => {
|
||||||
|
if (!p) return null
|
||||||
|
|
||||||
|
const result = {type: 'line', name: p.line || p.name}
|
||||||
|
if (p.cls) result.class = p.cls
|
||||||
|
if (p.prodCtx) {
|
||||||
|
result.productCode = +p.prodCtx.catCode
|
||||||
|
result.productName = p.prodCtx.catOutS
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = parseLine
|
24
parse/location.js
Normal file
24
parse/location.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const types = Object.create(null)
|
||||||
|
types.P = 'poi'
|
||||||
|
types.S = 'station'
|
||||||
|
types.A = 'address'
|
||||||
|
|
||||||
|
// todo: what is s.rRefL?
|
||||||
|
const parseLocation = (l) => {
|
||||||
|
const type = types[l.type] || 'unknown'
|
||||||
|
const result = {
|
||||||
|
type,
|
||||||
|
name: l.name,
|
||||||
|
coordinates: l.crd ? {
|
||||||
|
latitude: l.crd.y / 1000000,
|
||||||
|
longitude: l.crd.x / 1000000
|
||||||
|
} : null
|
||||||
|
}
|
||||||
|
if (type === 'poi' || type === 'station') result.id = l.extId
|
||||||
|
if ('pCls' in l) result.products = l.pCls
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = parseLocation
|
49
parse/movement.js
Normal file
49
parse/movement.js
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const parseDateTime = require('./date-time')
|
||||||
|
|
||||||
|
// tz = timezone, l = locations, ln = lines, r = remarks
|
||||||
|
const createParseMovement = (tz, l, ln, r) => {
|
||||||
|
// todo: what is m.dirGeo? maybe the speed?
|
||||||
|
// todo: what is m.stopL?
|
||||||
|
// todo: what is m.proc? wut?
|
||||||
|
// todo: what is m.pos?
|
||||||
|
// todo: what is m.ani.dirGeo[n]? maybe the speed?
|
||||||
|
// todo: what is m.ani.proc[n]? wut?
|
||||||
|
// todo: how does m.ani.poly work?
|
||||||
|
const parseMovement = (m) => {
|
||||||
|
const res = {
|
||||||
|
direction: m.dirTxt
|
||||||
|
, line: ln[m.prodX]
|
||||||
|
, coordinates: m.pos ? {
|
||||||
|
latitude: m.pos.y / 1000000,
|
||||||
|
longitude: m.pos.x / 1000000
|
||||||
|
} : null
|
||||||
|
, nextStops: m.stopL.map((s) => ({
|
||||||
|
station: l[s.locX]
|
||||||
|
, departure: s.dTimeR || s.dTimeS
|
||||||
|
? parseDateTime(tz, m.date, s.dTimeR || s.dTimeS).format()
|
||||||
|
: null
|
||||||
|
, arrival: s.aTimeR || s.aTimeS
|
||||||
|
? parseDateTime(tz, m.date, s.aTimeR || s.aTimeS).format()
|
||||||
|
: null
|
||||||
|
}))
|
||||||
|
, frames: []
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.ani && Array.isArray(m.ani.mSec)) {
|
||||||
|
for (let i = 0; i < m.ani.mSec.length; i++) {
|
||||||
|
res.frames.push({
|
||||||
|
origin: l[m.ani.fLocX[i]],
|
||||||
|
destination: l[m.ani.tLocX[i]],
|
||||||
|
t: m.ani.mSec[i]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
return parseMovement
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = createParseMovement
|
16
parse/nearby.js
Normal file
16
parse/nearby.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const parseLocation = require('./location')
|
||||||
|
|
||||||
|
// todo: remarks
|
||||||
|
// todo: lines
|
||||||
|
// todo: what is s.pCls?
|
||||||
|
// todo: what is s.wt?
|
||||||
|
// todo: what is s.dur?
|
||||||
|
const parseNearby = (n) => {
|
||||||
|
const result = location(n)
|
||||||
|
result.distance = n.dist
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = parseNearby
|
13
parse/operator.js
Normal file
13
parse/operator.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const slugg = require('slugg')
|
||||||
|
|
||||||
|
const parseOperator = (a) => {
|
||||||
|
return {
|
||||||
|
type: 'operator',
|
||||||
|
id: slugg(a.name), // todo: find a more reliable way
|
||||||
|
name: a.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = parseOperator
|
7
parse/remark.js
Normal file
7
parse/remark.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const parseRemark = (r) => {
|
||||||
|
return null // todo
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = parseRemark
|
23
parse/stopover.js
Normal file
23
parse/stopover.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
// s = stations, ln = lines, r = remarks, c = connection
|
||||||
|
const createParseStopover = (tz, s, ln, r, c) => {
|
||||||
|
const parseStopover = (st) => {
|
||||||
|
const res = {
|
||||||
|
station: s[parseInt(st.locX)]
|
||||||
|
}
|
||||||
|
if (st.aTimeR || st.aTimeS) {
|
||||||
|
const arr = parseDateTime(tz, c.date, st.aTimeR || st.aTimeS)
|
||||||
|
res.arrival = arr.format()
|
||||||
|
}
|
||||||
|
if (st.dTimeR || st.dTimeS) {
|
||||||
|
const dep = parseDateTime(tz, c.date, st.dTimeR || st.dTimeS)
|
||||||
|
res.departure = dep.format()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseStopover
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = createParseStopover
|
Loading…
Add table
Reference in a new issue