Last active
March 1, 2020 12:36
-
-
Save tomekzaw/4e499e3e36373b01cf8d36abe04494ac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
set_time_limit(5); | |
error_reporting(0); | |
function in_range($num, ...$ranges) { | |
foreach ($ranges as $range) { | |
if (is_array($range)) { | |
if ($range[0] <= $num and $num <= $range[1]) { | |
return true; | |
} | |
} else { | |
return $num == $range; | |
} | |
} | |
return false; | |
} | |
function vehicle_info($kmk_id) { | |
$num = (int) mb_substr($kmk_id, 2); | |
// based on: http://www.psmkms.krakow.pl/index.php/ciekawostki/krakowski-tabor | |
if (in_range($num, [2, 4])) { | |
return [ | |
'name' => 'Solaris Urbino 18 IV electric', | |
'shortName' => 'SU18IVe', | |
'electric' => true, | |
]; | |
} | |
if (in_range($num, [71, 83])) { | |
return [ | |
'name' => 'Solaris Urbino 18 hybrid', | |
'shortName' => 'SU18h', | |
]; | |
} | |
if (in_range($num, [84, 96])) { | |
return [ | |
'name' => 'Volvo 7900A Hybrid', | |
'shortName' => '7900A', | |
]; | |
} | |
if (in_range($num, [103, 105])) { | |
return [ | |
'name' => 'Automet Cityliner Smile', | |
'shortName' => 'Smile', | |
]; | |
} | |
if (in_range($num, [106, 138])) { | |
return [ | |
'name' => 'Autosan M09LE', | |
'shortName' => 'M09LE', | |
]; | |
} | |
if (in_range($num, 139)) { | |
return [ | |
'name' => 'Autosan M12LF', | |
'shortName' => 'M12LF', | |
]; | |
} | |
if (in_range($num, [141, 146])) { | |
return [ | |
'name' => 'MAN NL283', | |
'shortName' => 'NL283', | |
]; | |
} | |
if (in_range($num, 200)) { | |
return [ | |
'name' => 'Mercedes Conecto', | |
'shortName' => 'Conecto', | |
]; | |
} | |
if (in_range($num, [206, 243])) { | |
return [ | |
'name' => 'Mercedes O530', | |
'shortName' => 'O530', | |
]; | |
} | |
if (in_range($num, [244, 299])) { | |
return [ | |
'name' => 'Mercedes O530 C2', | |
'shortName' => 'C2', | |
]; | |
} | |
if (in_range($num, [301, 345], [978, 997])) { | |
return [ | |
'name' => 'Solaris Urbino 12 IV', | |
'shortName' => 'SU12IV', | |
]; | |
} | |
if (in_range($num, [400, 408])) { | |
return [ | |
'name' => 'Solaris Urbino 12,9 hybrid', | |
'shortName' => 'SU12,9h', | |
]; | |
} | |
if (in_range($num, [501, 595], [778, 797])) { | |
return [ | |
'name' => 'Solaris Urbino 18 IV', | |
'shortName' => 'SU18IV', | |
]; | |
} | |
if (in_range($num, 601, 606)) { | |
return [ | |
'name' => 'Solaris Urbino 12 III electric', | |
'shortName' => 'SU12IIIe', | |
'electric' => true, | |
]; | |
} | |
if (in_range($num, [602, 605])) { | |
return [ | |
'name' => 'Solaris Urbino 8,9LE electric', | |
'shortName' => '8,9LE', | |
'electric' => true, | |
]; | |
} | |
if (in_range($num, [607, 623])) { | |
return [ | |
'name' => 'Solaris Urbino 12 IV electric', | |
'shortName' => 'SU12IVe', | |
'electric' => true, | |
]; | |
} | |
if (in_range($num, 700, 732)) { | |
return [ | |
'name' => 'Mercedes Conecto G', | |
'shortName' => 'Conecto G', | |
]; | |
} | |
if (in_range($num, [701, 731])) { | |
return [ | |
'name' => 'Mercedes O530G', | |
'shortName' => 'O530G', | |
]; | |
} | |
if (in_range($num, [737, 768], 777)) { | |
return [ | |
'name' => 'Solaris Urbino 18 III', | |
'shortName' => 'SU18III', | |
]; | |
} | |
if (in_range($num, [769, 776])) { | |
return [ | |
'name' => 'Solaris Urbino 18 MetroStyle', | |
'shortName' => 'SU18MS', | |
]; | |
} | |
if (in_range($num, [851, 977])) { | |
return [ | |
'name' => 'Solaris Urbino 12 III', | |
'shortName' => 'SU12III', | |
]; | |
} | |
return []; | |
} | |
$vehicles_json_url = 'http://91.223.13.70/internetservice/geoserviceDispatcher/services/vehicleinfo/vehicles'; | |
$vehicle_positions_pb_url = 'ftp://ztp.krakow.pl/VehiclePositions_A.pb'; | |
define('TRIP_ID_PREFIX', '80952613041'); // all trip ids have this prefix | |
header('Content-type: application/json; charset=utf-8'); | |
$vehicles_json_raw = file_get_contents($vehicles_json_url); | |
if ($vehicles_json_raw === false) { | |
die('{}'); | |
} | |
$vehicles_json = json_decode($vehicles_json_raw, true); | |
$trip_ids_to_vehicle_ids = []; | |
foreach ($vehicles_json['vehicles'] as $vehicle) { | |
if (!array_key_exists('tripId', $vehicle)) { | |
continue; | |
} | |
$vehicleId = $vehicle['id']; | |
$tripId = $vehicle['tripId']; | |
$vehicle_ids_to_trip_ids[$vehicleId] = $tripId; | |
} | |
function trip_id_to_short_trip_id($trip_id) { | |
// simplifies arithmetic operations on trip ids | |
return bindec(mb_substr(decbin((int) mb_substr($trip_id, mb_strlen(TRIP_ID_PREFIX))), 0, -12)); | |
} | |
$trip_ids = array_values($vehicle_ids_to_trip_ids); | |
$trip_ids_to_short_trip_ids = []; | |
foreach ($trip_ids as $trip_id) { | |
$trip_ids_to_short_trip_ids[$trip_id] = trip_id_to_short_trip_id($trip_id); | |
} | |
$vehicle_positions_pb_raw = file_get_contents($vehicle_positions_pb_url); | |
if ($vehicle_positions_pb_raw === false) { | |
die('{}'); | |
} | |
$vehicle_positions_pb_raw_inline = str_replace(["\r\n", "\n", PHP_EOL], '', $vehicle_positions_pb_raw); | |
preg_match_all("/block_([0-9]+)_.*?\x05([A-Z]{2}[0-9]{3})/", $vehicle_positions_pb_raw_inline, $matches); // block = brygada | |
list(, $block_ids, $kmk_ids) = $matches; | |
$block_ids_to_kmk_ids = []; | |
foreach ($block_ids as $i => $block_id) { | |
$block_ids_to_kmk_ids[$block_id] = $kmk_ids[$i]; | |
} | |
function find_best_shift($as, $bs) { | |
// finds s that a+s=b is true in most cases | |
$shift_min = min($bs) - max($as); | |
$shift_max = max($bs) - min($as); | |
$best_shift = $shift_min; | |
$best_count = -1; | |
for ($shift = $shift_min; $shift <= $shift_max; $shift++) { | |
$count = 0; | |
foreach ($as as $a) { | |
$count += (int) in_array($a + $shift, $bs); | |
} | |
if ($count > $best_count) { | |
$best_shift = $shift; | |
$best_count = $count; | |
} | |
} | |
return $best_shift; | |
} | |
$short_trip_ids = array_values($trip_ids_to_short_trip_ids); | |
$block_ids = array_keys($block_ids_to_kmk_ids); | |
$shift = find_best_shift($short_trip_ids, $block_ids); // -21111 | |
$output = []; | |
ksort($vehicle_ids_to_trip_ids); | |
foreach ($vehicle_ids_to_trip_ids as $vehicle_id => $trip_id) { | |
$short_trip_id = $trip_ids_to_short_trip_ids[$trip_id]; | |
$block_id = $short_trip_id + $shift; | |
if (!array_key_exists($block_id, $block_ids_to_kmk_ids)) { | |
continue; | |
} | |
$kmk_id = $block_ids_to_kmk_ids[$block_id]; | |
// $output[$vehicle_id] = $kmk_id; | |
$output[] = [ | |
'vehicleId' => $vehicle_id, | |
'tripId' => $trip_id, | |
'blockId' => $block_id, | |
'kmkId' => $kmk_id, | |
'vehicleInfo' => vehicle_info($kmk_id) + [ | |
'type' => 'bus', | |
'name' => null, | |
'shortName' => null, | |
'lowFloor' => true, | |
], | |
]; | |
} | |
$output_json = json_encode($output, JSON_PRETTY_PRINT); | |
echo $output_json; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment