Projekt

Obecné

Profil

Stáhnout (5.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
    public function __construct() {
27
        $this->name = "DOPR_D_";
28
        $this->path = "http://doprava.plzensky-kraj.cz/opendata/doprava/den/".$this->name;
29
        
30
        // Pro lokace se data predzpracovavat nemusi.
31
        $this->locations = array();
32
        
33
        // Naopak u zaznamu je prilis zbytecnych informaci - k predzpracovani dojit musi.
34
        $this->intervalMilli = (int) (24 * 3600000 / $this->HOW_MANY_INTERVALS);
35
        $this->traffic = array();
36
    }
37
    
38
    public function doWork($date) {
39
        $zipUrl = $this->path.$date.".zip";
40
        $dir = "download/$date/";
41
        $downloaded = $dir."downloaded.zip";
42
        
43
        $result = $this->download($date, $zipUrl, $dir, $downloaded);
44
        if ($result == -1 || $result == 0 || $result == 1) {
45
            
46
            $ok = -1;
47
            if ($result == 0 && $this->extract($dir, $downloaded) == 0) {
48
                unlink($downloaded);
49
                $ok = 0;
50
            }
51
            
52
            if ($ok == 0 || $result == 1) {
53
                $this->parse($dir.$this->name.$date.".csv", TRUE);
54
                $this->parse($dir."Locations.csv", FALSE);
55
                // return; odkomentovat v pripade, ze extrahovana data nemaji byt odstranena.
56
            }
57
            
58
            $this->deleteDir($dir);
59
            
60
        }
61
    }
62
    
63
    private function parse($fileName, $traffic) {
64
        if (($file = fopen($fileName, "r"))) {
65
            while (($row = fgetcsv($file, 1000, "|"))) {
66
                if ($traffic) {
67
                    $this->saveVehicleInfo(new Traffic($row));
68
                } else {
69
                    $this->locations[] = new Location($row);
70
                }
71
            }
72
            fclose($file);
73
        }
74
    }
75
    
76
    private function saveVehicleInfo($t) {
77
        // Kontrola, jestli je pro dane zarizeni vytvorene pole casu.
78
        if (!isSet($this->traffic[$t->device])) {
79
            $this->traffic[$t->device] = array();
80
            for ($i = 0; $i < $this->HOW_MANY_INTERVALS; $i++) {
81
                $this->traffic[$t->device][$i] = NULL;
82
            }
83
        }
84
        
85
        // Zjisteni, do jakeho casoveho intervalu patri zaznam.
86
        list($date, $time) = explode(" ", $t->dateTime->format("Y-m-d H:i:s.u"), 2);
87
        list($hours, $minutes, $seconds) = explode(":", $time, 3);
88
        $interval = (int) (($hours * 3600000 + $minutes * 60000 + $seconds * 1000) / $this->intervalMilli);
89
        
90
        // Kontrola, jestli je pro dany casovy interval vytvorene pole pro smery.
91
        if ($this->traffic[$t->device][$interval] == NULL) {
92
            $this->traffic[$t->device][$interval] = array();
93
            for ($i = 0; $i < 2; $i++) {
94
                $this->traffic[$t->device][$interval][$i] = array();
95
                for ($j = 0; $j < 11; $j++) {
96
                    $this->traffic[$t->device][$interval][$i][$j] = array(0, 0); // Pocet danych vozidel, suma jejich rychlosti.
97
                }
98
            }
99
        }
100
        
101
        // Ulozeni dulezitych informaci o danem zaznamu.
102
        $this->traffic[$t->device][$interval][$t->direction][$t->type10][0]++;
103
        $this->traffic[$t->device][$interval][$t->direction][$t->type10][1] += $t->speed;
104
    }
105
    
106
    private function download($date, $zipUrl, $dir, $downloaded) {
107
        if (strpos(get_headers($zipUrl, 1)[0], "404") === FALSE) {
108
            if (!file_exists($dir)) {
109
                if (mkdir($dir)) {
110
                    if (copy($zipUrl, $downloaded)) {
111
                        // Stazeni probehlo v poradku.
112
                        return 0;
113
                    } else {
114
                        // Nepovedlo se stazeni zip souboru.
115
                        return -1;
116
                    }
117
                } else {
118
                    // Nepodarilo se vytvorit slozku pro data.
119
                    return -2;
120
                }
121
            } else {
122
                // Data k vybranemu dni jiz byla stazena.
123
                return 1;
124
            }
125
        } else {
126
            // Pro dany datum neexistuji data.
127
            return -3;
128
        }
129
    }
130
    
131
    private function extract($dir, $downloaded) {
132
        $zip = new ZipArchive();
133
        if ($zip->open($downloaded, ZIPARCHIVE::CREATE) === TRUE) {
134
            $zip->extractTo($dir);
135
            $zip->close();
136
            // Extrahovani v poradku dokonceno.
137
            return 0;
138
        } else {
139
            // Nepovedlo se extrahovani obsahu zipu.
140
            return -1;
141
        }
142
    }
143
    
144
    private function deleteDir($path) {
145
        if (is_dir($path)) {
146
            $files = scandir($path);
147
            foreach ($files as $file) {
148
                if ($file != "." && $file != "..") {
149
                    $path_ = $path."/".$file;
150
                    if (filetype($path_) == "dir") {
151
                        $this->deleteDir($path_);
152
                    } else {
153
                        unlink($path_);
154
                    }
155
                }
156
            }
157
            reset($files);
158
            rmdir($path);
159
        }
160
    }
161
    
162
    public function getTraffic() {
163
        return $this->traffic;
164
    }
165
    
166
    public function getLocations() {
167
        return $this->locations;
168
    }
169
    
170
}
171

    
172
?>
(4-4/6)