|  |  |  | 
|---|
|  |  |  | var vehicles_info = {}; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | var stops_xhr = null; | 
|---|
|  |  |  | var stops_ignored = ['131', '744', '1263']; | 
|---|
|  |  |  | var stops_ignored = ['131', '744', '1263', '3039']; | 
|---|
|  |  |  | var stops_style = { | 
|---|
|  |  |  | 'sb': new ol.style.Style({ | 
|---|
|  |  |  | image: new ol.style.Circle({ | 
|---|
|  |  |  | 
|---|
|  |  |  | var map = null; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | var panel = null; | 
|---|
|  |  |  | var find = null; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | var fail_element = document.getElementById('fail'); | 
|---|
|  |  |  | var fail_text = document.querySelector('#fail span'); | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | this._content = document.createElement('div'); | 
|---|
|  |  |  | this._element.appendChild(this._content); | 
|---|
|  |  |  | }; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Panel.prototype = { | 
|---|
|  |  |  | _element: null, | 
|---|
|  |  |  | _hide: null, | 
|---|
|  |  |  | 
|---|
|  |  |  | this._element.classList.remove('enabled'); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | }; | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | function Find() { | 
|---|
|  |  |  | this.div = document.createElement('div'); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | this.form = document.createElement('form'); | 
|---|
|  |  |  | this.div.appendChild(this.form); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | var para = addParaWithText(this.form, lang.enter_query); | 
|---|
|  |  |  | para.appendChild(document.createElement('br')); | 
|---|
|  |  |  | this.input = document.createElement('input'); | 
|---|
|  |  |  | this.input.type = 'text'; | 
|---|
|  |  |  | this.input.style.width = '80%'; | 
|---|
|  |  |  | para.appendChild(this.input); | 
|---|
|  |  |  | para.appendChild(document.createElement('hr')); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | this.results = document.createElement('div'); | 
|---|
|  |  |  | this.div.appendChild(this.results); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | this.input.addEventListener('keyup', this.findDelay.bind(this)); | 
|---|
|  |  |  | this.form.addEventListener('submit', this.findDelay.bind(this)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Find.prototype = { | 
|---|
|  |  |  | query: '', | 
|---|
|  |  |  | timeout: null, | 
|---|
|  |  |  |  | 
|---|
|  |  |  | div: null, | 
|---|
|  |  |  | form: null, | 
|---|
|  |  |  | input: null, | 
|---|
|  |  |  | results: null, | 
|---|
|  |  |  |  | 
|---|
|  |  |  | find: function() { | 
|---|
|  |  |  | var query = this.input.value.toUpperCase(); | 
|---|
|  |  |  | if(query === this.query) return; | 
|---|
|  |  |  | this.query = query; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if(query === '') { | 
|---|
|  |  |  | deleteChildren(this.results); | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | var features = []; | 
|---|
|  |  |  | stops_type.forEach(function(stop_type) { | 
|---|
|  |  |  | if(stop_type.substr(0,1) === 'p') return; | 
|---|
|  |  |  | stops_source[stop_type].forEachFeature(function(feature) { | 
|---|
|  |  |  | if(feature.get('name').toUpperCase().indexOf(query) > -1) { | 
|---|
|  |  |  | features.push(feature); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ttss_types.forEach(function(ttss_type) { | 
|---|
|  |  |  | vehicles_source[ttss_type].forEachFeature(function(feature) { | 
|---|
|  |  |  | if(feature.get('vehicle_type') && feature.get('vehicle_type').num.indexOf(query) > -1) { | 
|---|
|  |  |  | features.push(feature); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | deleteChildren(this.results); | 
|---|
|  |  |  | this.results.appendChild(listFeatures(features)); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | findDelay: function(e) { | 
|---|
|  |  |  | e.preventDefault(); | 
|---|
|  |  |  | if(this.timeout) clearTimeout(this.timeout); | 
|---|
|  |  |  | this.timeout = setTimeout(this.find.bind(this), 100); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | open: function(panel) { | 
|---|
|  |  |  | ignore_hashchange = true; | 
|---|
|  |  |  | window.location.hash = '#!f'; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | panel.show(this.div, this.close.bind(this)); | 
|---|
|  |  |  | this.input.focus(); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | close: function() { | 
|---|
|  |  |  | if(this.timeout) clearTimeout(this.timeout); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | }; | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | function fail(msg) { | 
|---|
|  |  |  | setText(fail_text, msg); | 
|---|
|  |  |  | 
|---|
|  |  |  | if(vehicle_feature) { | 
|---|
|  |  |  | vehicles_source[prefix].removeFeature(vehicle_feature); | 
|---|
|  |  |  | if(feature_clicked && feature_clicked.getId() === vehicle_feature.getId()) { | 
|---|
|  |  |  | featureClicked(); | 
|---|
|  |  |  | panel.close(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // Vehicle | 
|---|
|  |  |  | else if(ttss_types.includes(type)) { | 
|---|
|  |  |  | styleVehicle(feature, true); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | var span = displayVehicle(feature.get('vehicle_type')); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | additional = document.createElement('p'); | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | vehicleTable(feature, tbody); | 
|---|
|  |  |  | vehiclePath(feature); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | styleVehicle(feature, true); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // Stop or stop point | 
|---|
|  |  |  | else if(['s', 'p'].includes(type)) { | 
|---|
|  |  |  | 
|---|
|  |  |  | })}, 10); | 
|---|
|  |  |  | }; | 
|---|
|  |  |  | showOnMapElement.addEventListener('click', showOnMapFunction); | 
|---|
|  |  |  | showOnMapElement.className = 'icon-zoom pad-left-icon'; | 
|---|
|  |  |  | showOnMapElement.className = 'icon-pin addon-icon'; | 
|---|
|  |  |  | showOnMapElement.title = lang.show_on_map; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if(additional) { | 
|---|
|  |  |  | 
|---|
|  |  |  | feature_clicked = feature; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | function listFeatures(features) { | 
|---|
|  |  |  | var div = document.createElement('div'); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if(features.length === 0) { | 
|---|
|  |  |  | addParaWithText(div, lang.no_results); | 
|---|
|  |  |  | return div; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | addParaWithText(div, lang.select_feature); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | var feature, p, a, full_type, typeName; | 
|---|
|  |  |  | for(var i = 0; i < features.length; i++) { | 
|---|
|  |  |  | feature = features[i]; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | p = document.createElement('p'); | 
|---|
|  |  |  | a = document.createElement('a'); | 
|---|
|  |  |  | p.appendChild(a); | 
|---|
|  |  |  | a.addEventListener('click', function(feature) { return function() { | 
|---|
|  |  |  | featureClicked(feature); | 
|---|
|  |  |  | }}(feature)); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | full_type = feature.getId().match(/^[a-z]+/)[0]; | 
|---|
|  |  |  | typeName = lang.types[full_type]; | 
|---|
|  |  |  | if(typeof typeName === 'undefined') { | 
|---|
|  |  |  | typeName = ''; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(feature.get('vehicle_type')) { | 
|---|
|  |  |  | typeName += ' ' + feature.get('vehicle_type').num; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | addElementWithText(a, 'span', typeName).className = 'small'; | 
|---|
|  |  |  | a.appendChild(document.createTextNode(' ')); | 
|---|
|  |  |  | addElementWithText(a, 'span', normalizeName(feature.get('name'))); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | div.appendChild(p); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return div; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | function mapClicked(e) { | 
|---|
|  |  |  | var point = e.coordinate; | 
|---|
|  |  |  | var features = []; | 
|---|
|  |  |  | 
|---|
|  |  |  | var feature = features[0]; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if(features.length > 1) { | 
|---|
|  |  |  | featureClicked(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | var div = document.createElement('div'); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | addParaWithText(div, lang.select_feature); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | var p, a, full_type, typeName; | 
|---|
|  |  |  | for(var i = 0; i < features.length; i++) { | 
|---|
|  |  |  | feature = features[i]; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | p = document.createElement('p'); | 
|---|
|  |  |  | a = document.createElement('a'); | 
|---|
|  |  |  | p.appendChild(a); | 
|---|
|  |  |  | a.addEventListener('click', function(feature) { return function() { | 
|---|
|  |  |  | featureClicked(feature); | 
|---|
|  |  |  | }}(feature)); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | full_type = feature.getId().match(/^[a-z]+/)[0]; | 
|---|
|  |  |  | typeName = lang.types[full_type]; | 
|---|
|  |  |  | if(typeof typeName === 'undefined') { | 
|---|
|  |  |  | typeName = ''; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(feature.get('vehicle_type')) { | 
|---|
|  |  |  | typeName += ' ' + feature.get('vehicle_type').num; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | addElementWithText(a, 'span', typeName).className = 'small'; | 
|---|
|  |  |  | a.appendChild(document.createTextNode(' ')); | 
|---|
|  |  |  | addElementWithText(a, 'span', normalizeName(feature.get('name'))); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | div.appendChild(p); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | panel.show(div); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | panel.show(listFeatures(features)); | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | function hash() { | 
|---|
|  |  |  | if(ignore_hashchange) { | 
|---|
|  |  |  | ignore_hashchange = false; | 
|---|
|  |  |  | 
|---|
|  |  |  | stopId = window.location.hash.substr(2,1) + 't' + window.location.hash.substr(3); | 
|---|
|  |  |  | } else if(window.location.hash.match(/^#![sp][tb]-?[0-9]+$/)) { | 
|---|
|  |  |  | stopId = window.location.hash.substr(2); | 
|---|
|  |  |  | } else if(window.location.hash.match(/^#!f$/)) { | 
|---|
|  |  |  | find.open(panel); | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if(vehicleId) { | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | function init() { | 
|---|
|  |  |  | panel = new Panel(document.getElementById('panel')); | 
|---|
|  |  |  | find = new Find(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | route_source = new ol.source.Vector({ | 
|---|
|  |  |  | features: [], | 
|---|
|  |  |  | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | vehicles_layer[type] = new ol.layer.Vector({ | 
|---|
|  |  |  | source: vehicles_source[type], | 
|---|
|  |  |  | renderMode: 'image', | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | vehicles_last_update[type] = 0; | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | 
|---|
|  |  |  | geolocation_layer = new ol.layer.Vector({ | 
|---|
|  |  |  | source: geolocation_source, | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | geolocation_button = document.querySelector('#track button'); | 
|---|
|  |  |  | geolocation_button = document.querySelector('#track'); | 
|---|
|  |  |  | if(!navigator.geolocation) { | 
|---|
|  |  |  | geolocation_button.classList.add('hidden'); | 
|---|
|  |  |  | geolocation_button.remove(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | geolocation = new ol.Geolocation({projection: 'EPSG:3857'}); | 
|---|
|  |  |  | 
|---|
|  |  |  | geolocation.on('error', function(error) { | 
|---|
|  |  |  | fail(lang.error_location + ' ' + error.message); | 
|---|
|  |  |  | trackingStop(); | 
|---|
|  |  |  | geolocation_button.classList.add('hidden'); | 
|---|
|  |  |  | geolocation_button.remove(); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | geolocation_button.addEventListener('click', trackingToggle); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | document.getElementById('find').addEventListener('click', find.open.bind(find, panel)); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | var layers = [ | 
|---|
|  |  |  | new ol.layer.Tile({ | 
|---|
|  |  |  | 
|---|
|  |  |  | element: fail_element, | 
|---|
|  |  |  | }), | 
|---|
|  |  |  | new ol.control.Control({ | 
|---|
|  |  |  | element: document.getElementById('track'), | 
|---|
|  |  |  | element: document.getElementById('menu'), | 
|---|
|  |  |  | }), | 
|---|
|  |  |  | ]), | 
|---|
|  |  |  | loadTilesWhileAnimating: false, | 
|---|