Projekt

Obecné

Profil

Stáhnout (6.94 KB) Statistiky
| Větev: | Revize:
1
<?php
2

    
3
require_once "traffic.php";
4
require_once "location.php";
5

    
6
class Parser {
7
    
8
    // Pro data o doprave - na kolik intervalu se ma rozdelit den (96 = 4 * 24 => intervaly po ctvrt hodine).
9
    public $HOW_MANY_INTERVALS = 96;
10
    
11
    // Pro data o doprave - jak dlouho v milisekundach trva jeden interval.
12
    public $intervalMilli;
13
    
14
    private $name;
15
    private $path;
16
    
17
    // Pole informaci o lokacich.
18
    private $locations;
19
    
20
    // Pole informaci o doprave - peti-rozmerne pole s nasledujici strukturou:
21
    // Zaklad tvori pole zarizeni. Pro kazde zarizeni je pak pole pro casove intervaly.
22
    // Kazdy casovy interval ma pole o dvou prvcich (dva smery). Pro kazdy smer je vytvoreno pole o jedenacti
23
    // prvcich (jedenact typu vozidel). Pro kazde vozidlo je vytvoreno pole o dvou prvcich (pocet vozidel, suma rychlosti).
24
    private $traffic;
25
    
26
    // Skoro to same jako $traffic, akorat bez rozmeru pro casove intervaly.
27
    private $trafficOneDay;
28
    
29
    public function __construct() {
30
        $this->name = "DOPR_D_";
31
        $this->path = "http://doprava.plzensky-kraj.cz/opendata/doprava/den/".$this->name;
32
        
33
        // Pro lokace se data predzpracovavat nemusi.
34
        $this->locations = array();
35
        
36
        // Naopak u zaznamu je prilis zbytecnych informaci - k predzpracovani dojit musi.
37
        $this->intervalMilli = (int) (24 * 3600000 / $this->HOW_MANY_INTERVALS);
38
        $this->traffic = array();
39
        $this->trafficOneDay = array();
40
    }
41
    
42
    public function doWork($date) {
43
        $zipUrl = $this->path.$date.".zip";
44
        $dir = "download/$date/";
45
        $downloaded = $dir."downloaded.zip";
46
        
47
        $result = $this->download($date, $zipUrl, $dir, $downloaded);
48
        if ($result == -1 || $result == 0 || $result == 1) {
49
            
50
            $ok = -1;
51
            if ($result == 0 && $this->extract($dir, $downloaded) == 0) {
52
                unlink($downloaded);
53
                $ok = 0;
54
            }
55
            
56
            if ($ok == 0 || $result == 1) {
57
                $this->parse($dir.$this->name.$date.".csv", TRUE);
58
                $this->parse($dir."Locations.csv", FALSE);
59
                // return; odkomentovat v pripade, ze extrahovana data nemaji byt odstranena.
60
            }
61
            
62
            $this->deleteDir($dir);
63
            
64
        }
65
    }
66
    
67
    private function parse($fileName, $traffic) {
68
        if (($file = fopen($fileName, "r"))) {
69
            while (($row = fgetcsv($file, 1000, "|"))) {
70
                if ($traffic) {
71
                    $this->saveVehicleInfo(new Traffic($row));
72
                } else {
73
                    $this->locations[] = new Location($row);
74
                }
75
            }
76
            fclose($file);
77
        }
78
    }
79
    
80
    private function saveVehicleInfo($t) {
81
        // Kontrola, jestli je pro dane zarizeni vytvorene pole casu.
82
        if (!isSet($this->traffic[$t->device])) {
83
            // Vytvorit prvni dva rozmery pole pro dopravni data s rozdelenim na casove intervaly.
84
            $this->traffic[$t->device] = array();
85
            for ($i = 0; $i < $this->HOW_MANY_INTERVALS; $i++) {
86
                $this->traffic[$t->device][$i] = NULL;
87
            }
88
            
89
            // U pole s prumery za cely den rovnou vytvorit vsechny rozmery.
90
            $this->trafficOneDay[$t->device] = array();
91
            for ($i = 0; $i < 2; $i++) {
92
                $this->trafficOneDay[$t->device][$i] = array();
93
                for ($j = 0; $j < 11; $j++) {
94
                    $this->trafficOneDay[$t->device][$i][$j] = array(0, 0); // Pocet danych vozidel, suma jejich rychlosti.
95
                }
96
            }
97
            
98
        }
99
        
100
        // Zjisteni, do jakeho casoveho intervalu patri zaznam.
101
        list($date, $time) = explode(" ", $t->dateTime->format("Y-m-d H:i:s.u"), 2);
102
        list($hours, $minutes, $seconds) = explode(":", $time, 3);
103
        $interval = (int) (($hours * 3600000 + $minutes * 60000 + $seconds * 1000) / $this->intervalMilli);
104
        
105
        // Kontrola, jestli je pro dany casovy interval vytvorene pole pro smery.
106
        if ($this->traffic[$t->device][$interval] == NULL) {
107
            $this->traffic[$t->device][$interval] = array();
108
            for ($i = 0; $i < 2; $i++) {
109
                $this->traffic[$t->device][$interval][$i] = array();
110
                for ($j = 0; $j < 11; $j++) {
111
                    $this->traffic[$t->device][$interval][$i][$j] = array(0, 0); // Pocet danych vozidel, suma jejich rychlosti.
112
                }
113
            }
114
        }
115
        
116
        // Ulozeni dulezitych informaci o danem zaznamu.
117
        $this->traffic[$t->device][$interval][$t->direction][$t->type10][0]++;
118
        $this->traffic[$t->device][$interval][$t->direction][$t->type10][1] += $t->speed;
119
        
120
        // Ulozeni i do pole s prumery za cely den.
121
        $this->trafficOneDay[$t->device][$t->direction][$t->type10][0]++;
122
        $this->trafficOneDay[$t->device][$t->direction][$t->type10][1] += $t->speed;
123
    }
124
    
125
    private function download($date, $zipUrl, $dir, $downloaded) {
126
        if (strpos(get_headers($zipUrl, 1)[0], "404") === FALSE) {
127
            if (!file_exists($dir)) {
128
                if (mkdir($dir)) {
129
                    if (copy($zipUrl, $downloaded)) {
130
                        // Stazeni probehlo v poradku.
131
                        return 0;
132
                    } else {
133
                        // Nepovedlo se stazeni zip souboru.
134
                        return -1;
135
                    }
136
                } else {
137
                    // Nepodarilo se vytvorit slozku pro data.
138
                    return -2;
139
                }
140
            } else {
141
                // Data k vybranemu dni jiz byla stazena.
142
                return 1;
143
            }
144
        } else {
145
            // Pro dany datum neexistuji data.
146
            return -3;
147
        }
148
    }
149
    
150
    private function extract($dir, $downloaded) {
151
        $zip = new ZipArchive();
152
        if ($zip->open($downloaded, ZIPARCHIVE::CREATE) === TRUE) {
153
            $zip->extractTo($dir);
154
            $zip->close();
155
            // Extrahovani v poradku dokonceno.
156
            return 0;
157
        } else {
158
            // Nepovedlo se extrahovani obsahu zipu.
159
            return -1;
160
        }
161
    }
162
    
163
    private function deleteDir($path) {
164
        if (is_dir($path)) {
165
            $files = scandir($path);
166
            foreach ($files as $file) {
167
                if ($file != "." && $file != "..") {
168
                    $path_ = $path."/".$file;
169
                    if (filetype($path_) == "dir") {
170
                        $this->deleteDir($path_);
171
                    } else {
172
                        unlink($path_);
173
                    }
174
                }
175
            }
176
            reset($files);
177
            rmdir($path);
178
        }
179
    }
180
    
181
    public function getTraffic() {
182
        return $this->traffic;
183
    }
184
    
185
    public function getTrafficOneDay() {
186
        return $this->trafficOneDay;
187
    }
188
    
189
    public function getLocations() {
190
        return $this->locations;
191
    }
192
    
193
}
194

    
195
?>
(4-4/6)