Jacek Kowalski
2019-06-21 c077c73b10f6581a1bc3983b8a0ca4a7446a2b91
Output tables of vehicles on lines
2 files added
5 files modified
127 ■■■■■ changed files
composer.json 3 ●●●● patch | view | raw | blame | history
config.php 10 ●●●●● patch | view | raw | blame | history
data/empty 1 ●●●● patch | view | raw | blame | history
lib/mapper.php 11 ●●●● patch | view | raw | blame | history
lib/output.php 33 ●●●●● patch | view | raw | blame | history
parse.php 10 ●●●●● patch | view | raw | blame | history
templates/vehicles.html 59 ●●●●● patch | view | raw | blame | history
composer.json
@@ -1,6 +1,7 @@
{
    "require": {
        "google/gtfs-realtime-bindings": "^0.0.2",
        "monolog/monolog": "^1.24"
        "monolog/monolog": "^1.24",
        "twig/twig": "^2.0"
    }
}
config.php
@@ -7,7 +7,9 @@
        'ttss_file' => 'vehicles_A.json',
        'database' => 'mapping_A.sqlite3',
        'result' => 'mapping_A.json',
        'result_vehicles' => 'vehicles_A.html',
        'mapper' => 'numToTypeB',
        'prefix' => 'b',
    ],
    'tram' => [
        'gtfsrt' => 'ftp://ztp.krakow.pl/VehiclePositions_T.pb',
@@ -16,7 +18,9 @@
        'ttss_file' => 'vehicles_T.json',
        'database' => 'mapping_T.sqlite3',
        'result' => 'mapping_T.json',
        'result_vehicles' => 'vehicles_T.html',
        'mapper' => 'numToTypeT',
        'prefix' => 't',
    ],
    'tram2' => [
        'gtfsrt' => 'ftp://ztp.krakow.pl/VehiclePositions.pb',
@@ -25,14 +29,18 @@
        'ttss_file' => 'vehicles_T.json',
        'database' => 'mapping_T.sqlite3',
        'result' => 'mapping_T.json',
        'result_vehicles' => 'vehicles_T.html',
        'mapper' => 'numToTypeT',
        'prefix' => 't',
    ],
]; 
foreach($sources as $name => &$source) {
    foreach(['gtfsrt_file', 'ttss_file', 'database', 'result'] as $field) {
    foreach(['gtfsrt_file', 'ttss_file', 'database', 'result', 'result_vehicles'] as $field) {
        $source[$field] = __DIR__.'/data/'.$source[$field];
    }
    $source['result_temp'] = $source['result'].'.tmp';
    $source['result_vehicles_temp'] = $source['result_vehicles'].'.tmp';
}
unset($source);
data/empty
@@ -1 +0,0 @@
lib/mapper.php
@@ -34,13 +34,16 @@
            if(!isset($vehicle->name) || !$vehicle->name) continue;
            if(!isset($vehicle->latitude) || !$vehicle->latitude) continue;
            if(!isset($vehicle->longitude) || !$vehicle->longitude) continue;
            foreach($this->specialNames as $name) {
                if(substr($vehicle->name, -strlen($name)) == $name) {
            list($line, $direction) = explode(' ', $vehicle->name, 2);
            foreach($this->specialNames as $specialName) {
                if(substr($vehicle->name, -strlen($specialName)) == $specialName) {
                    continue;
                }
            }
            $this->ttssTrips[(string)$vehicle->tripId] = [
                'id' => (string)$vehicle->id,
                'line' => $line,
                'direction' => $direction,
                'latitude' => (float)$vehicle->latitude / 3600000.0,
                'longitude' => (float)$vehicle->longitude / 3600000.0,
            ];
@@ -52,6 +55,10 @@
        return $this->ttssDate / 1000.0;
    }
    
    public function getTTSSTrips() {
        return $this->ttssTrips;
    }
    public function loadGTFSRT($file) {
        $data = file_get_contents($file);
        $feed = new FeedMessage();
lib/output.php
New file
@@ -0,0 +1,33 @@
<?php
function createVehiclesList($trips, $mapping, $saveConfig = FALSE) {
    $lines = [];
    foreach($trips as $trip) {
        $lines[$trip['line']][] = [
            'trip' => $trip,
            'vehicle' => $mapping[$trip['id']] ?? [],
        ];
    }
    foreach($lines as &$line) {
        usort($line, function($a, $b) {
            return (substr($a['vehicle']['num'] ?? '', 2) <=> substr($b['vehicle']['num'] ?? '', 2));
        });
    }
    unset($line);
    ksort($lines);
    if($saveConfig) {
        $twigLoader = new \Twig\Loader\FilesystemLoader(__DIR__.'/../templates');
        $twig = new \Twig\Environment($twigLoader);
        $vehiclesHtml = $twig->render('vehicles.html', [
            'lines' => $lines,
            'prefix' => $saveConfig['prefix'],
        ]);
        if(!file_put_contents($saveConfig['result_vehicles_temp'], $vehiclesHtml)) {
            throw new Exception('Vehicles save failed');
        }
        rename($saveConfig['result_vehicles_temp'], $saveConfig['result_vehicles']);
    }
    return $lines;
}
parse.php
@@ -3,6 +3,7 @@
require_once(__DIR__.'/lib/database.php');
require_once(__DIR__.'/lib/fetch.php');
require_once(__DIR__.'/lib/mapper.php');
require_once(__DIR__.'/lib/output.php');
require_once(__DIR__.'/lib/vehicle_types.php');
require_once(__DIR__.'/config.php');
@@ -76,6 +77,9 @@
            throw new Exception('Ignoring result due to better data already present');
        }
        
        $logger->info('Creating mapping...');
        $db->addMapping($mapping);
        
        $jsonContent = [];
@@ -88,6 +92,12 @@
            throw new Exception('Result save failed');
        }
        rename($source['result_temp'], $source['result']);
        $logger->info('Creating vehicle list...');
        createVehiclesList($mapper->getTTSSTrips(), $jsonContent, $source);
        $logger->info('Finished');
    } catch(Throwable $e) {
        $logger->error($e->getMessage(), ['exception' => $e, 'exception_string' => (string)$e]);
templates/vehicles.html
New file
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<title>Vehicles on lines (TTSS-based)</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
table {
    border-collapse: collapse;
    border-spacing: 0;
}
th, td {
    border: 1px solid black;
    padding: 5px;
}
td {
    vertical-align: top;
    text-align: center;
}
a {
    text-decoration: none;
}
a:hover {
    text-decoration: underline;
}
.low {
    color: #000;
}
.low0 {
    color: #C70;
}
.low1, .low2 {
    color: #070;
}
</style>
<table>
<thead>
<tr>
{% for line in lines|keys %}
<th>{{ line | e }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
<tr>
{% for trips in lines %}
<td>
{% for trip in trips %}
<a href="https://mpk.jacekk.net/map.html#!{{ prefix }}{{ trip.trip.id | e }}" class="low{{ trip.vehicle.low | default }}">
{{ trip.vehicle.num | default('<?>') | e }}<br />
</a>
{% endfor %}
</td>
{% endfor %}
</tr>
</tbody>
</table>