/adei/trunk

To get this branch, use:
bzr branch http://darksoft.org/webbzr/adei/trunk

« back to all changes in this revision

Viewing changes to patches/riku-weather/services/imageservices.php

  • Committer: Suren A. Chilingaryan
  • Date: 2012-07-14 17:44:09 UTC
  • Revision ID: csa@dside.dyndns.org-20120714174409-cuzsy4vupyjx9lia
Update of setups

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
    header("Content-type: image/jpeg");
3
 
    header("Cache-control: no-cache, must-revalidate");
4
 
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
5
 
    
6
 
    clearstatcache();
7
 
    
8
 
    //abstract class that all imageservices should extend
9
 
    //at the moment this wouldn't be necessary but in the future all common functionality 
10
 
    //should be in this class
11
 
    abstract class ImageService
12
 
    {
13
 
        var $start;
14
 
        var $n;
15
 
    
16
 
        public function __construct($start, $n)
17
 
        {
18
 
            $this->start = $start;
19
 
            $this->n = $n;
20
 
        }
21
 
    }
22
 
    
23
 
    //class for the cloud cameras image processing
24
 
    class CloudCameraImageService extends ImageService
25
 
    {
26
 
        var $bg_width;//the initial width for the main graphs background image, further adjusted by code in $this::GetBackgroundImage()
27
 
        var $dir;//directory containing the cloud camera images
28
 
        var $window;//window made out of two timestamps
29
 
        
30
 
        public function __construct($start, $n, $window = NULL)
31
 
        {
32
 
            parent::__construct($start, $n);
33
 
            
34
 
            //these should be placed in some configuration file
35
 
            $this->dir = "/home/riku/small/";//the directory containing the cloud camera images
36
 
            $this->bg_width = 400;
37
 
            
38
 
            if($window && $window !== 0 && strstr($window, "-"))//if the window property is in the querystring and it's not 0
39
 
            {
40
 
                $this->window = $window;//we use the window to determine which images to include in the cropped image returned as the main graph bg
41
 
            }
42
 
        }
43
 
        
44
 
        //function to construct a timestamp for each cloud camera image out of their filenames
45
 
        function ConstructTimestamp($string)
46
 
        {
47
 
            $string = substr($string, 1);//get rid of the '2' from cc2
48
 
            $y = substr($string, 0, 4);//<YYYY> MMDDhhmmss
49
 
            $m = substr($string, 4, 2);//YYYY <MM> DDhhmmss
50
 
            $d = substr($string, 6, 2);//YYYYMM <DD> hhmmss
51
 
            $h = substr($string, 8, 2);//YYYYMMDD <hh> mmss
52
 
            $min = substr($string, 10, 2);//YYYYMMDDhh <mm> ss
53
 
            $sec = substr($string, 12, 2);//YYYYMMDDhhmm <ss>
54
 
 
55
 
            $stamp = mktime($h, $min, $sec, $m, $d, $y);
56
 
 
57
 
            return intval($stamp);
58
 
        }
59
 
        
60
 
        //function reading the required images' timestamps in an array, contructing the background from the images and retuning them in an array
61
 
        //also possibly returns an array with 'error' field if something goes wrong
62
 
        function GetBackgroundImage()
63
 
        {
64
 
            $dir = $this->dir;
65
 
 
66
 
            $timestamps = array();
67
 
            
68
 
            $data_amount = 0;
69
 
            
70
 
            if (is_dir($dir)) //read through the folder of images
71
 
            {
72
 
                if ($handle = opendir($dir)) {
73
 
                    $filenames = array();
74
 
                    while (false !== ($file = readdir($handle))) {
75
 
                        if(strstr($file, "kitcube"))
76
 
                        {
77
 
                            $string = preg_replace("/[^0-9]/", "", $file);
78
 
                            $ts = $this::ConstructTimestamp($string);
79
 
                            $filenames[$ts] = $file;
80
 
                            array_push($timestamps, $ts);
81
 
                            $data_amount++;
82
 
                        }
83
 
                    }
84
 
                }
85
 
            }
86
 
            ksort($filenames);//sort the images by their timestamp
87
 
            asort($timestamps);
88
 
            $timestamps = array_values($timestamps);
89
 
 
90
 
            if($this->window)//if the window property was not 0 we use it to determine the required data
91
 
            {
92
 
                $start = intval(substr($this->window, 0, strpos($this->window, "-")));
93
 
                $end = intval(substr($this->window, strpos($this->window, "-") + 1));
94
 
            }
95
 
            else//if window property was 0 we use the user control values (start and zoom) to determine the required data
96
 
            {
97
 
                $start_slider_max = 1;
98
 
                $data_dummy = $data_amount;
99
 
                while($data_dummy > 100)
100
 
                {
101
 
                    $data_dummy = floor($data_dummy / 10);
102
 
                    $start_slider_max = $start_slider_max * 10;
103
 
                }
104
 
                
105
 
                $start_index = (floor(count($timestamps) / $start_slider_max) * ($this->start - 1));
106
 
                $start = $timestamps[$start_index];
107
 
                if(count($timestamps) >= 200)
108
 
                {
109
 
                    $end = $timestamps[$start_index + (30 * $this->n)];
110
 
                }
111
 
                else
112
 
                {
113
 
                    $end = $timestamps[count($timestamps) - 1];
114
 
                }
115
 
            }
116
 
            
117
 
            if($start > $end)//if the start timestamp is after the end timestamp
118
 
            {
119
 
                $return = array(
120
 
                        "error" => "End point can't be before start!"
121
 
                        );
122
 
                return $return;
123
 
            }
124
 
            
125
 
            end($timestamps);
126
 
            $array_end = current($timestamps);
127
 
            reset($timestamps);
128
 
            $array_start = current($timestamps);
129
 
            
130
 
            $array_center = $timestamps[count($timestamps) / 2];
131
 
            
132
 
            if($start < $array_start)
133
 
            {
134
 
                $start = $array_start;
135
 
            }
136
 
            elseif($end > $array_end)
137
 
            {
138
 
                $end = $array_end;
139
 
            }
140
 
            elseif($start > $array_end || $end < $array_start)//if the start is after the last cloud image or the end is before the first one
141
 
            {
142
 
                $return = array(
143
 
                        "error" => "No data found!"
144
 
                        );
145
 
                return $return;
146
 
            }
147
 
            
148
 
            //this divides the timestamps array (which is quite big...) in half 4 times in a row to make it more managable to go through
149
 
            for($i = 0 ; $i < 4 ; $i++)//TODO: better condition here, this just narrows down the timestamps array to go through 4 times (what if its got some millions of stamps?)
150
 
            {
151
 
                if($array_center < $start)
152
 
                {
153
 
                    $timestamps = array_slice($timestamps, (count($timestamps) / 2));
154
 
                    reset($timestamps);
155
 
                    $array_start = current($timestamps);
156
 
                }
157
 
                else if($array_center > $start)
158
 
                {
159
 
                    $timestamps = array_slice($timestamps, 0, (count($timestamps) / 2));
160
 
                    end($timestamps);
161
 
                    $array_end = current($timestamps);
162
 
                }
163
 
                $array_center = $timestamps[count($timestamps) / 2];
164
 
            }
165
 
            reset($timestamps);
166
 
            
167
 
            $stamps = array();//stamps array contains the timestamps of the images to be displayed
168
 
            
169
 
            foreach($timestamps as $ts)
170
 
            {
171
 
                if(empty($stamps))
172
 
                {
173
 
                    if($prev_ts < $start && $ts >= $start)
174
 
                    {
175
 
                        array_push($stamps, $ts);
176
 
                    }
177
 
                    $prev_ts = $ts;
178
 
                }
179
 
                else
180
 
                {
181
 
                    if($ts <= $end)
182
 
                    {
183
 
                        array_push($stamps, $ts);
184
 
                    }
185
 
                    $prev_ts = $ts;
186
 
                }
187
 
            }
188
 
 
189
 
            //here we find out the original images' width and height
190
 
            $file = $filenames[$stamps[0]];
191
 
            $file_handle = fopen(($dir . $file), "r");
192
 
            $binary = fread($file_handle, filesize($dir . $file));
193
 
            
194
 
            $tmp = imagecreatefromstring($binary);
195
 
            
196
 
            $size = array(imagesx($tmp), imagesy($tmp));
197
 
            
198
 
            fclose($file_handle);
199
 
            imagedestroy($tmp);
200
 
            
201
 
            
202
 
            $width = $this->bg_width;
203
 
        
204
 
            $crop_width = floor($width / count($stamps));//the width of the slices to be taken from the images depends on the number of images
205
 
            $width = count($stamps) * $crop_width;//adjust the width of the return image based on the crop width
206
 
 
207
 
            $canvas = imagecreatetruecolor( $width, $size[1]/3 );//create the image to be returned by the function
208
 
 
209
 
            //go through the required images and copy a slice of them to the return image
210
 
            foreach($stamps as $key => $stamp)
211
 
            {
212
 
                $file = $filenames[$stamp];
213
 
                $file_handle = fopen(($dir . $file), "r");
214
 
                $binary = fread($file_handle, filesize($dir . $file));
215
 
                
216
 
                $cropped = imagecreatefromstring($binary);
217
 
 
218
 
                // Prepare image  crop - center the crop on the image
219
 
                $cropLeft = ( $size[0]/2 )  - ( $crop_width/2 );
220
 
                $cropHeight = 0;
221
 
                // Generate the cropped image
222
 
                imagecopyresized( $canvas, $cropped, $key * $crop_width, 0, $cropLeft, $cropHeight, $crop_width, $size[1]/3, $crop_width, $size[1] );
223
 
            }
224
 
 
225
 
            imagedestroy($cropped);//destroy the temporary image
226
 
        
227
 
            $return = array(
228
 
                    "background" => $canvas,
229
 
                    "timestamps" => $stamps
230
 
                    );
231
 
    
232
 
            return $return;
233
 
        }
234
 
        
235
 
        //function to get the main graph
236
 
        public function GetMainImage()
237
 
        {
238
 
            //requiring the needed jpgraph files
239
 
            require_once("/usr/share/php5/jpgraph/jpgraph.php");
240
 
            require_once("/usr/share/php5/jpgraph/jpgraph_bar.php");
241
 
            require_once("/usr/share/php5/jpgraph/jpgraph_date.php" );
242
 
 
243
 
            $n = $this->n;
244
 
        
245
 
            $bg_array = $this::GetBackgroundImage();//get the background image for the graph
246
 
            
247
 
            if($bg_array['error'])//if the background array contains the error field we return an error image
248
 
            {
249
 
                $error = new ErrorService();
250
 
                $image = $error->ShowError($bg_array['error']);
251
 
                return $image;
252
 
            }
253
 
            
254
 
            $background = $bg_array["background"];
255
 
            $timestamps = $bg_array["timestamps"];
256
 
            
257
 
            $filename = tempnam('/tmp/adei/', 'cc_') . ".jpg";//create a temporary file out of the background (needed to set the image as jpgraph bg)
258
 
 
259
 
            imagejpeg( $background, $filename, 100);
260
 
            
261
 
            $array = array();//array of 0 values for the graph needed to set the x-axis tick labels correctly
262
 
  
263
 
            for($i = 0 ; $i < count($timestamps) ; $i++)
264
 
            {
265
 
                array_push($array, 0);
266
 
            }
267
 
 
268
 
            //here we contruct the subtitle telling the current day shown on the graph
269
 
            $stamp_from = $timestamps[0];
270
 
            $stamp_to = $timestamps[count($timestamps) - 1];
271
 
 
272
 
            if(date("d.m.Y", $stamp_from) === date("d.m.Y", $stamp_to))
273
 
            {
274
 
                $subtitle = date("d.m.Y", $stamp_from);
275
 
            }
276
 
            else
277
 
            {
278
 
                $subtitle = date("d.m.Y", $stamp_from) . " - " . date("d.m.Y", $stamp_to);
279
 
            }
280
 
 
281
 
            foreach($timestamps as &$stamp)
282
 
            {
283
 
                $stamp = date("H:i:s", $stamp);
284
 
            }
285
 
 
286
 
            //create the graph
287
 
            $graph = new Graph(530, 400);
288
 
            $graph->SetScale('textint', 0, 0, 0, count($timestamps));
289
 
            $graph->xscale->ticks->Set((count($timestamps) / 5));
290
 
            
291
 
            $graph->SetBackgroundImage(($filename), BGIMG_FILLPLOT);
292
 
            $graph->SetBackgroundImageMix(100);
293
 
            $graph->SetMargin(50, 20, 50, 20);
294
 
            $graph->SetMarginColor("#DDDDDD");
295
 
 
296
 
            $graph->title->Set("Cloud graph");
297
 
            $graph->subtitle->Set($subtitle);
298
 
 
299
 
            $plot = new BarPlot($array);
300
 
            $graph->Add($plot);
301
 
 
302
 
            $graph->yaxis->Hide();
303
 
 
304
 
            $graph->xaxis->SetTitle("Time", "middle");
305
 
            $graph->xaxis->SetTickSide(SIDE_DOWN);
306
 
            $graph->xaxis->SetTickLabels($timestamps);
307
 
            $graph->xaxis->SetLabelAlign('right');
308
 
            $graph->xaxis->HideLastTickLabel(); 
309
 
 
310
 
            imagedestroy( $background );
311
 
    
312
 
            return $graph;//return the graph handle
313
 
        }
314
 
        
315
 
        //this function gets the full cloud camera image from one specific time to be shown in the secondary image slot of the module
316
 
        public function GetSecondaryImage($id)
317
 
        {
318
 
            $dir = $this->dir;
319
 
            
320
 
            if (is_dir($dir)) 
321
 
            {
322
 
                if ($handle = opendir($dir)) {
323
 
                    $filenames = array();
324
 
                    while (false !== ($file = readdir($handle))) {
325
 
                        if(strstr($file, "kitcube"))
326
 
                        {
327
 
                            array_push($filenames, $file);
328
 
                        }
329
 
                    }
330
 
                }
331
 
            }
332
 
            asort($filenames);
333
 
            
334
 
            $filenames = array_values($filenames);
335
 
            
336
 
            $file = $filenames[$id];
337
 
            $file_handle = fopen(($dir . $file), "r");
338
 
            $image = fread($file_handle, filesize($dir . $file));
339
 
            fclose($file_handle);
340
 
            
341
 
            return $image;
342
 
        }
343
 
    }
344
 
    
345
 
    //error service is used to show errors to the user in case something goes wrong
346
 
    class ErrorService extends ImageService
347
 
    {
348
 
        var $error;
349
 
        
350
 
        public function __construct($start, $n)
351
 
        {
352
 
            parent::__construct($start, $n);
353
 
        }
354
 
        
355
 
        function ShowError($string)
356
 
        {
357
 
            $font_size = 5;
358
 
            $width = 600;
359
 
            $height = 400;
360
 
            $img = imagecreate($width, $height);
361
 
            $bg = imagecolorallocate($img, 225, 225, 225);
362
 
            $black = imagecolorallocate($img, 0, 0, 0);
363
 
            $len = strlen($string);
364
 
            
365
 
            for($i = 0 ; $i < $len ; $i++)
366
 
            {
367
 
                $xpos = $i * imagefontwidth($font_size);
368
 
                $ypos = $height / 4;
369
 
                imagechar($img, $font_size, $xpos, $ypos, $string, $black);
370
 
                $string = substr($string, 1);
371
 
            }
372
 
            
373
 
            return $img;
374
 
        }
375
 
    }
376
 
    
377
 
    //here we create a service based on the query string's target property and pass the other properties to the service
378
 
    if(isset($_GET["target"]))
379
 
    {
380
 
        $target = $_GET["target"];
381
 
        
382
 
        if(isset($_GET["window"]))
383
 
        {
384
 
            $window = $_GET["window"];
385
 
        }
386
 
        switch($target)
387
 
        {
388
 
            case "cloud_main":
389
 
                if(isset($_GET["start"]))
390
 
                {
391
 
                    $start = $_GET["start"];
392
 
                }
393
 
                else 
394
 
                {
395
 
                    $start = 1;
396
 
                }
397
 
                if(isset($_GET["n"]))
398
 
                {
399
 
                    $n = 6 - $_GET["n"];
400
 
                }
401
 
                else
402
 
                {
403
 
                    $n = 5;
404
 
                }
405
 
                $service = new CloudCameraImageService($start, $n, $window);
406
 
                $image = $service->GetMainImage();
407
 
                break;
408
 
            case "cloud_sec":
409
 
                if(isset($_GET["id"]))
410
 
                {
411
 
                    $id = $_GET["id"];
412
 
                }
413
 
                else
414
 
                {
415
 
                    $id = 1;
416
 
                }
417
 
                $service = new CloudCameraImageService($start, $n, $window);
418
 
                $image = $service->GetSecondaryImage($id);
419
 
                break;
420
 
            case "ceilo_main":
421
 
                $service = new ErrorService();
422
 
                $image = $service->ShowError("Not implemented");
423
 
                break;
424
 
            case "ceilo_sec":
425
 
                $service = new ErrorService();
426
 
                $image = $service->ShowError("Not implemented");
427
 
                break;
428
 
            case "temp_main":
429
 
                $service = new ErrorService();
430
 
                $image = $service->ShowError("Not implemented");
431
 
                break;
432
 
            case "temp_sec":
433
 
                $service = new ErrorService();
434
 
                $image = $service->ShowError("Not implemented");
435
 
                break;
436
 
            default:
437
 
                $service = new ErrorService();
438
 
                $image = $service->ShowError("Target not valid");
439
 
                break;
440
 
        }
441
 
    }
442
 
    else
443
 
    {
444
 
        $service = new ErrorService();
445
 
        $image = $service->ShowError("No target");
446
 
    }
447
 
 
448
 
    if(!isset($image))
449
 
    {
450
 
        $service = new ErrorService();
451
 
        $image = $service->ShowError("Image creation failed!");
452
 
    }
453
 
    
454
 
    //here we handle the outputting of the image
455
 
    if($image instanceof Graph)
456
 
    {
457
 
        $image->Stroke();
458
 
    }
459
 
    else if(is_resource($image))
460
 
    {
461
 
        if(get_resource_type($image) === "gd")
462
 
            imagejpeg($image);
463
 
    }
464
 
    else
465
 
        echo $image;
466
 
 
467
 
?>
 
 
b'\\ No newline at end of file'