Improved www.ttss.krakow.pl
2 files added
1 files renamed
6 files modified
259 ■■■■ changed files
icons/loc.svg 1 ●●●● patch | view | raw | blame | history
icons/pin.svg 1 ●●●● patch | view | raw | blame | history
icons/zoom.svg 2 ●●● patch | view | raw | blame | history
index.html 2 ●●● patch | view | raw | blame | history
lang_en.js 4 ●●● patch | view | raw | blame | history
lang_pl.js 4 ●●● patch | view | raw | blame | history
map.css 62 ●●●●● patch | view | raw | blame | history
map.html 18 ●●●●● patch | view | raw | blame | history
map.js 165 ●●●● patch | view | raw | blame | history
icons/loc.svg
New file
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80"><style>*{stroke:black;stroke-width:5;fill:none}</style><circle cx="40" cy="40" r="25"></circle><circle cx="40" cy="40" r="10" style="fill:black;"></circle><line x1="40" y1="15" x2="40" y2="0"></line><line x1="65" y1="40" x2="80" y2="40"></line><line x1="40" y1="65" x2="40" y2="80"></line><line x1="15" y1="40" x2="0" y2="40"></line></svg>
icons/pin.svg
New file
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64"><path d="M32,64L14.1855,29.0909A20,20 0 1 1 49.8145,29.0909ZM42,20A10,10 0 0 0 22,20A10,10 0 0 0 42,20"/></svg>
icons/zoom.svg
File was renamed from zoom.svg
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="490" height="490"><path fill="none" stroke="#000" stroke-width="36" stroke-linecap="round" d="m280,278a153,153 0 1,0-2,2l170,170m-91-117 110,110-26,26-110-110"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="490" height="490"><path fill="none" stroke="#000" stroke-width="36" stroke-linecap="round" d="m280,278a153,153 0 1,0-2,2l170,170m-91-117 110,110-26,26-110-110"/></svg>
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>
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.',
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.',
map.css
@@ -5,7 +5,7 @@
}
#map {
    position: absolute;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
@@ -28,7 +28,7 @@
    
    transition: right .4s, width .4s;
    
    position: absolute;
    position: fixed;
    width: 350px;
    right: -365px;
    top: 0;
@@ -135,25 +135,44 @@
    float: right;
}
.pad-left-icon {
.addon-icon {
    margin-left: 0.2rem;
}
.icon-zoom {
.normal-icon, .addon-icon {
    font-size: 1rem;
}
.icon, .icon-loc, .icon-pin, .icon-zoom {
    display: inline-block;
    height: 1rem;
    width: 1rem;
    height: 1em;
    width: 1em;
    text-indent: 1rem;
    overflow: hidden;
    background-image: url(zoom.svg);
    background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OTAiIGhlaWdodD0iNDkwIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMzYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgZD0ibTI4MCwyNzhhMTUzLDE1MyAwIDEsMC0yLDJsMTcwLDE3MG0tOTEtMTE3IDExMCwxMTAtMjYsMjYtMTEwLTExMCIvPjwvc3ZnPgo=);
    background-size: contain;
    background-repeat: no-repeat;
}
.reverse {
    filter: invert(100%);
}
.icon-loc {
    background-image: url(icons/loc.svg);
    background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MCIgaGVpZ2h0PSI4MCI+PHN0eWxlPip7c3Ryb2tlOmJsYWNrO3N0cm9rZS13aWR0aDo1O2ZpbGw6bm9uZX08L3N0eWxlPjxjaXJjbGUgY3g9IjQwIiBjeT0iNDAiIHI9IjI1Ij48L2NpcmNsZT48Y2lyY2xlIGN4PSI0MCIgY3k9IjQwIiByPSIxMCIgc3R5bGU9ImZpbGw6YmxhY2s7Ij48L2NpcmNsZT48bGluZSB4MT0iNDAiIHkxPSIxNSIgeDI9IjQwIiB5Mj0iMCI+PC9saW5lPjxsaW5lIHgxPSI2NSIgeTE9IjQwIiB4Mj0iODAiIHkyPSI0MCI+PC9saW5lPjxsaW5lIHgxPSI0MCIgeTE9IjY1IiB4Mj0iNDAiIHkyPSI4MCI+PC9saW5lPjxsaW5lIHgxPSIxNSIgeTE9IjQwIiB4Mj0iMCIgeTI9IjQwIj48L2xpbmU+PC9zdmc+);
}
.icon-pin {
    background-image: url(icons/pin.svg);
    background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCI+PHBhdGggZD0iTTMyLDY0TDE0LjE4NTUsMjkuMDkwOUEyMCwyMCAwIDEgMSA0OS44MTQ1LDI5LjA5MDlaTTQyLDIwQTEwLDEwIDAgMCAwIDIyLDIwQTEwLDEwIDAgMCAwIDQyLDIwIi8+PC9zdmc+);
}
.icon-zoom {
    background-image: url(icons/zoom.svg);
    background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OTAiIGhlaWdodD0iNDkwIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMzYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgZD0ibTI4MCwyNzhhMTUzLDE1MyAwIDEsMC0yLDJsMTcwLDE3MG0tOTEtMTE3IDExMCwxMTAtMjYsMjYtMTEwLTExMCIvPjwvc3ZnPgo=);
}
#title {
    top: .5em;
    left: .5em;
    padding: 2px .5em;
    padding: 0 .5em;
    font-size: 1.14em;
    line-height: 1.4em;
    height: 1.375em;
    font-weight: bold;
    background-color: rgba(255,255,255,.6);
}
@@ -169,24 +188,27 @@
    right: 0.5em;
}
.ol-zoom {
    top: 2.2em;
    top: 2.3em;
}
#track {
#menu {
    top: 6em;
    left: 0.5em;
}
.ol-touch #track {
.ol-touch #menu {
    top: 7em;
}
#menu button {
    border-radius: 0;
}
#menu button:first-child {
    border-top-left-radius: 2px;
    border-top-right-radius: 2px;
}
#menu button:last-child {
    border-bottom-left-radius: 2px;
    border-bottom-right-radius: 2px;
}
.ol-control button svg * {
    stroke: white;
    stroke-width: 5%;
    fill: none;
}
.ol-control button svg .fill {
    fill: white;
}
.ol-control button.clicked {
    background-color: black;
}
map.html
@@ -5,27 +5,23 @@
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v5.3.0/css/ol.css" integrity="sha384-C7SzZySesoxngSK5V0BaD1DUap0LPZGWZpnXQGoIwvBXFc8G21y4s1QYvyr84FNa" crossorigin="anonymous">
<link rel="stylesheet" href="map.css?v4" type="text/css" />
<link rel="stylesheet" href="map.css?v6" type="text/css" />
<link rel="manifest" href="map.manifest" />
</head>
<body>
<div id="map">
<div id="title" class="ol-unselectable ol-control"><a href="/">TTSS Kraków</a></div>
<div id="track" class="ol-unselectable ol-control"><button type="button" title="GPS"><svg width="100%" height="100%">
<circle cx="50%" cy="50%" r="25%"></circle>
<circle cx="50%" cy="50%" r="10%" class="fill"></circle>
<line x1="50%" y1="25%" x2="50%" y2="10%"></line>
<line x1="75%" y1="50%" x2="90%" y2="50%"></line>
<line x1="50%" y1="75%" x2="50%" y2="90%"></line>
<line x1="25%" y1="50%" x2="10%" y2="50%"></line>
</svg></button></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?v23"></script>
<script tyle="text/javascript" src="map.js?v25"></script>
</body>
</html>
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);
@@ -269,7 +344,7 @@
                if(vehicle_feature) {
                    vehicles_source[prefix].removeFeature(vehicle_feature);
                    if(feature_clicked && feature_clicked.getId() === vehicle_feature.getId()) {
                        featureClicked();
                        panel.close();
                    }
                }
                continue;
@@ -594,7 +669,7 @@
        })}, 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) {
@@ -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 = [];
@@ -637,41 +747,7 @@
    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;
    }
    
@@ -720,6 +796,7 @@
    }
}
function hash() {
    if(ignore_hashchange) {
        ignore_hashchange = false;
@@ -744,6 +821,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 +857,7 @@
function init() {
    panel = new Panel(document.getElementById('panel'));
    find = new Find();
    
    route_source = new ol.source.Vector({
        features: [],
@@ -839,9 +920,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'});
@@ -866,9 +947,11 @@
    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({
@@ -904,7 +987,7 @@
                element: fail_element,
            }),
            new ol.control.Control({
                element: document.getElementById('track'),
                element: document.getElementById('menu'),
            }),
        ]),
        loadTilesWhileAnimating: false,