parseCommon: resolve location references

This commit is contained in:
Jannis R 2019-08-23 16:17:20 +02:00
parent 758deaf2d5
commit 62cc53ffcf
No known key found for this signature in database
GPG key ID: 0FE83946296A88A5
7 changed files with 42 additions and 33 deletions

View file

@ -9,7 +9,7 @@ const DEPARTURE = 'd'
// todo: d.stbStop.dProgType/d.stbStop.aProgType // todo: d.stbStop.dProgType/d.stbStop.aProgType
const createParseArrOrDep = (profile, opt, data, prefix) => { 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') if (prefix !== ARRIVAL && prefix !== DEPARTURE) throw new Error('invalid prefix')
const parseArrOrDep = (d) => { const parseArrOrDep = (d) => {
@ -18,7 +18,7 @@ const createParseArrOrDep = (profile, opt, data, prefix) => {
const res = { const res = {
tripId: d.jid, tripId: d.jid,
stop: locations[parseInt(d.stbStop.locX)] || null, stop: d.stbStop.location || null,
when: profile.parseDateTime(profile, d.date, t, tz), when: profile.parseDateTime(profile, d.date, t, tz),
// todo: for arrivals, this is the *origin*, not the *direction* // todo: for arrivals, this is the *origin*, not the *direction*
direction: prefix === DEPARTURE && d.dirTxt && profile.parseStationName(d.dirTxt) || null, direction: prefix === DEPARTURE && d.dirTxt && profile.parseStationName(d.dirTxt) || null,

View file

@ -56,6 +56,17 @@ const parseCommonData = (profile, opt, res) => {
loc.station.type = 'station' loc.station.type = 'station'
} else if (raw.isMainMast) loc.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 = [] res.hints = []

View file

@ -5,16 +5,15 @@ const findRemark = require('./find-remark')
const clone = obj => Object.assign({}, obj) const clone = obj => Object.assign({}, obj)
const locX = Symbol('locX')
const applyRemarks = (leg, hints, warnings, refs) => { const applyRemarks = (leg, hints, warnings, refs) => {
for (let ref of refs) { for (let ref of refs) {
const remark = findRemark(hints, warnings, ref) const remark = findRemark(hints, warnings, ref)
if (!remark) continue if (!remark) continue
const {fromLocation, toLocation} = ref
if ('number' === typeof ref.fLocX && 'number' === typeof ref.tLocX) { if (ref.fromLocation && ref.toLocation) {
const fromI = leg.stopovers.findIndex(s => s[locX] === ref.fLocX) const fromI = leg.stopovers.findIndex(s => s.stop === fromLocation)
const toI = leg.stopovers.findIndex(s => s[locX] === ref.tLocX) const toI = leg.stopovers.findIndex(s => s.stop === toLocation)
if (fromI < 0 || toI < 0) continue if (fromI < 0 || toI < 0) continue
const wholeLeg = fromI === 0 && toI === (leg.stopovers.length - 1) 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 createParseJourneyLeg = (profile, opt, data) => {
const {locations, hints, warnings, polylines} = data const {hints, warnings, polylines} = data
// todo: pt.status, pt.isPartCncl // todo: pt.status, pt.isPartCncl
// todo: pt.isRchbl, pt.chRatingRT, pt.chgDurR, pt.minChg // todo: pt.isRchbl, pt.chRatingRT, pt.chgDurR, pt.minChg
// todo: pt.dep.dProgType, pt.arr.dProgType // 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 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 arr = profile.parseDateTime(profile, j.date, pt.arr.aTimeR || pt.arr.aTimeS, pt.arr.aTZOffset)
const res = { const res = {
origin: clone(locations[parseInt(pt.dep.locX)]) || null, origin: clone(pt.dep.location) || null,
destination: clone(locations[parseInt(pt.arr.locX)]), destination: clone(pt.arr.location),
departure: dep, departure: dep,
arrival: arr arrival: arr
} }
@ -119,12 +118,6 @@ const createParseJourneyLeg = (profile, opt, data) => {
res.stopovers = stopL.map(parse) res.stopovers = stopL.map(parse)
if (opt.remarks && Array.isArray(pt.jny.msgL)) { 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 // todo: apply leg-wide remarks if `parseStopovers` is false
applyRemarks(res, hints, warnings, pt.jny.msgL) applyRemarks(res, hints, warnings, pt.jny.msgL)
} }

View file

@ -1,7 +1,7 @@
'use strict' 'use strict'
const createParseMovement = (profile, opt, data) => { const createParseMovement = (profile, opt, data) => {
const {locations, polylines} = data const {polylines} = data
// todo: what is m.dirGeo? maybe the speed? // todo: what is m.dirGeo? maybe the speed?
// todo: what is m.stopL? // todo: what is m.stopL?
@ -30,8 +30,8 @@ const createParseMovement = (profile, opt, data) => {
if (Array.isArray(m.ani.mSec)) { if (Array.isArray(m.ani.mSec)) {
for (let i = 0; i < m.ani.mSec.length; i++) { for (let i = 0; i < m.ani.mSec.length; i++) {
res.frames.push({ res.frames.push({
origin: locations[m.ani.fLocX[i]] || null, origin: m.ani.fromLocations[i] || null,
destination: locations[m.ani.tLocX[i]] || null, destination: m.ani.toLocations[i] || null,
t: m.ani.mSec[i] t: m.ani.mSec[i]
}) })
} }

View file

@ -3,7 +3,7 @@
const {toGeoJSON} = require('@mapbox/polyline') const {toGeoJSON} = require('@mapbox/polyline')
const distance = require('gps-distance') const distance = require('gps-distance')
const createParsePolyline = (profile, opt, {locations}) => { const createParsePolyline = (profile, opt, _) => {
// todo: what is p.delta? // todo: what is p.delta?
// todo: what is p.type? // todo: what is p.type?
// todo: what is p.crdEncS? // todo: what is p.crdEncS?
@ -24,8 +24,7 @@ const createParsePolyline = (profile, opt, {locations}) => {
if (Array.isArray(p.ppLocRefL)) { if (Array.isArray(p.ppLocRefL)) {
for (let ref of p.ppLocRefL) { for (let ref of p.ppLocRefL) {
const p = res[ref.ppIdx] const p = res[ref.ppIdx]
const loc = locations[ref.locX] if (p && ref.location) p.properties = ref.location
if (p && loc) p.properties = loc
} }
// Often there is one more point right next to each point at a station. // Often there is one more point right next to each point at a station.

View file

@ -3,11 +3,11 @@
const findRemark = require('./find-remark') const findRemark = require('./find-remark')
const createParseStopover = (profile, opt, data, date) => { const createParseStopover = (profile, opt, data, date) => {
const {locations, lines, hints, warnings} = data const {hints, warnings} = data
const parseStopover = (st) => { const parseStopover = (st) => {
const res = { const res = {
stop: locations[parseInt(st.locX)] || null, stop: st.location || null,
arrival: null, arrival: null,
arrivalDelay: null, arrivalDelay: null,
arrivalPlatform: st.aPlatfR || st.aPlatfS || null, arrivalPlatform: st.aPlatfR || st.aPlatfS || null,

View file

@ -9,17 +9,23 @@ const typesByIcon = Object.assign(Object.create(null), {
HimWarn: 'status' HimWarn: 'status'
}) })
const parseMsgEdge = (profile, data) => (e) => { const parseMsgEdge = (profile) => (e) => {
const res = omit(e, ['icoX', 'fLocX', 'tLocX']) const res = omit(e, [
'icoX',
'fLocX', 'fromLocation',
'tLocX', 'toLocation'
])
res.icon = e.icon || null res.icon = e.icon || null
res.fromLoc = 'number' === typeof e.fLocX && data.locations[e.fLocX] || null // todo: rename `Loc` -> `Location` [breaking]
res.toLoc = 'number' === typeof e.tLocX && data.locations[e.tLocX] || null res.fromLoc = e.fromLocation || null
res.toLoc = e.toLocation || null
return res return res
} }
const parseMsgEvent = (profile, data) => (e) => { const parseMsgEvent = (profile) => (e) => {
return { return {
fromLoc: 'number' === typeof e.fLocX && data.locations[e.fLocX] || null, // todo: rename `Loc` -> `Location` [breaking]
toLoc: 'number' === typeof e.tLocX && data.locations[e.tLocX] || null, fromLoc: e.fromLocation || null,
toLoc: e.toLocation || null,
start: parseDateTime(profile, e.fDate, e.fTime, null), start: parseDateTime(profile, e.fDate, e.fTime, null),
end: parseDateTime(profile, e.tDate, e.tTime, null), end: parseDateTime(profile, e.tDate, e.tTime, null),
sections: e.sectionNums || [] // todo: parse sections: e.sectionNums || [] // todo: parse
@ -64,13 +70,13 @@ const parseWarning = (profile, w, data) => {
res.edges = w.edgeRefL res.edges = w.edgeRefL
.map(i => data.himMsgEdgeL[i]) .map(i => data.himMsgEdgeL[i])
.filter(e => !!e) .filter(e => !!e)
.map(parseMsgEdge(profile, data)) .map(parseMsgEdge(profile))
} }
if (w.eventRefL && data.himMsgEventL) { if (w.eventRefL && data.himMsgEventL) {
res.events = w.eventRefL res.events = w.eventRefL
.map(i => data.himMsgEventL[i]) .map(i => data.himMsgEventL[i])
.filter(e => !!e) .filter(e => !!e)
.map(parseMsgEvent(profile, data)) .map(parseMsgEvent(profile))
} }
if (w.sDate && w.sTime) res.validFrom = parseDateTime(profile, w.sDate, w.sTime, null) if (w.sDate && w.sTime) res.validFrom = parseDateTime(profile, w.sDate, w.sTime, null)