diff --git a/parse/arrival-or-departure.js b/parse/arrival-or-departure.js index b71fb3a5..2b3631ea 100644 --- a/parse/arrival-or-departure.js +++ b/parse/arrival-or-departure.js @@ -9,7 +9,7 @@ const DEPARTURE = 'd' // todo: d.stbStop.dProgType/d.stbStop.aProgType const createParseArrOrDep = (profile, opt, data, prefix) => { - const {locations, hints, warnings} = data + const {hints, warnings} = data if (prefix !== ARRIVAL && prefix !== DEPARTURE) throw new Error('invalid prefix') const parseArrOrDep = (d) => { @@ -18,7 +18,7 @@ const createParseArrOrDep = (profile, opt, data, prefix) => { const res = { tripId: d.jid, - stop: locations[parseInt(d.stbStop.locX)] || null, + stop: d.stbStop.location || null, when: profile.parseDateTime(profile, d.date, t, tz), // todo: for arrivals, this is the *origin*, not the *direction* direction: prefix === DEPARTURE && d.dirTxt && profile.parseStationName(d.dirTxt) || null, diff --git a/parse/common.js b/parse/common.js index 9fc84c35..f5061ee3 100644 --- a/parse/common.js +++ b/parse/common.js @@ -56,6 +56,17 @@ const parseCommonData = (profile, opt, res) => { loc.station.type = 'station' } else if (raw.isMainMast) loc.type = 'station' } + + // todo: correct props? + resolveIdxRefs(res, '**.locX', res.locations, 'location') + findIdxRefs(res, '**.ani.fLocX', (idxs, parent) => { + parent.fromLocations = idxs.map(idx => res.locations[idx]) + }) + findIdxRefs(res, '**.ani.tLocX', (idxs, parent) => { + parent.toLocations = idxs.map(idx => res.locations[idx]) + }) + resolveIdxRefs(res, '**.fLocX', res.locations, 'fromLocation') + resolveIdxRefs(res, '**.tLocX', res.locations, 'toLocation') } res.hints = [] diff --git a/parse/journey-leg.js b/parse/journey-leg.js index 288f0c20..3e7fa076 100644 --- a/parse/journey-leg.js +++ b/parse/journey-leg.js @@ -5,16 +5,15 @@ const findRemark = require('./find-remark') const clone = obj => Object.assign({}, obj) -const locX = Symbol('locX') - const applyRemarks = (leg, hints, warnings, refs) => { for (let ref of refs) { const remark = findRemark(hints, warnings, ref) if (!remark) continue + const {fromLocation, toLocation} = ref - if ('number' === typeof ref.fLocX && 'number' === typeof ref.tLocX) { - const fromI = leg.stopovers.findIndex(s => s[locX] === ref.fLocX) - const toI = leg.stopovers.findIndex(s => s[locX] === ref.tLocX) + if (ref.fromLocation && ref.toLocation) { + const fromI = leg.stopovers.findIndex(s => s.stop === fromLocation) + const toI = leg.stopovers.findIndex(s => s.stop === toLocation) if (fromI < 0 || toI < 0) continue const wholeLeg = fromI === 0 && toI === (leg.stopovers.length - 1) @@ -40,7 +39,7 @@ const applyRemarks = (leg, hints, warnings, refs) => { } const createParseJourneyLeg = (profile, opt, data) => { - const {locations, hints, warnings, polylines} = data + const {hints, warnings, polylines} = data // todo: pt.status, pt.isPartCncl // todo: pt.isRchbl, pt.chRatingRT, pt.chgDurR, pt.minChg // todo: pt.dep.dProgType, pt.arr.dProgType @@ -56,8 +55,8 @@ const createParseJourneyLeg = (profile, opt, data) => { const dep = profile.parseDateTime(profile, j.date, pt.dep.dTimeR || pt.dep.dTimeS, pt.dep.dTZOffset) const arr = profile.parseDateTime(profile, j.date, pt.arr.aTimeR || pt.arr.aTimeS, pt.arr.aTZOffset) const res = { - origin: clone(locations[parseInt(pt.dep.locX)]) || null, - destination: clone(locations[parseInt(pt.arr.locX)]), + origin: clone(pt.dep.location) || null, + destination: clone(pt.arr.location), departure: dep, arrival: arr } @@ -119,12 +118,6 @@ const createParseJourneyLeg = (profile, opt, data) => { res.stopovers = stopL.map(parse) if (opt.remarks && Array.isArray(pt.jny.msgL)) { - for (let i = 0; i < stopL.length; i++) { - Object.defineProperty(res.stopovers[i], locX, { - value: stopL[i].locX - }) - } - // todo: parse `pt.dep.msgL` & `pt.arr.msgL` // todo: apply leg-wide remarks if `parseStopovers` is false applyRemarks(res, hints, warnings, pt.jny.msgL) } diff --git a/parse/movement.js b/parse/movement.js index 975af21a..0b68efd7 100644 --- a/parse/movement.js +++ b/parse/movement.js @@ -1,7 +1,7 @@ 'use strict' const createParseMovement = (profile, opt, data) => { - const {locations, polylines} = data + const {polylines} = data // todo: what is m.dirGeo? maybe the speed? // todo: what is m.stopL? @@ -30,8 +30,8 @@ const createParseMovement = (profile, opt, data) => { if (Array.isArray(m.ani.mSec)) { for (let i = 0; i < m.ani.mSec.length; i++) { res.frames.push({ - origin: locations[m.ani.fLocX[i]] || null, - destination: locations[m.ani.tLocX[i]] || null, + origin: m.ani.fromLocations[i] || null, + destination: m.ani.toLocations[i] || null, t: m.ani.mSec[i] }) } diff --git a/parse/polyline.js b/parse/polyline.js index c2d5e15e..367dac9e 100644 --- a/parse/polyline.js +++ b/parse/polyline.js @@ -3,7 +3,7 @@ const {toGeoJSON} = require('@mapbox/polyline') const distance = require('gps-distance') -const createParsePolyline = (profile, opt, {locations}) => { +const createParsePolyline = (profile, opt, _) => { // todo: what is p.delta? // todo: what is p.type? // todo: what is p.crdEncS? @@ -24,8 +24,7 @@ const createParsePolyline = (profile, opt, {locations}) => { if (Array.isArray(p.ppLocRefL)) { for (let ref of p.ppLocRefL) { const p = res[ref.ppIdx] - const loc = locations[ref.locX] - if (p && loc) p.properties = loc + if (p && ref.location) p.properties = ref.location } // Often there is one more point right next to each point at a station. diff --git a/parse/stopover.js b/parse/stopover.js index 9887ca07..c0943c90 100644 --- a/parse/stopover.js +++ b/parse/stopover.js @@ -3,11 +3,11 @@ const findRemark = require('./find-remark') const createParseStopover = (profile, opt, data, date) => { - const {locations, lines, hints, warnings} = data + const {hints, warnings} = data const parseStopover = (st) => { const res = { - stop: locations[parseInt(st.locX)] || null, + stop: st.location || null, arrival: null, arrivalDelay: null, arrivalPlatform: st.aPlatfR || st.aPlatfS || null, diff --git a/parse/warning.js b/parse/warning.js index 7829022b..b5ef6d52 100644 --- a/parse/warning.js +++ b/parse/warning.js @@ -9,17 +9,23 @@ const typesByIcon = Object.assign(Object.create(null), { HimWarn: 'status' }) -const parseMsgEdge = (profile, data) => (e) => { - const res = omit(e, ['icoX', 'fLocX', 'tLocX']) +const parseMsgEdge = (profile) => (e) => { + const res = omit(e, [ + 'icoX', + 'fLocX', 'fromLocation', + 'tLocX', 'toLocation' + ]) res.icon = e.icon || null - res.fromLoc = 'number' === typeof e.fLocX && data.locations[e.fLocX] || null - res.toLoc = 'number' === typeof e.tLocX && data.locations[e.tLocX] || null + // todo: rename `Loc` -> `Location` [breaking] + res.fromLoc = e.fromLocation || null + res.toLoc = e.toLocation || null return res } -const parseMsgEvent = (profile, data) => (e) => { +const parseMsgEvent = (profile) => (e) => { return { - fromLoc: 'number' === typeof e.fLocX && data.locations[e.fLocX] || null, - toLoc: 'number' === typeof e.tLocX && data.locations[e.tLocX] || null, + // todo: rename `Loc` -> `Location` [breaking] + fromLoc: e.fromLocation || null, + toLoc: e.toLocation || null, start: parseDateTime(profile, e.fDate, e.fTime, null), end: parseDateTime(profile, e.tDate, e.tTime, null), sections: e.sectionNums || [] // todo: parse @@ -64,13 +70,13 @@ const parseWarning = (profile, w, data) => { res.edges = w.edgeRefL .map(i => data.himMsgEdgeL[i]) .filter(e => !!e) - .map(parseMsgEdge(profile, data)) + .map(parseMsgEdge(profile)) } if (w.eventRefL && data.himMsgEventL) { res.events = w.eventRefL .map(i => data.himMsgEventL[i]) .filter(e => !!e) - .map(parseMsgEvent(profile, data)) + .map(parseMsgEvent(profile)) } if (w.sDate && w.sTime) res.validFrom = parseDateTime(profile, w.sDate, w.sTime, null)