Jacek Kowalski
2019-06-10 0c85a7bd59cfa3a0f99b630161ba31f1cc7cfab5
commit | author | age
4673cc 1 <?php
JK 2 require_once(__DIR__.'/../vendor/autoload.php');
3 require_once(__DIR__.'/vehicle_types.php');
4
5 use transit_realtime\FeedMessage;
6
7 class Mapper {
0c85a7 8     private $ttssTrips = [];
JK 9     private $gtfsrtTrips = [];
4673cc 10     private $logger = NULL;
JK 11     
12     private $specialNames = [
13         'Zjazd do zajezdni',
14         'Przejazd techniczny',
15         'Wyjazd na trasÄ™',
16     ];
17     
18     public function __construct() {
19         $this->logger = new Monolog\Logger(__CLASS__);
20     }
21     
22     public static function convertTripId($tripId) {
23         $tripId = explode('_', $tripId);
24         if($tripId[0] != 'block') return;
25         if($tripId[2] != 'trip') return;
26         return 4096 * (int)$tripId[1] + (int)$tripId[3];
27     }
28     
29     public function loadTTSS($file) {
0c85a7 30         $ttss = json_decode(file_get_contents($file));
JK 31         foreach($ttss->vehicles as $vehicle) {
4673cc 32             if(isset($vehicle->isDeleted) && $vehicle->isDeleted) continue;
JK 33             if(!isset($vehicle->tripId) || !$vehicle->tripId) continue;
34             if(!isset($vehicle->name) || !$vehicle->name) continue;
35             if(!isset($vehicle->latitude) || !$vehicle->latitude) continue;
36             if(!isset($vehicle->longitude) || !$vehicle->longitude) continue;
37             foreach($this->specialNames as $name) {
38                 if(substr($vehicle->name, -strlen($name)) == $name) {
39                     continue;
40                 }
41             }
0c85a7 42             $this->ttssTrips[(int)$vehicle->tripId] = [
4673cc 43                 'id' => $vehicle->id,
JK 44                 'latitude' => (float)$vehicle->latitude / 3600000.0,
45                 'longitude' => (float)$vehicle->longitude / 3600000.0,
46             ];
47         }
0c85a7 48         ksort($this->ttssTrips);
4673cc 49     }
JK 50     
0c85a7 51     public function loadGTFSRT($file) {
4673cc 52         $data = file_get_contents($file);
JK 53         $feed = new FeedMessage();
54         $feed->parse($data);
55         foreach ($feed->getEntityList() as $entity) {
56             $vehiclePosition = $entity->getVehicle();
57             $position = $vehiclePosition->getPosition();
58             $vehicle = $vehiclePosition->getVehicle();
59             $trip = $vehiclePosition->getTrip();
60             $tripId = $trip->getTripId();
0c85a7 61             $this->gtfsrtTrips[self::convertTripId($tripId)] = [
4673cc 62                 'id' => $entity->getId(),
JK 63                 'num' => $vehicle->getLicensePlate(),
64                 'tripId' => $tripId,
65                 'latitude' => $position->getLatitude(),
66                 'longitude' => $position->getLongitude(),
67             ];
68         }
0c85a7 69         ksort($this->gtfsrtTrips);
4673cc 70     }
JK 71     
72     public function findOffset() {
0c85a7 73         if(count($this->ttssTrips) == 0 || count($this->gtfsrtTrips) == 0) {
4673cc 74             return NULL;
JK 75         }
76         
0c85a7 77         $ttssTripIds = array_keys($this->ttssTrips);
JK 78         $gtfsTripIds = array_keys($this->gtfsrtTrips);
4673cc 79         
JK 80         $possibleOffsets = [];
0c85a7 81         for($i = 0; $i < count($this->ttssTrips); $i++) {
JK 82             for($j = 0; $j < count($this->gtfsrtTrips); $j++) {
83                 $possibleOffsets[$ttssTripIds[$i] - $gtfsTripIds[$j]] = TRUE;
4673cc 84             }
JK 85         }
86         $possibleOffsets = array_keys($possibleOffsets);
87         
88         $bestOffset = 0;
89         $maxMatched = 0;
90         $options = 0;
91         
92         foreach($possibleOffsets as $offset) {
93             $matched = 0;
94             
95             foreach($gtfsTripIds as $tripId) {
96                 $tripId += $offset;
0c85a7 97                 if(isset($this->ttssTrips[$tripId])) {
4673cc 98                     $matched++;
JK 99                 }
100             }
101             
102             if($matched > $maxMatched) {
103                 $bestOffset = $offset;
104                 $maxMatched = $matched;
105                 $options = 1;
106             } elseif($matched == $maxMatched) {
107                 $options++;
108             }
109         }
110         
111         if($options != 1) {
112             throw new Exception('Found '.$options.' possible mappings!');
113         }
114         return $bestOffset;
115     }
116     
0c85a7 117     public function mapUsingOffset($offset) {
4673cc 118         $result = [];
0c85a7 119         foreach($this->gtfsrtTrips as $gtfsTripId => $gtfsTrip) {
JK 120             $ttssTripId = $gtfsTripId + $offset;
121             if(isset($this->ttssTrips[$ttssTripId])) {
4673cc 122                 $data = numToTypeB($gtfsTrip['id']);
JK 123                 $num = $gtfsTrip['num'];
124                 if(!is_array($data) || !isset($data['num'])) {
125                     $data = [
126                         'num' => $num,
127                         'low' => 2,
128                     ];
129                 } elseif($data['num'] != $num) {
130                     // Ignore due to incorrect depot markings in the data
131                     //$this->logger->warn('Got '.$num.', database has '.$data['num']);
132                 }
0c85a7 133                 $result[$this->ttssTrips[$ttssTripId]['id']] = $data;
4673cc 134             }
JK 135         }
136         return $result;
137     }
138 }