diff --git a/elevators.js b/elevators.js
index 34b9713..912f1ea 100644
--- a/elevators.js
+++ b/elevators.js
@@ -1,3 +1,11 @@
+const internalData = {
+ lastUpdate: 0,
+ stations: [],
+};
+let geolocationPermission = false;
+let geolocation = [null, null];
+
+
Object.defineProperty(String.prototype, 'capitalize', {
value: function () {
return this.charAt(0).toUpperCase() + this.toLowerCase().slice(1);
@@ -9,7 +17,90 @@ async function loadElevators() {
const res = await fetch('https://www.hvv.de/elevators', {referrer: ""});
const data = await res.json();
- localStorage.setItem("elevator_data", JSON.stringify(data));
+
+ const stations = data['stations'];
+ stations.sort(sortStations)
+ internalData.lastUpdate = new Date(data['lastUpdate']);
+
+ let stationIndex = 0;
+
+ for (const station of stations) {
+ const stationName = station['mainSubStation']['stationName'];
+ const lines = new Set();
+ const elevators = [];
+ for (const elevatorKey of Object.keys(station.elevators)) {
+ const elevatorApi = station.elevators[elevatorKey];
+ const elevatorLines = [];
+ for (let line of elevatorApi.lines) {
+ line = line.replace(/[()]/g, "");
+ lines.add(line);
+ elevatorLines.push({
+ line: line,
+ type: getType(line),
+ });
+ }
+
+ // try to detect levels from description
+ let levels = [];
+ if (elevatorApi.description.search('<->') >= 0) {
+ levels = elevatorApi.description.split('<->').map(level => level.trim());
+ } else if (elevatorApi.description.search('<>') >= 0) {
+ levels = elevatorApi.description.split('<>').map(level => level.trim());
+ } else if (elevatorApi.description.search('/ ') >= 0) {
+ levels = elevatorApi.description.split('/ ').map(level => level.trim());
+ }
+
+ const elevator = {
+ working: elevatorApi['state'] === 1,
+ stateUnavailable: elevatorApi['state'] === -1,
+ dimensions: {
+ width: elevatorApi['cabinWidth'],
+ length: elevatorApi['cabinLength'],
+ door: elevatorApi['doorWidth'],
+ },
+ description: elevatorApi['description'],
+ label: elevatorApi['label'],
+ type: elevatorApi['type'].replace('_', ' ').capitalize(),
+ braille: elevatorApi['tasterType'] === 'UNBEKANNT' ? -1 : elevatorApi['tasterType'] === 'KOMBI' || elevatorApi['tasterType'] === 'BRAILLE',
+ speaker: elevatorApi['tasterType'] === 'UNBEKANNT' ? -1 : elevatorApi['tasterType'] === 'KOMBI',
+ lines: elevatorLines,
+ levels: levels,
+ instCause: elevatorApi['instCause'],
+ osmNodeId: elevatorApi['osmId'],
+ }
+
+ elevators.push(elevator);
+ }
+
+ let stationState = {
+ unavailable: 0,
+ working: 0,
+ outOfOrder: 0,
+ }
+
+ for (const elevator of elevators) {
+ if (elevator.stateUnavailable) {
+ stationState.unavailable++;
+ } else if (elevator.working) {
+ stationState.working++;
+ } else {
+ stationState.outOfOrder++;
+ }
+ }
+
+ const stationLines = Array.from(lines);
+ const stationTypes = Array.from(getTypes(stationLines));
+
+ internalData.stations[stationIndex++] = {
+ name: stationName,
+ state: stationState,
+ lines: stationLines,
+ types: stationTypes,
+ elevators: elevators,
+ }
+ }
+
+ localStorage.setItem("internal_data", JSON.stringify(internalData));
}
const dateTimeStyle = new Intl.DateTimeFormat('de-DE', {
@@ -18,19 +109,11 @@ const dateTimeStyle = new Intl.DateTimeFormat('de-DE', {
timeZone: 'Europe/Berlin',
})
-const internalData = []
-let geolocationPermission = false;
-let geolocation = [null, null];
-
async function loadOsmData() {
- const elevatorNodes = document.querySelectorAll('.elevator');
const nodeIdList = [];
- for (const elevator of elevatorNodes) {
- const osmContainer = elevator.querySelector('.osm');
- const nodeId = osmContainer.dataset.nodeid;
- if (nodeId > 0) {
- elevator.querySelector('.osm').insertAdjacentHTML("beforeend", '
loading...
');
- nodeIdList.push(nodeId)
+ for (const station of internalData.stations) {
+ for (const elevator of station.elevators) {
+ nodeIdList.push(elevator.osmNodeId)
}
}
@@ -39,44 +122,7 @@ async function loadOsmData() {
if (!osmJson.hasOwnProperty('elements')) return;
- for (const elevator of elevatorNodes) {
- const tagContainer = elevator.querySelector('.osmTags');
- const nodeId = elevator.querySelector('.osm').dataset.nodeid;
-
- const nodes = osmJson.elements.filter(node => node.id === parseInt(nodeId))
- if (!nodes.length) {
- tagContainer.innerHTML = 'keine Daten';
- continue;
- }
- const nodeInfo = nodes[0];
-
- if (!nodeInfo.hasOwnProperty('tags')) {
- tagContainer.innerHTML = 'keine Daten';
- continue;
- }
- const tags = nodeInfo['tags'];
-
- if (tags['highway'] === 'elevator') {
- let osmTemplate = '';
- osmTemplate += ``;
- if (tags.hasOwnProperty('description')) {
- osmTemplate += `Beschreibung${tags['description']}`;
- }
- if (tags.hasOwnProperty('level')) {
- osmTemplate += `Ebenen${tags['level'].split(';').sort().join(', ')}`;
- }
- if (tags.hasOwnProperty('wheelchair')) {
- osmTemplate += `Rollstühle${tags['wheelchair'] === 'yes' ? 'Ja' : 'Nein'}`;
- }
- if (tags.hasOwnProperty('bicycle')) {
- osmTemplate += `Fahrräder${tags['bicycle'] === 'yes' ? 'Ja' : 'Nein'}`;
- }
- tagContainer.innerHTML = ''; // clear loading state
- tagContainer.insertAdjacentHTML('beforeend', osmTemplate);
- }
- }
+ localStorage.setItem("osm_data", JSON.stringify(osmJson));
}
function distance([lat1, lon1], [lat2, lon2]) {
@@ -171,85 +217,34 @@ function getTypes(lines) {
}
function renderData() {
- const data = JSON.parse(localStorage.getItem("elevator_data"));
+ const ls = JSON.parse(localStorage.getItem("internal_data"));
+ if (!ls) return;
+ internalData.lastUpdate = ls['lastUpdate'];
+ internalData.stations = ls['stations'];
+ const osmData = JSON.parse(localStorage.getItem("osm_data"));
- if (!data) {
+ if (!internalData || !internalData.stations.length) {
console.error('No Data available!')
return;
}
- let stations = data.stations;
- stations.sort(sortStations)
- const date = new Date(data.lastUpdate);
-
document.querySelector('#loadElevators').innerHTML = 'Daten aktualisieren';
- const listContainer = document.querySelector('#stationList');
const dateContainer = document.querySelector('#lastUpdated');
+ dateContainer.innerHTML = dateTimeStyle.format(new Date(internalData.lastUpdate));
- dateContainer.innerHTML = dateTimeStyle.format(date);
-
- let stationIndex = 0;
-
+ const listContainer = document.querySelector('#stationList');
//clear list before update
listContainer.innerHTML = '';
- for (const station of stations) {
- const stationName = station.mainSubStation.stationName;
- const lines = new Set();
- const elevators = [];
- for (const elevatorKey of Object.keys(station.elevators)) {
- const elevatorApi = station.elevators[elevatorKey];
- const elevatorLines = [];
- for (let line of elevatorApi.lines) {
- line = line.replace(/[\(\)]/g, "");
- lines.add(line);
- elevatorLines.push({
- line: line,
- type: getType(line),
- });
- }
- // try to detect levels from description
- let levels = [];
- if (elevatorApi.description.search('<->') >= 0) {
- levels = elevatorApi.description.split('<->').map(level => level.trim());
- } else if (elevatorApi.description.search('<>') >= 0) {
- levels = elevatorApi.description.split('<>').map(level => level.trim());
- } else if (elevatorApi.description.search('/ ') >= 0) {
- levels = elevatorApi.description.split('/ ').map(level => level.trim());
- }
+ const stations = internalData['stations'];
- const elevator = {
- working: elevatorApi['state'] === 1,
- stateUnavailable: elevatorApi['state'] === -1,
- dimensions: {
- width: elevatorApi['cabinWidth'],
- length: elevatorApi['cabinLength'],
- door: elevatorApi['doorWidth'],
- },
- description: elevatorApi['description'],
- label: elevatorApi['label'],
- type: elevatorApi['type'].replace('_', ' ').capitalize(),
- braille: elevatorApi['tasterType'] === 'UNBEKANNT' ? -1 : elevatorApi['tasterType'] === 'KOMBI' || elevatorApi['tasterType'] === 'BRAILLE',
- speaker: elevatorApi['tasterType'] === 'UNBEKANNT' ? -1 : elevatorApi['tasterType'] === 'KOMBI',
- lines: elevatorLines,
- levels: levels,
- instCause: elevatorApi['instCause'],
- osmNodeId: elevatorApi['osmId'],
- }
-
- elevators.push(elevator);
- }
-
- const stationTypes = getTypes(Array.from(lines));
+ for (const stationIndex in stations) {
+ const station = stations[stationIndex];
let elevatorsTemplate = '';
let previewTemplate = '';
- let stationState = {
- unavailable: 0,
- working: 0,
- outOfOrder: 0,
- }
- for (const elevator of elevators) {
+
+ for (const elevator of station.elevators) {
let linesTemplate = 'Linien: ';
for (const line of elevator.lines) {
linesTemplate += `
${line.line}`;
@@ -262,16 +257,45 @@ function renderData() {
}
levelsTemplate += '';
+ let osmTemplate = '';
+ if (osmData) {
+ const nodes = osmData.elements.filter(node => node.id === elevator.osmNodeId)
+ if (nodes.length) {
+ const nodeInfo = nodes[0];
+ if (nodeInfo.hasOwnProperty('tags')) {
+ const tags = nodeInfo['tags'];
+ if (tags['highway'] === 'elevator') {
+ osmTemplate = '
';
+ osmTemplate += ``;
+ if (tags.hasOwnProperty('description')) {
+ osmTemplate += `- Beschreibung
- ${tags['description']}
`;
+ }
+ if (tags.hasOwnProperty('level')) {
+ osmTemplate += `- Ebenen
- ${tags['level'].split(';').sort().join(', ')}
`;
+ }
+ if (tags.hasOwnProperty('wheelchair')) {
+ osmTemplate += `- Rollstühle
- ${tags['wheelchair'] === 'yes' ? 'Ja' : 'Nein'}
`;
+ }
+ if (tags.hasOwnProperty('bicycle')) {
+ osmTemplate += `- Fahrräder
- ${tags['bicycle'] === 'yes' ? 'Ja' : 'Nein'}
`;
+ }
+
+ osmTemplate += '';
+ }
+ } else {
+ osmTemplate = 'keine Daten';
+ }
+ } else {
+ osmTemplate = 'keine Daten';
+ }
+ }
+
+
previewTemplate += ``
- if (elevator.stateUnavailable) {
- stationState.unavailable++;
- } else if (elevator.working) {
- stationState.working++;
- } else {
- stationState.outOfOrder++;
- }
elevatorsTemplate += `
Daten von OpenStreetMap
+ ${osmTemplate}
`;
@@ -319,14 +344,14 @@ function renderData() {
const template = `
- ${Array.from(stationTypes).sort().map(t => `${t}`).join('')}
+ ${station.types.sort().map(t => `${t}`).join('')}
-
${stationName}
+
${station.name}
+ aria-label="${station.state.working ? `${station.state.working} ${station.state.working > 1 ? 'Aufzüge sind' : 'Aufzug ist'} funktionstüchtig.` : ''}
+${station.state.outOfOrder ? `${station.state.outOfOrder} ${station.state.outOfOrder > 1 ? 'Aufzüge sind' : 'Aufzug ist'} außer Betrieb.` : ''}
+${station.state.unavailable ? `Bei ${station.state.unavailable} ${station.state.unavailable > 1 ? 'Aufzügen' : 'Aufzug'} ist der Funktionsstatus unbekannt.` : ''}">
${previewTemplate}
@@ -349,38 +374,39 @@ ${stationState.unavailable ? `Bei ${stationState.unavailable} ${stationState.una
// .addEventListener('click', () => toggleElevatorList(stationId))
// }());
-
- internalData[stationIndex++] = {
- name: stationName,
- state: stationState,
- elevators: elevators,
- }
}
}
document.querySelector('#loadElevators')
.addEventListener('click', (e) => {
- loadElevators().then(() => renderData());
+ loadElevators().then(() => {
+ renderData();
+ filterData();
+ });
})
document.querySelector('#loadOSM')
.addEventListener('click', (e) => {
- loadOsmData();
+ loadOsmData().then(() => {
+ renderData();
+ });
})
renderData();
-function filterData(searchString) {
- for (const stationIndex in internalData) {
- const matches = internalData[stationIndex].name.toLowerCase().search(searchString.toLowerCase()) >= 0;
- document.querySelector(`#station_${stationIndex}`).classList.toggle('hidden', !matches);
-
+function filterData() {
+ const searchString = document.querySelector('#searchStation').value;
+ if (internalData) {
+ for (const stationIndex in internalData.stations) {
+ const matches = internalData.stations[stationIndex].name.toLowerCase().search(searchString.toLowerCase()) >= 0;
+ document.querySelector(`#station_${stationIndex}`).classList.toggle('hidden', !matches);
+ }
}
}
document.querySelector('#searchStation').addEventListener('input', (e) => {
- filterData(e.target.value);
+ filterData();
})
-filterData(document.querySelector('#searchStation').value)
\ No newline at end of file
+filterData()
\ No newline at end of file