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