Jacek Kowalski
2019-02-01 138f39292e0f703d6b65b805e8b04bbbbdd1b5bc
commit | author | age
138f39 1 <?php
JK 2 require_once 'vendor/autoload.php';
3
4 use transit_realtime\FeedMessage;
5
6 class IdMapper {
7     private $jsonTrips = [];
8     private $gtfsTrips = [];
9     
10     private $specialNames = [
11         'Zjazd do zajezdni',
12         'Przejazd techniczny',
13         'Wyjazd na trasÄ™',
14     ];
15     
16     public static function convertTripId($tripId) {
17         $tripId = explode('_', $tripId);
18         if($tripId[0] != 'block') return;
19         if($tripId[2] != 'trip') return;
20         return 4096 * (int)$tripId[1] + (int)$tripId[3];
21     }
22     
23     public function loadJson($file) {
24         $json = json_decode(file_get_contents($file));
25         foreach($json->vehicles as $vehicle) {
26             if(isset($vehicle->isDeleted) && $vehicle->isDeleted) continue;
27             if(!isset($vehicle->tripId) || !$vehicle->tripId) continue;
28             if(!isset($vehicle->name) || !$vehicle->name) continue;
29             if(!isset($vehicle->latitude) || !$vehicle->latitude) continue;
30             if(!isset($vehicle->longitude) || !$vehicle->longitude) continue;
31             foreach($this->specialNames as $name) {
32                 if(substr($vehicle->name, -strlen($name)) == $name) {
33                     continue;
34                 }
35             }
36             $this->jsonTrips[(int)$vehicle->tripId] = [
37                 'id' => $vehicle->id,
38                 'latitude' => (float)$vehicle->latitude / 3600000.0,
39                 'longitude' => (float)$vehicle->longitude / 3600000.0,
40             ];
41         }
42         ksort($this->jsonTrips);
43     }
44     
45     public function loadGtfs($file) {
46         $data = file_get_contents($file);
47         $feed = new FeedMessage();
48         $feed->parse($data);
49         foreach ($feed->getEntityList() as $entity) {
50             $vehiclePosition = $entity->getVehicle();
51             $position = $vehiclePosition->getPosition();
52             $vehicle = $vehiclePosition->getVehicle();
53             $trip = $vehiclePosition->getTrip();
54             $tripId = $trip->getTripId();
55             $this->gtfsTrips[self::convertTripId($tripId)] = [
56                 'num' => $vehicle->getLicensePlate(),
57                 'tripId' => $tripId,
58                 'latitude' => $position->getLatitude(),
59                 'longitude' => $position->getLongitude(),
60             ];
61         }
62         ksort($this->gtfsTrips);
63     }
64     
65     public function findOffset() {
66         if(count($this->jsonTrips) == 0 || count($this->gtfsTrips) == 0) {
67             return NULL;
68         }
69         
70         $jsonTripIds = array_keys($this->jsonTrips);
71         $gtfsTripIds = array_keys($this->gtfsTrips);
72         
73         $possibleOffsets = [];
74         for($i = 0; $i < count($this->jsonTrips); $i++) {
75             for($j = 0; $j < count($this->gtfsTrips); $j++) {
76                 $possibleOffsets[$jsonTripIds[$i] - $gtfsTripIds[$j]] = TRUE;
77             }
78         }
79         $possibleOffsets = array_keys($possibleOffsets);
80         
81         $bestOffset = 0;
82         $maxMatched = 0;
83         $options = 0;
84         
85         foreach($possibleOffsets as $offset) {
86             $matched = 0;
87             
88             foreach($gtfsTripIds as $tripId) {
89                 $tripId += $offset;
90                 if(isset($this->jsonTrips[$tripId])) {
91                     $matched++;
92                 }
93             }
94             
95             if($matched > $maxMatched) {
96                 $bestOffset = $offset;
97                 $maxMatched = $matched;
98                 $options = 1;
99             } elseif($matched == $maxMatched) {
100                 $options++;
101             }
102         }
103         
104         if($options != 1) {
105             return FALSE;
106         }
107         return $bestOffset;
108     }
109     
110     public function getMapping($offset) {
111         $result = [];
112         foreach($this->gtfsTrips as $gtfsTripId => $gtfsTrip) {
113             $jsonTripId = $gtfsTripId + $offset;
114             if(isset($this->jsonTrips[$jsonTripId])) {
115                 $result[$jsonTripId] = [
116                     'num' => $gtfsTrip['num'],
117                 ];
118             }
119         }
120         return $result;
121     }
122 }
123
124 $mapper = new IdMapper();
125 $mapper->loadJson('./data/vehicles_A.json');
126 $mapper->loadGtfs('./data/VehiclePositions_A.pb');
127 $offset = $mapper->findOffset();
128 if($offset) {
129     echo json_encode($mapper->getMapping($offset));
130 }