only render Elements in renderData
This commit is contained in:
parent
dc84436346
commit
7673265167
1 changed files with 167 additions and 141 deletions
308
elevators.js
308
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", '<dl class="osmTags">loading...</dl>');
|
||||
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 += `<div><dt><span data-icon="location" class="size-l"></span>Link zur Karte</dt><dd><a href="https://www.openstreetmap.org/node/${nodeId}" target="_blank">
|
||||
Auf Karte anzeigen
|
||||
</a></dd></div>`;
|
||||
if (tags.hasOwnProperty('description')) {
|
||||
osmTemplate += `<div><dt><span data-icon="info" class="size-l"></span>Beschreibung</dt><dd>${tags['description']}</dd></div>`;
|
||||
}
|
||||
if (tags.hasOwnProperty('level')) {
|
||||
osmTemplate += `<div><dt><span data-icon="up-down" class="size-l"></span>Ebenen</dt><dd>${tags['level'].split(';').sort().join(', ')}</dd></div>`;
|
||||
}
|
||||
if (tags.hasOwnProperty('wheelchair')) {
|
||||
osmTemplate += `<div><dt><span data-icon="wheelchair" class="size-l"></span>Rollstühle</dt><dd>${tags['wheelchair'] === 'yes' ? 'Ja' : 'Nein'}</dd></div>`;
|
||||
}
|
||||
if (tags.hasOwnProperty('bicycle')) {
|
||||
osmTemplate += `<div><dt><span data-icon="bicycle" class="size-l"></span>Fahrräder</dt><dd>${tags['bicycle'] === 'yes' ? 'Ja' : 'Nein'}</dd></div>`;
|
||||
}
|
||||
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 = '<div class="lineList">Linien: ';
|
||||
for (const line of elevator.lines) {
|
||||
linesTemplate += `<span data-type="${line.type}" data-line="${line.line}" class="lineChip">${line.line}</span>`;
|
||||
|
@ -262,16 +257,45 @@ function renderData() {
|
|||
}
|
||||
levelsTemplate += '</ol>';
|
||||
|
||||
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 = '<dl>';
|
||||
osmTemplate += `<div><dt><span data-icon="location" class="size-l"></span>Link zur Karte</dt><dd><a href="https://www.openstreetmap.org/node/${elevator.osmNodeId}" target="_blank">
|
||||
Auf Karte anzeigen
|
||||
</a></dd></div>`;
|
||||
if (tags.hasOwnProperty('description')) {
|
||||
osmTemplate += `<div><dt><span data-icon="info" class="size-l"></span>Beschreibung</dt><dd>${tags['description']}</dd></div>`;
|
||||
}
|
||||
if (tags.hasOwnProperty('level')) {
|
||||
osmTemplate += `<div><dt><span data-icon="up-down" class="size-l"></span>Ebenen</dt><dd>${tags['level'].split(';').sort().join(', ')}</dd></div>`;
|
||||
}
|
||||
if (tags.hasOwnProperty('wheelchair')) {
|
||||
osmTemplate += `<div><dt><span data-icon="wheelchair" class="size-l"></span>Rollstühle</dt><dd>${tags['wheelchair'] === 'yes' ? 'Ja' : 'Nein'}</dd></div>`;
|
||||
}
|
||||
if (tags.hasOwnProperty('bicycle')) {
|
||||
osmTemplate += `<div><dt><span data-icon="bicycle" class="size-l"></span>Fahrräder</dt><dd>${tags['bicycle'] === 'yes' ? 'Ja' : 'Nein'}</dd></div>`;
|
||||
}
|
||||
|
||||
osmTemplate += '<dl>';
|
||||
}
|
||||
} else {
|
||||
osmTemplate = 'keine Daten';
|
||||
}
|
||||
} else {
|
||||
osmTemplate = 'keine Daten';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
previewTemplate += `<span data-icon="${elevator.working || elevator.stateUnavailable ? 'elevator' : 'elevator-slash'}"
|
||||
class="size-l ${elevator.working ? 'text-green' : elevator.stateUnavailable ? 'text-orange' : 'text-red'}"></span>`
|
||||
|
||||
if (elevator.stateUnavailable) {
|
||||
stationState.unavailable++;
|
||||
} else if (elevator.working) {
|
||||
stationState.working++;
|
||||
} else {
|
||||
stationState.outOfOrder++;
|
||||
}
|
||||
|
||||
elevatorsTemplate += `<li class="elevator">
|
||||
<span data-icon="${elevator.working || elevator.stateUnavailable ? 'elevator' : 'elevator-slash'}"
|
||||
|
@ -311,6 +335,7 @@ function renderData() {
|
|||
${elevator.lines.length ? `${linesTemplate}` : ''}
|
||||
<div class="osm" data-nodeid="${elevator.osmNodeId}">
|
||||
<h4>Daten von OpenStreetMap</h4>
|
||||
${osmTemplate}
|
||||
</div>
|
||||
</div>
|
||||
</li>`;
|
||||
|
@ -319,14 +344,14 @@ function renderData() {
|
|||
const template = `<li class="station" id="station_${stationIndex}">
|
||||
<div class="stationSummary">
|
||||
<div class="typeList">
|
||||
${Array.from(stationTypes).sort().map(t => `<span class="typeChip" data-type="${t}">${t}</span>`).join('')}
|
||||
${station.types.sort().map(t => `<span class="typeChip" data-type="${t}">${t}</span>`).join('')}
|
||||
</div>
|
||||
<div class="stationTitle">
|
||||
<h3>${stationName}</h3>
|
||||
<h3>${station.name}</h3>
|
||||
<div class="elevator-preview" role="img"
|
||||
aria-label="${stationState.working ? `${stationState.working} ${stationState.working > 1 ? 'Aufzüge sind' : 'Aufzug ist'} funktionstüchtig.` : ''}
|
||||
${stationState.outOfOrder ? `${stationState.outOfOrder} ${stationState.outOfOrder > 1 ? 'Aufzüge sind' : 'Aufzug ist'} außer Betrieb.` : ''}
|
||||
${stationState.unavailable ? `Bei ${stationState.unavailable} ${stationState.unavailable > 1 ? 'Aufzügen' : 'Aufzug'} ist der Funktionsstatus unbekannt.` : ''}">
|
||||
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}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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)
|
||||
filterData()
|
Loading…
Add table
Add a link
Reference in a new issue