|
|
@ -2,11 +2,23 @@ |
|
|
|
* @type {string} |
|
|
|
* @type {string} |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var trainNumber |
|
|
|
var trainNumber |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @type {string | null} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
var tripId = null |
|
|
|
/** |
|
|
|
/** |
|
|
|
* @type {Date} |
|
|
|
* @type {Date} |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var date |
|
|
|
var date |
|
|
|
var groupIndex = null |
|
|
|
var groupIndex = null |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @type {string | null} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
var startId = null |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @type {string | null} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
var stopId = null |
|
|
|
|
|
|
|
|
|
|
|
var yesterday = false |
|
|
|
var yesterday = false |
|
|
|
var showKm = false |
|
|
|
var showKm = false |
|
|
@ -17,71 +29,62 @@ var trainData = null |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var lastSuccessfulFetch = null |
|
|
|
var lastSuccessfulFetch = null |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var loadMap = false |
|
|
|
/** |
|
|
|
/** |
|
|
|
* @typedef ArrDep |
|
|
|
* @type {any} |
|
|
|
* @property {string} scheduleTime |
|
|
|
*/ |
|
|
|
* @property {?{delay: number, real: boolean}} status |
|
|
|
var leafletMap = null |
|
|
|
* |
|
|
|
/** |
|
|
|
* @typedef Note |
|
|
|
* @type {any[]} |
|
|
|
* @property {string} kind |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @typedef DepartsAsNote |
|
|
|
|
|
|
|
* @type {Note} |
|
|
|
|
|
|
|
* @property {"departsAs"} kind |
|
|
|
|
|
|
|
* @property {string} rank |
|
|
|
|
|
|
|
* @property {string} number |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @typedef TrainNumberChangeNote |
|
|
|
|
|
|
|
* @type {Note} |
|
|
|
|
|
|
|
* @property {"trainNumberChange"} kind |
|
|
|
|
|
|
|
* @property {string} rank |
|
|
|
|
|
|
|
* @property {string} number |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @typedef DetachingWagonsNote |
|
|
|
|
|
|
|
* @type {Note} |
|
|
|
|
|
|
|
* @property {"detachingWagons"} kind |
|
|
|
|
|
|
|
* @property {string} station |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @typedef ReceivingWagonsNote |
|
|
|
|
|
|
|
* @type {Note} |
|
|
|
|
|
|
|
* @property {"receivingWagons"} kind |
|
|
|
|
|
|
|
* @property {string} station |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @typedef TrainStop |
|
|
|
|
|
|
|
* @property {string} name |
|
|
|
|
|
|
|
* @property {number} km |
|
|
|
|
|
|
|
* @property {?number} stoppingTime |
|
|
|
|
|
|
|
* @property {?string} platform |
|
|
|
|
|
|
|
* @property {ArrDep} arrival |
|
|
|
|
|
|
|
* @property {ArrDep} departure |
|
|
|
|
|
|
|
* @property {Note[]} notes |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @typedef Group |
|
|
|
|
|
|
|
* @property {{from: string; to: string}} route |
|
|
|
|
|
|
|
* @property {{delay: number; station: string; state: "passing" | "arrival" | "departure"} | undefined} status |
|
|
|
|
|
|
|
* @property {TrainStop[]} stations |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
var mapLayers = [] |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* @param {{ rank: string; number: string; operator: string; date: string; groups: Group[]; }} data |
|
|
|
* @param {DbTrip & DbArrDep} data |
|
|
|
* @param {?Date} fetchDate |
|
|
|
* @param {?Date} fetchDate |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
function onTrainData(data, fetchDate) { |
|
|
|
function onTrainData(data, fetchDate) { |
|
|
|
|
|
|
|
if (loadMap) { |
|
|
|
|
|
|
|
document.getElementById('load-map-button').remove() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (window.localStorage) { |
|
|
|
|
|
|
|
localStorage.setItem('recent/view-train', JSON.stringify({ |
|
|
|
|
|
|
|
trainNumber: data.line.fahrtNr, |
|
|
|
|
|
|
|
name: data.line.name, |
|
|
|
|
|
|
|
tripId: data.id, |
|
|
|
|
|
|
|
date: date ? date.toISOString() : undefined, |
|
|
|
|
|
|
|
$addDate: new Date().toISOString(), |
|
|
|
|
|
|
|
})) |
|
|
|
|
|
|
|
} |
|
|
|
var title = document.getElementById('title') |
|
|
|
var title = document.getElementById('title') |
|
|
|
title.textContent = '' |
|
|
|
title.textContent = '' |
|
|
|
title.appendChild(document.createTextNode('Train ')) |
|
|
|
title.appendChild(document.createTextNode('Train ')) |
|
|
|
trainIdSpan(data.rank, data.number, title) |
|
|
|
var lineNameSpan = document.createElement('span') |
|
|
|
|
|
|
|
title.appendChild(lineNameSpan) |
|
|
|
|
|
|
|
lineNameSpan.textContent = data.line.name |
|
|
|
|
|
|
|
if (data.line.product) { |
|
|
|
|
|
|
|
if (data.line.productName === 'STB' && data.line.name.startsWith('STB U')) { |
|
|
|
|
|
|
|
data.line.product = 'subway' |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
lineNameSpan.classList.add('product-' + data.line.product) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// trainIdSpan(data.line.productName, data.line.fahrtNr, title)
|
|
|
|
|
|
|
|
// title.append(' ')
|
|
|
|
|
|
|
|
title.append(` (${data.line.fahrtNr})`) |
|
|
|
|
|
|
|
|
|
|
|
document.getElementsByTagName('title')[0].textContent = `Train ${data.rank} ${data.number}` |
|
|
|
document.getElementsByTagName('title')[0].textContent = `Train ${data.line.productName} ${data.line.fahrtNr} (${data.line.name})` |
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('company').textContent = data.operator |
|
|
|
if (data.line.operator) { |
|
|
|
|
|
|
|
document.getElementById('company').textContent = data.line.operator.name |
|
|
|
|
|
|
|
} |
|
|
|
var dateHref = document.createElement('a') |
|
|
|
var dateHref = document.createElement('a') |
|
|
|
var dateP = document.getElementById('date') |
|
|
|
var dateP = document.getElementById('date') |
|
|
|
while (dateP.childNodes.length > 0) { |
|
|
|
while (dateP.childNodes.length > 0) { |
|
|
|
dateP.childNodes[0].remove() |
|
|
|
dateP.childNodes[0].remove() |
|
|
|
} |
|
|
|
} |
|
|
|
dateP.appendChild(dateHref) |
|
|
|
dateP.appendChild(dateHref) |
|
|
|
dateHref.textContent = data.date |
|
|
|
dateHref.textContent = new Date(data.departure || data.plannedDeparture).toDateString() |
|
|
|
dateHref.href = '#' |
|
|
|
dateHref.href = '#' |
|
|
|
dateHref.classList.add('no-a-custom') |
|
|
|
dateHref.classList.add('no-a-custom') |
|
|
|
dateHref.classList.add('items', 'no-a-custom') |
|
|
|
dateHref.classList.add('items', 'no-a-custom') |
|
|
@ -105,80 +108,9 @@ function onTrainData(data, fetchDate) { |
|
|
|
document.getElementById('loading').classList.add('hidden') |
|
|
|
document.getElementById('loading').classList.add('hidden') |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* @type {Group | null} |
|
|
|
* @type {DbTrip & DbArrDep} |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var group = null; |
|
|
|
var group = data |
|
|
|
if (data.groups.length > 1 && groupIndex == null) { |
|
|
|
|
|
|
|
document.getElementById('group-choice').classList.remove('hidden') |
|
|
|
|
|
|
|
document.getElementById('group-choice').focus() |
|
|
|
|
|
|
|
document.getElementById('train-info').classList.add('hidden') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
document.getElementsByClassName('rsk')[0].textContent = '' |
|
|
|
|
|
|
|
document.getElementsByClassName('csk')[0].textContent = 'Select' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
title.textContent = 'Select Group for ' |
|
|
|
|
|
|
|
trainIdSpan(data.rank, data.number, title) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var gc = document.getElementById('group-choice') |
|
|
|
|
|
|
|
while (gc.childNodes.length > 0) { |
|
|
|
|
|
|
|
gc.childNodes[0].remove() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < data.groups.length; i++) { |
|
|
|
|
|
|
|
var g = data.groups[i] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var groupLi = document.createElement('li') |
|
|
|
|
|
|
|
gc.append(groupLi) |
|
|
|
|
|
|
|
groupLi.tabIndex = i |
|
|
|
|
|
|
|
groupLi.classList.add('items') |
|
|
|
|
|
|
|
if (i === currentIndex) { |
|
|
|
|
|
|
|
groupLi.focus() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function (i) { |
|
|
|
|
|
|
|
function onAction(e) { |
|
|
|
|
|
|
|
var url = new URL(window.location.toString()) |
|
|
|
|
|
|
|
groupIndex = i |
|
|
|
|
|
|
|
if (window.localStorage) { |
|
|
|
|
|
|
|
localStorage.setItem('recent/view-train', JSON.stringify({ |
|
|
|
|
|
|
|
trainNumber: trainNumber, |
|
|
|
|
|
|
|
date: date.toISOString(), |
|
|
|
|
|
|
|
groupIndex: groupIndex, |
|
|
|
|
|
|
|
$addDate: new Date().toISOString(), |
|
|
|
|
|
|
|
})) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
url.searchParams.append('groupIndex', groupIndex) |
|
|
|
|
|
|
|
window.history.pushState({'groupIndex': groupIndex}, '', url.toString( )) |
|
|
|
|
|
|
|
onTrainData(data) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
groupLi.addEventListener('click', onAction) |
|
|
|
|
|
|
|
groupLi.addEventListener('keypress', function (e) { |
|
|
|
|
|
|
|
if (e.key == 'Enter') { |
|
|
|
|
|
|
|
onAction(e) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
})(i) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var routeP = document.createElement('p') |
|
|
|
|
|
|
|
groupLi.append(routeP) |
|
|
|
|
|
|
|
routeP.classList.add('pri') |
|
|
|
|
|
|
|
routeP.textContent = `${g.route.from} ➔ ${g.route.to}` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var groupP = document.createElement('p') |
|
|
|
|
|
|
|
groupLi.append(groupP) |
|
|
|
|
|
|
|
groupP.classList.add('thi') |
|
|
|
|
|
|
|
groupP.textContent = i === 0 ? 'Main train' : `Group ${i}` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (data.groups.length === 1) { |
|
|
|
|
|
|
|
group = data.groups[0] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
group = data.groups[groupIndex] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
document.getElementById('group-choice').classList.add('hidden') |
|
|
|
document.getElementById('group-choice').classList.add('hidden') |
|
|
|
document.getElementById('train-info').classList.remove('hidden') |
|
|
|
document.getElementById('train-info').classList.remove('hidden') |
|
|
|
document.getElementById('train-info').focus() |
|
|
|
document.getElementById('train-info').focus() |
|
|
@ -186,8 +118,8 @@ function onTrainData(data, fetchDate) { |
|
|
|
document.getElementsByClassName('rsk')[0].textContent = 'Refresh' |
|
|
|
document.getElementsByClassName('rsk')[0].textContent = 'Refresh' |
|
|
|
document.getElementsByClassName('csk')[0].textContent = '' |
|
|
|
document.getElementsByClassName('csk')[0].textContent = '' |
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('route-from').textContent = group.route.from |
|
|
|
document.getElementById('route-from').textContent = group.origin.name |
|
|
|
document.getElementById('route-to').textContent = group.route.to |
|
|
|
document.getElementById('route-to').textContent = group.destination.name |
|
|
|
|
|
|
|
|
|
|
|
if (group.status) { |
|
|
|
if (group.status) { |
|
|
|
document.getElementById('status').classList.remove('hidden') |
|
|
|
document.getElementById('status').classList.remove('hidden') |
|
|
@ -279,21 +211,47 @@ function onTrainData(data, fetchDate) { |
|
|
|
var stationsList = document.createElement('ul') |
|
|
|
var stationsList = document.createElement('ul') |
|
|
|
stationsDiv.appendChild(stationsList) |
|
|
|
stationsDiv.appendChild(stationsList) |
|
|
|
|
|
|
|
|
|
|
|
group.stations.forEach(function (station) { |
|
|
|
/** |
|
|
|
|
|
|
|
* @type {string[] | null} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
var journeyStations = null |
|
|
|
|
|
|
|
if (startId && stopId) { |
|
|
|
|
|
|
|
journeyStations = [] |
|
|
|
|
|
|
|
var include = false |
|
|
|
|
|
|
|
for (var si = 0; si < group.stopovers.length; si++) { |
|
|
|
|
|
|
|
if (group.stopovers[si].stop.id === startId) { |
|
|
|
|
|
|
|
include = true |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (include) { |
|
|
|
|
|
|
|
journeyStations.push(group.stopovers[si].stop.id) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (group.stopovers[si].stop.id === stopId) { |
|
|
|
|
|
|
|
break |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
group.stopovers.forEach(function (station) { |
|
|
|
var stationItem = document.createElement('li') |
|
|
|
var stationItem = document.createElement('li') |
|
|
|
stationsList.appendChild(stationItem) |
|
|
|
stationsList.appendChild(stationItem) |
|
|
|
stationItem.classList.add('stationItem') |
|
|
|
stationItem.classList.add('stationItem') |
|
|
|
|
|
|
|
if (station.cancelled && !station.arrival && !station.departure) { |
|
|
|
|
|
|
|
stationItem.classList.add('cancelled') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (journeyStations && !journeyStations.includes(station.stop.id)) { |
|
|
|
|
|
|
|
stationItem.classList.add('not-in-journey') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var stationName = document.createElement('p') |
|
|
|
var stationName = document.createElement('p') |
|
|
|
stationItem.appendChild(stationName) |
|
|
|
stationItem.appendChild(stationName) |
|
|
|
stationName.classList.add('pri', 'name') |
|
|
|
stationName.classList.add('pri', 'name') |
|
|
|
var stationNameHref = document.createElement('a') |
|
|
|
var stationNameHref = document.createElement('a') |
|
|
|
stationName.appendChild(stationNameHref) |
|
|
|
stationName.appendChild(stationNameHref) |
|
|
|
stationNameHref.textContent = station.name |
|
|
|
stationNameHref.textContent = station.stop.name |
|
|
|
stationNameHref.classList.add('items', 'no-a-custom') |
|
|
|
stationNameHref.classList.add('items', 'no-a-custom') |
|
|
|
var stationUrl = new URL('/view-station.html', window.location.origin) |
|
|
|
var stationUrl = new URL('/view-station.html', window.location.origin) |
|
|
|
stationUrl.searchParams.append('station', station.name) |
|
|
|
stationUrl.searchParams.append('stationId', station.stop.id) |
|
|
|
stationUrl.searchParams.append('date', (station.arrival || station.departure).scheduleTime) |
|
|
|
stationUrl.searchParams.append('date', (station.arrival || station.departure)) |
|
|
|
stationNameHref.href = stationUrl.toString() |
|
|
|
stationNameHref.href = stationUrl.toString() |
|
|
|
|
|
|
|
|
|
|
|
if (station.arrival) { |
|
|
|
if (station.arrival) { |
|
|
@ -305,26 +263,26 @@ function onTrainData(data, fetchDate) { |
|
|
|
stationArrival.appendChild(originalArr) |
|
|
|
stationArrival.appendChild(originalArr) |
|
|
|
var originalArrSpan = document.createElement('pre') |
|
|
|
var originalArrSpan = document.createElement('pre') |
|
|
|
originalArr.appendChild(originalArrSpan) |
|
|
|
originalArr.appendChild(originalArrSpan) |
|
|
|
var arrDate = new Date(station.arrival.scheduleTime) |
|
|
|
var arrDate = new Date(station.plannedArrival) |
|
|
|
originalArrSpan.textContent = arrDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' }) |
|
|
|
originalArrSpan.textContent = arrDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' }) |
|
|
|
originalArr.classList.add('pri') |
|
|
|
originalArr.classList.add('pri') |
|
|
|
if (station.arrival.status && station.arrival.status.delay != 0) { |
|
|
|
if (station.arrivalDelay) { |
|
|
|
originalArr.classList.remove('pri') |
|
|
|
originalArr.classList.remove('pri') |
|
|
|
originalArr.classList.add('thi') |
|
|
|
originalArr.classList.add('thi') |
|
|
|
originalArrSpan.classList.add('original') |
|
|
|
originalArrSpan.classList.add('original') |
|
|
|
var delaySpanArr = document.createElement('span') |
|
|
|
var delaySpanArr = document.createElement('span') |
|
|
|
originalArr.appendChild(delaySpanArr) |
|
|
|
originalArr.appendChild(delaySpanArr) |
|
|
|
delaySpanArr.textContent = `${station.arrival.status.delay > 0 ? '+' : ''}${station.arrival.status.delay}`; |
|
|
|
delaySpanArr.textContent = `${station.arrivalDelay > 0 ? '+' : ''}${station.arrivalDelay / 60}`; |
|
|
|
delaySpanArr.classList.add(station.arrival.status.delay > 0 ? 'late' : 'early') |
|
|
|
delaySpanArr.classList.add(station.arrivalDelay > 0 ? 'late' : 'early') |
|
|
|
delaySpanArr.style.marginLeft = '4px' |
|
|
|
delaySpanArr.style.marginLeft = '4px' |
|
|
|
|
|
|
|
|
|
|
|
var actualArr = document.createElement('p') |
|
|
|
var actualArr = document.createElement('p') |
|
|
|
stationArrival.appendChild(actualArr) |
|
|
|
stationArrival.appendChild(actualArr) |
|
|
|
arrDate.setMinutes(arrDate.getMinutes() + station.arrival.status.delay) |
|
|
|
arrDate.setSeconds(arrDate.getSeconds() + station.arrivalDelay) |
|
|
|
actualArr.classList.add('pri', station.arrival.status.delay > 0 ? 'late' : 'early') |
|
|
|
actualArr.classList.add('pri', station.arrivalDelay > 0 ? 'late' : 'early') |
|
|
|
if (!station.arrival.status.real) { |
|
|
|
// if (!station.arrival.status.real) {
|
|
|
|
actualArr.classList.add('not-real') |
|
|
|
// actualArr.classList.add('not-real')
|
|
|
|
} |
|
|
|
// }
|
|
|
|
var actualArrPre = document.createElement('pre') |
|
|
|
var actualArrPre = document.createElement('pre') |
|
|
|
actualArr.appendChild(actualArrPre) |
|
|
|
actualArr.appendChild(actualArrPre) |
|
|
|
actualArrPre.textContent = arrDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' }) |
|
|
|
actualArrPre.textContent = arrDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' }) |
|
|
@ -338,88 +296,413 @@ function onTrainData(data, fetchDate) { |
|
|
|
|
|
|
|
|
|
|
|
var originalDep = document.createElement('p') |
|
|
|
var originalDep = document.createElement('p') |
|
|
|
stationDeparture.appendChild(originalDep) |
|
|
|
stationDeparture.appendChild(originalDep) |
|
|
|
var depDate = new Date(station.departure.scheduleTime) |
|
|
|
var depDate = new Date(station.plannedDeparture) |
|
|
|
var originalDepSpan = document.createElement('pre') |
|
|
|
var originalDepSpan = document.createElement('pre') |
|
|
|
originalDep.appendChild(originalDepSpan) |
|
|
|
originalDep.appendChild(originalDepSpan) |
|
|
|
originalDepSpan.textContent = depDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' }) |
|
|
|
originalDepSpan.textContent = depDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' }) |
|
|
|
originalDep.classList.add('pri') |
|
|
|
originalDep.classList.add('pri') |
|
|
|
if (station.departure.status && station.departure.status.delay != 0) { |
|
|
|
if (station.departureDelay) { |
|
|
|
originalDep.classList.remove('pri') |
|
|
|
originalDep.classList.remove('pri') |
|
|
|
originalDep.classList.add('thi') |
|
|
|
originalDep.classList.add('thi') |
|
|
|
originalDepSpan.classList.add('original') |
|
|
|
originalDepSpan.classList.add('original') |
|
|
|
var delaySpanDep = document.createElement('span') |
|
|
|
var delaySpanDep = document.createElement('span') |
|
|
|
originalDep.appendChild(delaySpanDep) |
|
|
|
originalDep.appendChild(delaySpanDep) |
|
|
|
delaySpanDep.textContent = `${station.departure.status.delay > 0 ? '+' : ''}${station.departure.status.delay}`; |
|
|
|
delaySpanDep.textContent = `${station.departureDelay > 0 ? '+' : ''}${station.departureDelay / 60}`; |
|
|
|
delaySpanDep.classList.add(station.departure.status.delay > 0 ? 'late' : 'early') |
|
|
|
delaySpanDep.classList.add(station.departureDelay > 0 ? 'late' : 'early') |
|
|
|
delaySpanDep.style.marginLeft = '4px' |
|
|
|
delaySpanDep.style.marginLeft = '4px' |
|
|
|
|
|
|
|
|
|
|
|
var actualDep = document.createElement('p') |
|
|
|
var actualDep = document.createElement('p') |
|
|
|
stationDeparture.appendChild(actualDep) |
|
|
|
stationDeparture.appendChild(actualDep) |
|
|
|
depDate.setMinutes(depDate.getMinutes() + station.departure.status.delay) |
|
|
|
depDate.setSeconds(depDate.getSeconds() + station.departureDelay) |
|
|
|
actualDep.classList.add('pri', station.departure.status.delay > 0 ? 'late' : 'early') |
|
|
|
actualDep.classList.add('pri', station.departureDelay > 0 ? 'late' : 'early') |
|
|
|
if (!station.departure.status.real) { |
|
|
|
// if (!station.departure.status.real) {
|
|
|
|
actualDep.classList.add('not-real') |
|
|
|
// actualDep.classList.add('not-real')
|
|
|
|
} |
|
|
|
// }
|
|
|
|
var actualDepPre = document.createElement('pre') |
|
|
|
var actualDepPre = document.createElement('pre') |
|
|
|
actualDep.appendChild(actualDepPre) |
|
|
|
actualDep.appendChild(actualDepPre) |
|
|
|
actualDepPre.textContent = depDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' }) |
|
|
|
actualDepPre.textContent = depDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' }) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var stationKm = document.createElement('p') |
|
|
|
// var stationKm = document.createElement('p')
|
|
|
|
stationItem.appendChild(stationKm) |
|
|
|
// stationItem.appendChild(stationKm)
|
|
|
|
stationKm.textContent = `${station.km} km` |
|
|
|
// stationKm.textContent = `${station.km} km`
|
|
|
|
stationKm.classList.add('thi', 'km') |
|
|
|
// stationKm.classList.add('thi', 'km')
|
|
|
|
if (!showKm) { |
|
|
|
// if (!showKm) {
|
|
|
|
stationKm.classList.add('hidden') |
|
|
|
// stationKm.classList.add('hidden')
|
|
|
|
} |
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
if (station.platform) { |
|
|
|
if (station.arrivalPlatform || station.departurePlatform) { |
|
|
|
var stationPlatform = document.createElement('p') |
|
|
|
var stationPlatform = document.createElement('p') |
|
|
|
stationItem.appendChild(stationPlatform) |
|
|
|
stationItem.appendChild(stationPlatform) |
|
|
|
stationPlatform.textContent = `platform ${station.platform}` |
|
|
|
stationPlatform.textContent = `platform ${station.departurePlatform || station.arrivalPlatform}` |
|
|
|
stationPlatform.classList.add('thi', 'platform') |
|
|
|
stationPlatform.classList.add('thi', 'platform') |
|
|
|
|
|
|
|
if (station.departurePlatform && station.departurePlatform !== station.plannedDeparturePlatform) { |
|
|
|
|
|
|
|
stationPlatform.classList.add('changed') |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (station.notes && station.notes.length > 0) { |
|
|
|
|
|
|
|
var stationNotes = document.createElement('div') |
|
|
|
var stationNotes = document.createElement('div') |
|
|
|
stationItem.appendChild(stationNotes) |
|
|
|
stationItem.appendChild(stationNotes) |
|
|
|
stationNotes.classList.add('notes') |
|
|
|
stationNotes.classList.add('notes') |
|
|
|
|
|
|
|
if (station.remarks) { |
|
|
|
|
|
|
|
station.remarks.forEach(function (remark) { |
|
|
|
|
|
|
|
var noteP = document.createElement('p') |
|
|
|
|
|
|
|
stationNotes.appendChild(noteP) |
|
|
|
|
|
|
|
noteP.classList.add('note', 'thi', `remark-${remark.type}`) |
|
|
|
|
|
|
|
noteP.textContent = remark.text |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (journeyStations && station.stop.id === journeyStations[0]) { |
|
|
|
|
|
|
|
var boardNoteP = document.createElement('p') |
|
|
|
|
|
|
|
stationNotes.appendChild(boardNoteP) |
|
|
|
|
|
|
|
boardNoteP.classList.add('note', 'thi', 'remark-board') |
|
|
|
|
|
|
|
boardNoteP.textContent = 'Board here' |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (journeyStations && station.stop.id === journeyStations[journeyStations.length - 1]) { |
|
|
|
|
|
|
|
var boardNoteP = document.createElement('p') |
|
|
|
|
|
|
|
stationNotes.appendChild(boardNoteP) |
|
|
|
|
|
|
|
boardNoteP.classList.add('note', 'thi', 'remark-exit') |
|
|
|
|
|
|
|
boardNoteP.textContent = 'Exit here' |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// if (station.notes && station.notes.length > 0) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// station.notes.forEach(function (note) {
|
|
|
|
|
|
|
|
// var noteP = document.createElement('p')
|
|
|
|
|
|
|
|
// stationNotes.appendChild(noteP)
|
|
|
|
|
|
|
|
// noteP.classList.add('note', 'thi')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// switch (note.kind) {
|
|
|
|
|
|
|
|
// case 'departsAs': {
|
|
|
|
|
|
|
|
// noteP.textContent = 'Train departs as '
|
|
|
|
|
|
|
|
// trainIdSpan(note.rank, note.number, noteP)
|
|
|
|
|
|
|
|
// break
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// case 'detachingWagons': {
|
|
|
|
|
|
|
|
// noteP.textContent = `Detaching wagons to ${note.station}`
|
|
|
|
|
|
|
|
// break
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// case 'receivingWagons': {
|
|
|
|
|
|
|
|
// noteP.textContent = `Receiving wagons from ${note.station}`
|
|
|
|
|
|
|
|
// break
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// case 'trainNumberChange': {
|
|
|
|
|
|
|
|
// noteP.textContent = 'Train changes number to '
|
|
|
|
|
|
|
|
// trainIdSpan(note.rank, note.number, noteP)
|
|
|
|
|
|
|
|
// break
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
station.notes.forEach(function (note) { |
|
|
|
if (station.cancelled && !station.arrival && !station.departure) { |
|
|
|
var noteP = document.createElement('p') |
|
|
|
var noteP = document.createElement('p') |
|
|
|
stationNotes.appendChild(noteP) |
|
|
|
stationNotes.appendChild(noteP) |
|
|
|
noteP.classList.add('note', 'thi') |
|
|
|
noteP.classList.add('note', 'thi') |
|
|
|
|
|
|
|
noteP.textContent = 'Stop is cancelled' |
|
|
|
switch (note.kind) { |
|
|
|
|
|
|
|
case 'departsAs': { |
|
|
|
|
|
|
|
noteP.textContent = 'Train departs as ' |
|
|
|
|
|
|
|
trainIdSpan(note.rank, note.number, noteP) |
|
|
|
|
|
|
|
break |
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case 'detachingWagons': { |
|
|
|
}) |
|
|
|
noteP.textContent = `Detaching wagons to ${note.station}` |
|
|
|
|
|
|
|
break |
|
|
|
if (group.remarks && group.remarks.length > 0) { |
|
|
|
|
|
|
|
var remarksSeparator = document.createElement('h4') |
|
|
|
|
|
|
|
stationsDiv.appendChild(remarksSeparator) |
|
|
|
|
|
|
|
remarksSeparator.textContent = 'Remarks' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var remarksList = document.createElement('ul') |
|
|
|
|
|
|
|
stationsDiv.appendChild(remarksList) |
|
|
|
|
|
|
|
remarksList.classList.add('remarks') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
group.remarks.forEach(function (remark) { |
|
|
|
|
|
|
|
var remarkItem = document.createElement('li') |
|
|
|
|
|
|
|
remarksList.append(remarkItem) |
|
|
|
|
|
|
|
remarkItem.classList.add('remarkItem', `remark-${remark.type}`) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var remarkSummaryP = document.createElement('p') |
|
|
|
|
|
|
|
remarkItem.appendChild(remarkSummaryP) |
|
|
|
|
|
|
|
remarkSummaryP.classList.add('remark', 'pri') |
|
|
|
|
|
|
|
remarkSummaryP.textContent = remark.summary |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var remarkTextP = document.createElement('p') |
|
|
|
|
|
|
|
remarkItem.appendChild(remarkTextP) |
|
|
|
|
|
|
|
remarkTextP.classList.add('remark', 'sec') |
|
|
|
|
|
|
|
remarkTextP.textContent = remark.text |
|
|
|
|
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
case 'receivingWagons': { |
|
|
|
|
|
|
|
noteP.textContent = `Receiving wagons from ${note.station}` |
|
|
|
var mapDiv = document.getElementById('map') |
|
|
|
break |
|
|
|
if (group.polyline) { |
|
|
|
|
|
|
|
console.log(group.polyline) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mapDiv.classList.remove('hidden') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var actualMap = document.getElementById('actual-map') |
|
|
|
|
|
|
|
if (!actualMap) { |
|
|
|
|
|
|
|
actualMap = document.createElement('div') |
|
|
|
|
|
|
|
actualMap.id = 'actual-map' |
|
|
|
|
|
|
|
mapDiv.insertBefore(actualMap, null) |
|
|
|
} |
|
|
|
} |
|
|
|
case 'trainNumberChange': { |
|
|
|
|
|
|
|
noteP.textContent = 'Train changes number to ' |
|
|
|
if (!leafletMap) { |
|
|
|
trainIdSpan(note.rank, note.number, noteP) |
|
|
|
leafletMap = L.map('actual-map', { |
|
|
|
break |
|
|
|
zoomSnap: 0.5, |
|
|
|
|
|
|
|
// zoomDelta: 0.5,
|
|
|
|
|
|
|
|
}).setView([51.1657, 10.4515], 6) |
|
|
|
|
|
|
|
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { |
|
|
|
|
|
|
|
maxZoom: 19, |
|
|
|
|
|
|
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' |
|
|
|
|
|
|
|
}).addTo(leafletMap); |
|
|
|
|
|
|
|
L.tileLayer('https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png', { |
|
|
|
|
|
|
|
attribution: ' Style: <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA 2.0</a> <a href="http://www.openrailwaymap.org/">OpenRailwayMap</a> and OpenStreetMap', |
|
|
|
|
|
|
|
minZoom: 2, |
|
|
|
|
|
|
|
maxZoom: 19, |
|
|
|
|
|
|
|
tileSize: 256 |
|
|
|
|
|
|
|
}).addTo(leafletMap) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mapLayers) { |
|
|
|
|
|
|
|
mapLayers.forEach(function (layer) { layer.remove() }) |
|
|
|
|
|
|
|
mapLayers = [] |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @type {[number, number][]} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
var lines = [] |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @type {[number, number][] | null} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
var journeyLines = null |
|
|
|
|
|
|
|
include = false |
|
|
|
|
|
|
|
var stops = [] |
|
|
|
|
|
|
|
var minLat = group.polyline.features[0].geometry.coordinates[1] |
|
|
|
|
|
|
|
var maxLat = minLat |
|
|
|
|
|
|
|
var minLng = group.polyline.features[0].geometry.coordinates[0] |
|
|
|
|
|
|
|
var maxLng = minLng |
|
|
|
|
|
|
|
for (var pi = 0; pi < group.polyline.features.length; pi++) { |
|
|
|
|
|
|
|
var feature = group.polyline.features[pi] |
|
|
|
|
|
|
|
var coord = feature.geometry.coordinates |
|
|
|
|
|
|
|
lines.push([coord[1], coord[0]]) |
|
|
|
|
|
|
|
if (journeyStations && include !== -1) { |
|
|
|
|
|
|
|
if (feature.properties && feature.properties.id === journeyStations[0]) { |
|
|
|
|
|
|
|
minLat = maxLat = coord[1] |
|
|
|
|
|
|
|
minLng = maxLng = coord[0] |
|
|
|
|
|
|
|
include = true |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (include) { |
|
|
|
|
|
|
|
if (!journeyLines) journeyLines = [] |
|
|
|
|
|
|
|
journeyLines.push([coord[1], coord[0]]) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (feature.properties && feature.properties.id === journeyStations[journeyStations.length - 1]) { |
|
|
|
|
|
|
|
include = -1 |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (feature.properties && feature.properties.type == 'stop') { |
|
|
|
|
|
|
|
stops.push({ |
|
|
|
|
|
|
|
coord: [coord[1], coord[0]], |
|
|
|
|
|
|
|
id: feature.properties.id, |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!journeyStations || include === true) { |
|
|
|
|
|
|
|
if (minLat > coord[1]) { |
|
|
|
|
|
|
|
minLat = coord[1] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (minLng > coord[0]) { |
|
|
|
|
|
|
|
minLng = coord[0] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (maxLat < coord[1]) { |
|
|
|
|
|
|
|
maxLat = coord[1] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (maxLng < coord[0]) { |
|
|
|
|
|
|
|
maxLng = coord[0] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mapLayers.push(L.polyline(lines, { |
|
|
|
|
|
|
|
color: !journeyLines ? '#6666ff' : '#9999dd', |
|
|
|
|
|
|
|
opacity: !journeyLines ? 1.0 : 0.8, |
|
|
|
|
|
|
|
weight: 4, |
|
|
|
|
|
|
|
}).addTo(leafletMap)); |
|
|
|
|
|
|
|
if (journeyLines) { |
|
|
|
|
|
|
|
mapLayers.push(L.polyline(journeyLines, { |
|
|
|
|
|
|
|
color: '#6666ff', |
|
|
|
|
|
|
|
weight: 2, |
|
|
|
|
|
|
|
}).addTo(leafletMap)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (var si = 0; si < stops.length; si++) { |
|
|
|
|
|
|
|
var stop = stops[si] |
|
|
|
|
|
|
|
mapLayers.push(L.circleMarker(stop.coord, { |
|
|
|
|
|
|
|
color: !journeyStations || journeyStations.includes(stop.id) ? '#ffff66' : '#dfdf66', |
|
|
|
|
|
|
|
radius: 5, |
|
|
|
|
|
|
|
}).addTo(leafletMap)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
leafletMap.flyToBounds([[minLat, minLng], [maxLat, maxLng]], { |
|
|
|
|
|
|
|
duration: 0.2, |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
actualMap.scrollIntoView() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (loadMap) { |
|
|
|
|
|
|
|
mapDiv.classList.add('hidden') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
lastSuccessfulFetch = fetchDate || new Date() |
|
|
|
lastSuccessfulFetch = fetchDate || new Date() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var refreshStopToken = null |
|
|
|
var refreshStopToken = null |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @typedef DbProducts |
|
|
|
|
|
|
|
* @property {boolean} nationalExpress |
|
|
|
|
|
|
|
* @property {boolean} national |
|
|
|
|
|
|
|
* @property {boolean} regionalExpress |
|
|
|
|
|
|
|
* @property {boolean} regional |
|
|
|
|
|
|
|
* @property {boolean} suburban |
|
|
|
|
|
|
|
* @property {boolean} bus |
|
|
|
|
|
|
|
* @property {boolean} ferry |
|
|
|
|
|
|
|
* @property {boolean} subway |
|
|
|
|
|
|
|
* @property {boolean} tram |
|
|
|
|
|
|
|
* @property {boolean} taxi |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @typedef DbLocation |
|
|
|
|
|
|
|
* @property {'location'} type |
|
|
|
|
|
|
|
* @property {?string} id |
|
|
|
|
|
|
|
* @property {number} latitude |
|
|
|
|
|
|
|
* @property {number} longitude |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @typedef DbLine |
|
|
|
|
|
|
|
* @property {'line'} type |
|
|
|
|
|
|
|
* @property {string} id |
|
|
|
|
|
|
|
* @property {string} fahrtNr |
|
|
|
|
|
|
|
* @property {string} name |
|
|
|
|
|
|
|
* @property {boolean} public |
|
|
|
|
|
|
|
* @property {string} adminCode |
|
|
|
|
|
|
|
* @property {string} productName |
|
|
|
|
|
|
|
* @property {string} mode |
|
|
|
|
|
|
|
* @property {string} product |
|
|
|
|
|
|
|
* @property {{type: 'operator', id: string, name: string}} operator |
|
|
|
|
|
|
|
* @property {string} additionalName |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @typedef DbStop |
|
|
|
|
|
|
|
* @property {'stop'} type |
|
|
|
|
|
|
|
* @property {?string} id |
|
|
|
|
|
|
|
* @property {string} name |
|
|
|
|
|
|
|
* @property {DbLocation} location |
|
|
|
|
|
|
|
* @property {DbProducts} products |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @typedef DbRemark |
|
|
|
|
|
|
|
* @property {string} type |
|
|
|
|
|
|
|
* @property {string} text |
|
|
|
|
|
|
|
* @property {string} code |
|
|
|
|
|
|
|
* @property {string} summary |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @typedef DbArrDep |
|
|
|
|
|
|
|
* @property {string | null} arrival |
|
|
|
|
|
|
|
* @property {string | null} plannedArrival |
|
|
|
|
|
|
|
* @property {number | null} arrivalDelay |
|
|
|
|
|
|
|
* @property {string | null} arrivalPlatform |
|
|
|
|
|
|
|
* @property {string | null} plannedArrivalPlatform |
|
|
|
|
|
|
|
* @property {string | null} arrivalPrognosisType |
|
|
|
|
|
|
|
* @property {string | null} departure |
|
|
|
|
|
|
|
* @property {string | null} plannedDeparture |
|
|
|
|
|
|
|
* @property {number | null} departureDelay |
|
|
|
|
|
|
|
* @property {string | null} departurePlatform |
|
|
|
|
|
|
|
* @property {string | null} plannedDeparturePlatform |
|
|
|
|
|
|
|
* @property {string | null} departurePrognosisType |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @typedef DbTrip |
|
|
|
|
|
|
|
* @property {DbStop} origin |
|
|
|
|
|
|
|
* @property {DbStop} destination |
|
|
|
|
|
|
|
* @property {DbLine} line |
|
|
|
|
|
|
|
* @property {string} direction |
|
|
|
|
|
|
|
* @property {DbLocation} location |
|
|
|
|
|
|
|
* @property {({stop: DbStop, cancelled?: boolean, remarks?: DbRemark[]} & DbArrDep)[]} stopovers |
|
|
|
|
|
|
|
* @property {DbRemark[]} remarks |
|
|
|
|
|
|
|
* @property {string} id |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* @param {string | null} tripId |
|
|
|
|
|
|
|
* @returns {Promise} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
function onTripId(tripId) { |
|
|
|
|
|
|
|
if (tripId) { |
|
|
|
|
|
|
|
var reqUrl = new URL(`https://v6.db.transport.rest/trips/${encodeURIComponent(tripId)}`) |
|
|
|
|
|
|
|
reqUrl.searchParams.append('stopovers', 'true') |
|
|
|
|
|
|
|
reqUrl.searchParams.append('remarks', 'true') |
|
|
|
|
|
|
|
if (loadMap) { |
|
|
|
|
|
|
|
reqUrl.searchParams.append('polyline', 'true') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return fetch( |
|
|
|
|
|
|
|
reqUrl.toString(), |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
cache: 'no-store', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
).then(function (response) { |
|
|
|
|
|
|
|
if (!response.ok) { |
|
|
|
|
|
|
|
// Check in 10 seconds if server returned error
|
|
|
|
|
|
|
|
return Promise.reject('Response not okay')
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var cacheDate = response.headers.get('SW-Cached-At') |
|
|
|
|
|
|
|
return response.json().then(function (data) { |
|
|
|
|
|
|
|
data['$cacheDate'] = cacheDate |
|
|
|
|
|
|
|
return data |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
}).then(function (response) { |
|
|
|
|
|
|
|
if (!response) { |
|
|
|
|
|
|
|
return Promise.reject('No JSON response') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var cacheDate = response['$cacheDate'] |
|
|
|
|
|
|
|
if (cacheDate) { |
|
|
|
|
|
|
|
cacheDate = new Date(cacheDate) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var success = !cacheDate |
|
|
|
|
|
|
|
trainData = response.trip |
|
|
|
|
|
|
|
onTrainData(response.trip, cacheDate) |
|
|
|
|
|
|
|
return success |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
return Promise.reject('No tripId found') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Callback for when trips are found |
|
|
|
|
|
|
|
* @param {string} wantedTrainNumber |
|
|
|
|
|
|
|
* @param {{trips: (DbTrip & DbArrDep)[]}} data
|
|
|
|
|
|
|
|
* @param {?Date} fetchDate
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
function onTripsData(wantedTrainNumber, data, fetchDate) { |
|
|
|
|
|
|
|
data.trips.forEach(function (trip) { |
|
|
|
|
|
|
|
if (trip.line.fahrtNr == wantedTrainNumber || trip.line.name == wantedTrainNumber) { |
|
|
|
|
|
|
|
tripId = trip.id |
|
|
|
|
|
|
|
console.group('Found tripId by train number') |
|
|
|
|
|
|
|
console.log(`ID: ${trip.id}`) |
|
|
|
|
|
|
|
console.log(`Fahrt Nr: ${trip.line.fahrtNr}`) |
|
|
|
|
|
|
|
console.log(`Name: ${trip.line.name}`) |
|
|
|
|
|
|
|
console.log(`+Name: ${trip.line.additionalName}`) |
|
|
|
|
|
|
|
console.groupEnd() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
return onTripId(tripId) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* @returns {Promise<boolean>} |
|
|
|
* @returns {Promise<boolean>} |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -432,6 +715,9 @@ function refresh() { |
|
|
|
refresh() |
|
|
|
refresh() |
|
|
|
}, timeout || 60000) |
|
|
|
}, timeout || 60000) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (tripId) { |
|
|
|
|
|
|
|
return onTripId(tripId) |
|
|
|
|
|
|
|
} |
|
|
|
/** |
|
|
|
/** |
|
|
|
* @type {Date} |
|
|
|
* @type {Date} |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -440,8 +726,14 @@ function refresh() { |
|
|
|
reqDate.setDate(reqDate.getDate() - 1) |
|
|
|
reqDate.setDate(reqDate.getDate() - 1) |
|
|
|
} |
|
|
|
} |
|
|
|
reqDate.setMinutes(0, 0, 0) |
|
|
|
reqDate.setMinutes(0, 0, 0) |
|
|
|
|
|
|
|
var reqUrl = new URL(`https://v6.db.transport.rest/trips`) |
|
|
|
|
|
|
|
reqUrl.searchParams.append('query', trainNumber) |
|
|
|
|
|
|
|
if (loadMap) { |
|
|
|
|
|
|
|
reqUrl.searchParams.append('polyline', 'true') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
reqUrl.searchParams.append('when', reqDate.toISOString()) |
|
|
|
return fetch( |
|
|
|
return fetch( |
|
|
|
`https://scraper.infotren.dcdev.ro/v3/trains/${trainNumber}?date=${reqDate.toISOString()}`, |
|
|
|
reqUrl.toString(), |
|
|
|
{ |
|
|
|
{ |
|
|
|
cache: 'no-store', |
|
|
|
cache: 'no-store', |
|
|
|
}, |
|
|
|
}, |
|
|
@ -465,11 +757,12 @@ function refresh() { |
|
|
|
cacheDate = new Date(cacheDate) |
|
|
|
cacheDate = new Date(cacheDate) |
|
|
|
} |
|
|
|
} |
|
|
|
var success = !cacheDate |
|
|
|
var success = !cacheDate |
|
|
|
trainData = response |
|
|
|
return onTripsData(trainNumber, response, cacheDate) |
|
|
|
onTrainData(response, cacheDate) |
|
|
|
.then(function () { |
|
|
|
// Check in 1 seconds if network error
|
|
|
|
// Check in 1 seconds if network error
|
|
|
|
reschedule(success ? undefined : 1000) |
|
|
|
reschedule(success ? undefined : 1000) |
|
|
|
return success |
|
|
|
return success |
|
|
|
|
|
|
|
}) |
|
|
|
}).catch(function (e) { |
|
|
|
}).catch(function (e) { |
|
|
|
// Check in 1 second if network error
|
|
|
|
// Check in 1 second if network error
|
|
|
|
reschedule(1000) |
|
|
|
reschedule(1000) |
|
|
@ -521,7 +814,9 @@ window.addEventListener('popstate', function (e) { |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
window.addEventListener('load', function (e) { |
|
|
|
window.addEventListener('load', function (e) { |
|
|
|
if (!new URL(window.location.href).searchParams.has('train')) { |
|
|
|
var sp = new URL(window.location.href).searchParams |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!sp.has('train') && !sp.has('tripId')) { |
|
|
|
window.history.back() |
|
|
|
window.history.back() |
|
|
|
this.setTimeout(function () { |
|
|
|
this.setTimeout(function () { |
|
|
|
var url = new URL(window.location.href) |
|
|
|
var url = new URL(window.location.href) |
|
|
@ -530,11 +825,12 @@ window.addEventListener('load', function (e) { |
|
|
|
}, 100) |
|
|
|
}, 100) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var sp = new URL(window.location.href).searchParams |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
trainNumber = sp.get('train') |
|
|
|
trainNumber = sp.get('train') |
|
|
|
date = sp.has('date') ? new Date(sp.get('date')) : new Date() |
|
|
|
date = sp.has('date') ? new Date(sp.get('date')) : new Date() |
|
|
|
groupIndex = sp.has('groupIndex') ? parseInt(sp.get('groupIndex')) : null |
|
|
|
groupIndex = sp.has('groupIndex') ? parseInt(sp.get('groupIndex')) : null |
|
|
|
|
|
|
|
tripId = sp.get('tripId') |
|
|
|
|
|
|
|
startId = sp.get('startId') |
|
|
|
|
|
|
|
stopId = sp.get('stopId') |
|
|
|
|
|
|
|
|
|
|
|
if (window.localStorage) { |
|
|
|
if (window.localStorage) { |
|
|
|
var oldRecent = localStorage.getItem('recent/view-train') |
|
|
|
var oldRecent = localStorage.getItem('recent/view-train') |
|
|
@ -543,8 +839,8 @@ window.addEventListener('load', function (e) { |
|
|
|
} |
|
|
|
} |
|
|
|
localStorage.setItem('recent/view-train', JSON.stringify({ |
|
|
|
localStorage.setItem('recent/view-train', JSON.stringify({ |
|
|
|
trainNumber: trainNumber, |
|
|
|
trainNumber: trainNumber, |
|
|
|
|
|
|
|
tripId: tripId, |
|
|
|
date: date.toISOString(), |
|
|
|
date: date.toISOString(), |
|
|
|
groupIndex: oldRecent && oldRecent.trainNumber === trainNumber ? oldRecent.groupIndex : undefined, |
|
|
|
|
|
|
|
$addDate: new Date().toISOString(), |
|
|
|
$addDate: new Date().toISOString(), |
|
|
|
})) |
|
|
|
})) |
|
|
|
} |
|
|
|
} |
|
|
@ -598,6 +894,13 @@ window.addEventListener('load', function (e) { |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('load-map-button').addEventListener('click', function (event) { |
|
|
|
|
|
|
|
event.preventDefault() |
|
|
|
|
|
|
|
event.target.textContent = 'Loading...' |
|
|
|
|
|
|
|
loadMap = true; |
|
|
|
|
|
|
|
refresh() |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
refresh() |
|
|
|
refresh() |
|
|
|
|
|
|
|
|
|
|
|
setInterval(function () { |
|
|
|
setInterval(function () { |
|
|
|