From ee953eef09cc090dc98a09038ab97be55875a2a5 Mon Sep 17 00:00:00 2001 From: Jacek Kowalski <Jacek@jacekk.info> Date: Mon, 18 Dec 2023 22:22:11 +0000 Subject: [PATCH] Update stop names --- map.js | 258 +++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 186 insertions(+), 72 deletions(-) diff --git a/map.js b/map.js index ff7d3a3..85542e9 100644 --- a/map.js +++ b/map.js @@ -1,4 +1,4 @@ -"use strict"; +'use strict'; var ttss_refresh = 10000; // 10 seconds var ttss_position_type = 'RAW'; @@ -20,7 +20,7 @@ var vehicles_info = {}; var stops_xhr = null; -var stops_ignored = ['131', '744']; +var stops_ignored = ['131', '744', '1263', '3039']; var stops_style = { 'sb': new ol.style.Style({ image: new ol.style.Circle({ @@ -70,6 +70,7 @@ var map = null; var panel = null; +var find = null; var fail_element = document.getElementById('fail'); var fail_text = document.querySelector('#fail span'); @@ -81,22 +82,27 @@ this._element = element; this._element.classList.add('panel'); - this._hide = addParaWithText(this._element, '▶'); + this._hide = addElementWithText(this._element, 'a', '▶'); this._hide.title = lang.action_collapse; this._hide.className = 'hide'; this._hide.addEventListener('click', this.toggleExpanded.bind(this)); - this._close = addParaWithText(this._element, '×'); + this._container = document.createElement('div'); + this._container.className = 'panel-container'; + + this._close = addElementWithText(this._container, 'a', '×'); this._close.title = lang.action_close; this._close.className = 'close'; this._close.addEventListener('click', this.close.bind(this)); this._content = document.createElement('div'); - this._element.appendChild(this._content); -}; + this._container.appendChild(this._content); + this._element.appendChild(this._container); +} Panel.prototype = { _element: null, _hide: null, + _container: null, _close: null, _content: null, @@ -143,6 +149,85 @@ 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); @@ -193,14 +278,15 @@ fill = '#05B'; } if(selected) { - fill = '#292'; + fill = '#922'; } - var image = '<svg xmlns="http://www.w3.org/2000/svg" height="30" width="20"><polygon points="10,0 20,23 0,23" style="fill:'+fill+';stroke:'+color_type+';stroke-width:3" /></svg>'; + var image = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="30"><polygon points="10,0 20,23 0,23" style="fill:'+fill+';stroke:'+color_type+';stroke-width:3"/></svg>'; vehicle.setStyle(new ol.style.Style({ image: new ol.style.Icon({ src: 'data:image/svg+xml;base64,' + btoa(image), + imgSize: [20,30], rotation: Math.PI * parseFloat(vehicle.get('heading') ? vehicle.get('heading') : 0) / 180.0, }), text: new ol.style.Text({ @@ -228,7 +314,6 @@ var feature, prefix; for(var i = 0; i < stops.length; i++) { - feature = null; if(stops[i].getId) { feature = stops[i]; } else { @@ -270,7 +355,7 @@ if(vehicle_feature) { vehicles_source[prefix].removeFeature(vehicle_feature); if(feature_clicked && feature_clicked.getId() === vehicle_feature.getId()) { - featureClicked(); + panel.close(); } } continue; @@ -278,7 +363,7 @@ var vehicle_name_space = vehicle.name.indexOf(' '); vehicle.line = vehicle.name.substr(0, vehicle_name_space); - vehicle.direction = vehicle.name.substr(vehicle_name_space+1); + vehicle.direction = normalizeName(vehicle.name.substr(vehicle_name_space+1)); if(special_directions[vehicle.direction]) { vehicle.line = special_directions[vehicle.direction]; } @@ -310,8 +395,9 @@ function updateStopSource(stops, prefix) { var source = stops_source[prefix]; var mapping = stops_mapping[prefix]; + var stop; for(var i = 0; i < stops.length; i++) { - var stop = stops[i]; + stop = stops[i]; if(stop.category == 'other') continue; if(stops_ignored.includes(stop.shortName)) continue; @@ -347,7 +433,7 @@ }).fail(fail_ajax); } -function vehiclePath(feature, tripId) { +function vehiclePath(feature) { if(path_xhr) path_xhr.abort(); var featureId = feature.getId(); @@ -401,7 +487,7 @@ for(var i = 0, il = all_departures.length; i < il; i++) { tr = document.createElement('tr'); addCellWithText(tr, all_departures[i].actualTime || all_departures[i].plannedTime); - addCellWithText(tr, all_departures[i].stop_seq_num + '. ' + all_departures[i].stop.name); + addCellWithText(tr, all_departures[i].stop_seq_num + '. ' + normalizeName(all_departures[i].stop.name)); if(i >= data.old.length) { stopsToMark.push('s' + ttss_type + all_departures[i].stop.id); @@ -446,7 +532,7 @@ for(var i = 0, il = all_departures.length; i < il; i++) { tr = document.createElement('tr'); addCellWithText(tr, all_departures[i].patternText); - dir_cell = addCellWithText(tr, all_departures[i].direction); + dir_cell = addCellWithText(tr, normalizeName(all_departures[i].direction)); vehicle = parseVehicle(all_departures[i].vehicleId); dir_cell.appendChild(displayVehicle(vehicle)); status = parseStatus(all_departures[i]); @@ -484,12 +570,9 @@ return; } - var coordinates = feature.getGeometry().getCoordinates(); - var div = document.createElement('div'); - var typeName; - var name = feature.get('name'); + var name = normalizeName(feature.get('name')); var additional; var table = document.createElement('table'); var thead = document.createElement('thead'); @@ -514,6 +597,8 @@ } // Vehicle else if(ttss_types.includes(type)) { + styleVehicle(feature, true); + var span = displayVehicle(feature.get('vehicle_type')); additional = document.createElement('p'); @@ -529,8 +614,6 @@ vehicleTable(feature, tbody); vehiclePath(feature); - - styleVehicle(feature, true); } // Stop or stop point else if(['s', 'p'].includes(type)) { @@ -586,7 +669,19 @@ loader.colSpan = thead.childNodes.length; addParaWithText(div, typeName).className = 'type'; - addParaWithText(div, name).className = 'name'; + + var nameElement = addParaWithText(div, name + ' '); + nameElement.className = 'name'; + + var showOnMapElement = addElementWithText(nameElement, 'a', lang.show_on_map); + var showOnMapFunction = function() { + setTimeout(function () {map.getView().animate({ + center: feature.getGeometry().getCoordinates(), + })}, 10); + }; + showOnMapElement.addEventListener('click', showOnMapFunction); + showOnMapElement.className = 'icon icon-pin'; + showOnMapElement.title = lang.show_on_map; if(additional) { div.appendChild(additional); @@ -598,10 +693,7 @@ window.location.hash = '#!' + feature.getId(); } - setTimeout(function () {map.getView().animate({ - center: feature.getGeometry().getCoordinates(), - }) }, 10); - + showOnMapFunction(); panel.show(div, function() { if(!ignore_hashchange) { @@ -620,6 +712,46 @@ 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 = []; @@ -628,43 +760,13 @@ if(feature.getId()) features.push(feature); }); + var feature = features[0]; + if(features.length > 1) { - featureClicked(); - - var div = document.createElement('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 = ''; - } - - addElementWithText(a, 'span', typeName).className = 'small'; - a.appendChild(document.createTextNode(' ')); - addElementWithText(a, 'span', feature.get('name')); - - div.appendChild(p); - } - - panel.show(div); - + panel.show(listFeatures(features)); return; } - var feature = features[0]; if(!feature) { stops_type.forEach(function(type) { if(stops_layer[type].getVisible()) { @@ -710,6 +812,7 @@ } } + function hash() { if(ignore_hashchange) { ignore_hashchange = false; @@ -734,6 +837,9 @@ 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) { @@ -767,6 +873,7 @@ function init() { panel = new Panel(document.getElementById('panel')); + find = new Find(); route_source = new ol.source.Vector({ features: [], @@ -804,11 +911,10 @@ }); vehicles_layer[type] = new ol.layer.Vector({ source: vehicles_source[type], + renderMode: 'image', }); vehicles_last_update[type] = 0; }); - - ol.style.IconImageCache.shared.setSize(512); geolocation_feature = new ol.Feature({ name: '', @@ -828,9 +934,9 @@ 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'}); @@ -855,13 +961,17 @@ 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({ - source: new ol.source.OSM(), + source: new ol.source.OSM({ + url: 'https://tiles.ttss.pl/{z}/{x}/{y}.png', + }), }), route_layer, geolocation_layer, @@ -893,7 +1003,7 @@ element: fail_element, }), new ol.control.Control({ - element: document.getElementById('track'), + element: document.getElementById('menu'), }), ]), loadTilesWhileAnimating: false, @@ -914,7 +1024,7 @@ }); // Change layer visibility on zoom - var change_resolution = function(e) { + var change_resolution = function() { stops_type.forEach(function(type) { if(type.startsWith('p')) { stops_layer[type].setVisible(map.getView().getZoom() >= 16); @@ -939,11 +1049,15 @@ window.addEventListener('hashchange', hash); setTimeout(function() { - if(trams_xhr) trams_xhr.abort(); - if(trams_timer) clearTimeout(trams_timer); - if(buses_xhr) buses_xhr.abort(); - if(buses_timer) clearTimeout(buses_timer); - + ttss_types.forEach(function(type) { + if(vehicles_xhr[type]) { + vehicles_xhr[type].abort(); + } + if(vehicles_timer[type]) { + clearTimeout(vehicles_timer[type]); + } + }); + fail(lang.error_refresh); }, 1800000); } -- Gitblit v1.9.1