From 5be662f756540fff10a35cb5b1caa933a257e62e Mon Sep 17 00:00:00 2001 From: Jacek Kowalski <Jacek@jacekk.info> Date: Sat, 06 Jul 2019 00:01:22 +0000 Subject: [PATCH] Add search feature to the map --- map.js | 152 +++++++++++++++++++++++++++++++++++++++----------- lang_en.js | 4 + index.html | 2 map.html | 5 + lang_pl.js | 4 + 5 files changed, 128 insertions(+), 39 deletions(-) diff --git a/index.html b/index.html index 9c3db11..4b7b298 100644 --- a/index.html +++ b/index.html @@ -135,7 +135,7 @@ </div> </div> <script src="https://polyfill.io/v3/polyfill.min.js?features=Promise,XMLHttpRequest"></script> - <script type="text/javascript" src="lang_pl.js?v9" id="lang_script"></script> + <script type="text/javascript" src="lang_pl.js?v10" id="lang_script"></script> <script type="text/javascript" src="common.js?v10"></script> <script type="text/javascript" src="index.js?v8"></script> </body> diff --git a/lang_en.js b/lang_en.js index a9428b4..db691a6 100644 --- a/lang_en.js +++ b/lang_en.js @@ -9,6 +9,7 @@ action_expand: 'Expand', action_collapse: 'Collapse', + enter_query: 'Enter stop name or vehicle number:', enter_stop_name_to_begin: 'Enter the stop name to begin.', select_stop_click_go: 'Select the stop and click "Go".', select_stop_type: { @@ -61,7 +62,8 @@ }, show_on_map: 'Show on map', - select_feature: 'There is more than one feature here. Select the proper one:', + select_feature: 'More than one feature was found. Select the proper one:', + no_results: 'Nothing was found.', departures_for_stop: 'Click for stop departures (and not only this stop point).', departures_for_trams: 'Switch to tram departures.', departures_for_buses: 'Switch to bus departures.', diff --git a/lang_pl.js b/lang_pl.js index d6e280d..9682cd6 100644 --- a/lang_pl.js +++ b/lang_pl.js @@ -9,6 +9,7 @@ action_expand: 'Rozwiń', action_collapse: 'Zwiń', + enter_query: 'Wpisz nazwę przystanku lub numer pojazdu:', enter_stop_name_to_begin: 'Zacznij wpisywać nazwę przystanku.', select_stop_click_go: 'Wyierz przystanek i kliknij "Dalej".', select_stop_type: { @@ -61,7 +62,8 @@ }, show_on_map: 'Pokaż na mapie', - select_feature: 'W tym miejscu znajduje się więcej niż jeden element. Wybierz właściwy z listy:', + select_feature: 'Znaleziono więcej niż jeden element. Wybierz właściwy z listy:', + no_results: 'Nie udało się znaleźć pasujących elementów.', departures_for_stop: 'Kliknij, by zobaczyć odjazdy dla całego przystanku (a nie tylko peronu).', departures_for_trams: 'Przełącz na odjazdy tramwajów.', departures_for_buses: 'Przełącz na odjazdy autobusów.', diff --git a/map.html b/map.html index be0d733..351e1c4 100644 --- a/map.html +++ b/map.html @@ -13,14 +13,15 @@ <div id="title" class="ol-unselectable ol-control"><a href="/">TTSS Kraków</a></div> <div id="fail" class="ol-unselectable ol-control"><span></span> <span class="close">×</p></div> <div id="menu" class="ol-unselectable ol-control"> +<button id="find" type="button" title="Find"><span class="icon-zoom normal-icon reverse"></span></button> <button id="track" type="button" title="GPS"><span class="icon-loc reverse"></span></button> </div> </div> <div id="panel"></div> <script src="https://polyfill.io/v3/polyfill.min.js?features=Array.prototype.forEach,Array.prototype.includes,Array.prototype.map,Element.prototype.classList,Promise,String.prototype.startsWith,XMLHttpRequest,requestAnimationFrame"></script> <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v5.3.0/build/ol.js" integrity="sha384-iQkGyyH4ioz3m+maM3s9MX1Oq67mACa4B9Z3ovUv3Sv37LJ96fx3WnZfLoiC3Wfl" crossorigin="anonymous"></script> -<script tyle="text/javascript" src="lang_pl.js?v9" id="lang_script"></script> +<script tyle="text/javascript" src="lang_pl.js?v10" id="lang_script"></script> <script tyle="text/javascript" src="common.js?v10"></script> -<script tyle="text/javascript" src="map.js?v24"></script> +<script tyle="text/javascript" src="map.js?v25"></script> </body> </html> diff --git a/map.js b/map.js index 07f2361..bd9765b 100644 --- a/map.js +++ b/map.js @@ -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'); @@ -143,6 +144,80 @@ 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; + + 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); @@ -626,6 +701,41 @@ feature_clicked = feature; } +function listFeatures(features) { + 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 = ''; + } + 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 = []; @@ -638,40 +748,7 @@ 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; } @@ -720,6 +797,7 @@ } } + function hash() { if(ignore_hashchange) { ignore_hashchange = false; @@ -744,6 +822,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) { @@ -777,6 +858,7 @@ function init() { panel = new Panel(document.getElementById('panel')); + find = new Find(); route_source = new ol.source.Vector({ features: [], @@ -870,6 +952,8 @@ }); 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(), -- Gitblit v1.9.1