1: <?php
2:
3: namespace Mapbender\PrintBundle\Component;
4:
5: use Symfony\Component\HttpFoundation\Request;
6: use Symfony\Component\HttpFoundation\Response;
7: use Symfony\Component\HttpKernel\HttpKernelInterface;
8: use FPDF_FPDF;
9: use FPDF_FPDI;
10: use Mapbender\PrintBundle\Component\PDF_ImageAlpha;
11:
12: 13: 14: 15: 16:
17: class PrintService
18: {
19: public function __construct($container)
20: {
21: $this->container = $container;
22: $this->tempdir = sys_get_temp_dir();
23: }
24:
25: 26: 27: 28:
29: public function doPrint($content)
30: {
31: $this->data = json_decode($content, true);
32: $template = $this->data['template'];
33:
34:
35:
36:
37: $this->getTemplateConf($template);
38: $this->createUrlArray();
39: $this->setMapParameter();
40:
41: if ($this->data['rotation'] == 0)
42: {
43: $this->setExtent();
44: $this->setImageSize();
45: $this->getImages();
46: }else{
47: $this->rotate();
48: }
49:
50: $this->buildPdf();
51: }
52:
53: 54: 55: 56:
57: private function getTemplateConf($template)
58: {
59: $odgParser = new OdgParser($this->container);
60: $this->conf = $odgParser->getConf($template);
61:
62:
63:
64:
65: }
66:
67: 68: 69: 70:
71: private function createUrlArray()
72: {
73: foreach ($this->data['layers'] as $i => $layer)
74: {
75: $url = strstr($this->data['layers'][$i]['url'], 'BBOX', true);
76: $this->layer_urls[$i] = $url;
77: }
78: }
79:
80: 81: 82: 83:
84: private function setMapParameter()
85: {
86: $conf = $this->conf;
87: $quality = $this->data['quality'];
88: $this->orientation = $conf['orientation'];
89: $this->x_ul = $conf['map']['x']*10;
90: $this->y_ul = $conf['map']['y']*10;
91: $this->width = $conf['map']['width']*10;
92: $this->height = $conf['map']['height']*10;
93: $this->image_width = round($conf['map']['width'] / 2.54 * $quality);
94: $this->image_height = round($conf['map']['height'] / 2.54 * $quality);
95: }
96:
97: 98: 99: 100:
101: private function setExtent()
102: {
103: $map_width = $this->data['extent']['width'];
104: $map_height = $this->data['extent']['height'];
105: $centerx = $this->data['center']['x'];
106: $centery = $this->data['center']['y'];
107:
108: $ll_x = $centerx - $map_width * 0.5;
109: $ll_y = $centery - $map_height * 0.5;
110: $ur_x = $centerx + $map_width * 0.5;
111: $ur_y = $centery + $map_height * 0.5;
112:
113: $bbox = 'BBOX='.$ll_x.','.$ll_y.','.$ur_x.','.$ur_y;
114:
115: foreach ($this->layer_urls as $k => $url) {
116: $url .= $bbox;
117: $this->layer_urls[$k] = $url;
118: }
119: }
120:
121: 122: 123: 124:
125: private function setImageSize()
126: {
127: foreach ($this->layer_urls as $k => $url)
128: {
129: $width = '&WIDTH='.$this->image_width;
130: $height = '&HEIGHT='.$this->image_height;
131: $url .= $width.$height;
132: if ($this->data['quality'] == '288')
133: {
134: $url .= '&map_resolution=288';
135: }
136: $this->layer_urls[$k] = $url;
137: }
138: }
139:
140: 141: 142: 143:
144: private function getImages()
145: {
146: foreach ($this->layer_urls as $k => $url)
147: {
148: $attributes = array();
149: $attributes['_controller'] = 'OwsProxy3CoreBundle:OwsProxy:entryPoint';
150: $subRequest = new Request(array(
151: 'url' => $url
152: ), array(), $attributes, array(), array(), array(), '');
153: $response = $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
154:
155: $tempdir = $this->tempdir;
156: $imagename = $tempdir.'/tempimage'.$k;
157:
158: file_put_contents($imagename, $response->getContent());
159:
160: switch(trim($response->headers->get('content-type'))) {
161: case 'image/png' :
162: $im = imagecreatefrompng($imagename);
163: break;
164: case 'image/jpeg' :
165: $im = imagecreatefromjpeg($imagename);
166: break;
167: case 'image/gif' :
168: $im = imagecreatefromgif($imagename);
169: break;
170: default:
171: continue;
172: $this->container->get("logger")->debug("Unknown mimetype " . trim($response->headers->get('content-type')));
173:
174: }
175:
176: if(isset($im)) {
177: imagesavealpha($im, true);
178: imagepng($im , $imagename);
179: }
180:
181: }
182:
183: $finalimagename = $tempdir.'/mergedimage.png';
184: $finalImage = imagecreatetruecolor($this->image_width, $this->image_height);
185: $bg = ImageColorAllocate($finalImage, 255, 255, 255);
186: imagefilledrectangle($finalImage,0,0,$this->image_width, $this->image_height,$bg);
187: imagepng($finalImage , $finalimagename);
188: foreach ($this->layer_urls as $k => $url)
189: {
190: if(is_file($tempdir.'/tempimage'.$k) && mime_content_type($tempdir.'/tempimage'.$k) == 'image/png') {
191: $dest = imagecreatefrompng($finalimagename);
192: $src = imagecreatefrompng($tempdir.'/tempimage'.$k);
193: imagecopy($dest, $src, 0, 0, 0, 0, $this->image_width , $this->image_height);
194: imagepng($dest , $finalimagename);
195: }
196: unlink($tempdir.'/tempimage'.$k);
197: }
198: }
199:
200: 201: 202: 203:
204: private function rotate()
205: {
206: $tempdir = $this->tempdir;
207: $rotation = $this->data['rotation'];
208:
209: foreach ($this->layer_urls as $k => $url)
210: {
211: $map_width = $this->data['extent']['width'];
212: $map_height = $this->data['extent']['height'];
213: $centerx = $this->data['center']['x'];
214: $centery = $this->data['center']['y'];
215:
216:
217: $neededExtentWidth = round(abs(sin(deg2rad($rotation))*$map_height)+abs(cos(deg2rad($rotation))*$map_width));
218: $neededExtentHeight = round(abs(sin(deg2rad($rotation))*$map_width)+abs(cos(deg2rad($rotation))*$map_height));
219:
220: $ll_x = $centerx - $neededExtentWidth * 0.5;
221: $ll_y = $centery - $neededExtentHeight * 0.5;
222: $ur_x = $centerx + $neededExtentWidth * 0.5;
223: $ur_y = $centery + $neededExtentHeight * 0.5;
224:
225: $bbox = 'BBOX='.$ll_x.','.$ll_y.','.$ur_x.','.$ur_y;
226: $url .= $bbox;
227: $this->layer_urls[$k] = $url;
228:
229:
230: $neededImageWidth = round(abs(sin(deg2rad($rotation))*$this->image_height)+abs(cos(deg2rad($rotation))*$this->image_width));
231: $neededImageHeight = round(abs(sin(deg2rad($rotation))*$this->image_width)+abs(cos(deg2rad($rotation))*$this->image_height));
232:
233: $w = '&WIDTH='.$neededImageWidth;
234: $h = '&HEIGHT='.$neededImageHeight;
235: $url .= $w.$h;
236: $this->layer_urls[$k] = $url;
237:
238:
239: $attributes = array();
240: $attributes['_controller'] = 'OwsProxy3CoreBundle:OwsProxy:entryPoint';
241: $subRequest = new Request(array(
242: 'url' => $url
243: ), array(), $attributes, array(), array(), array(), '');
244: $response = $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
245:
246: $tempdir = $this->tempdir;
247: $imagename = $tempdir.'/tempimage'.$k;
248:
249: file_put_contents($imagename, $response->getContent());
250:
251: switch(trim($response->headers->get('content-type'))) {
252: case 'image/png' :
253: $im = imagecreatefrompng($imagename);
254: break;
255: case 'image/jpeg' :
256: $im = imagecreatefromjpeg($imagename);
257: break;
258: case 'image/gif' :
259: $im = imagecreatefromgif($imagename);
260: break;
261: default:
262: continue;
263:
264: }
265:
266:
267: $transColor = imagecolorallocatealpha($im, 255, 255, 255, 127);
268: $rotatedImage = imagerotate($im , $rotation, $transColor);
269: imagealphablending($rotatedImage, false);
270: imagesavealpha($rotatedImage, true);
271: imagepng($rotatedImage , $imagename);
272:
273:
274: $rotated_width = round(abs(sin(deg2rad($rotation))*$neededImageHeight)+abs(cos(deg2rad($rotation))*$neededImageWidth));
275: $rotated_height = round(abs(sin(deg2rad($rotation))*$neededImageWidth)+abs(cos(deg2rad($rotation))*$neededImageHeight));
276: $newx = ($rotated_width - $this->image_width ) / 2 ;
277: $newy = ($rotated_height - $this->image_height ) / 2 ;
278:
279: $clippedImageName = $tempdir.'/clipped_image'.$k.'.png';
280: $clippedImage = imagecreatetruecolor($this->image_width, $this->image_height);
281:
282: imagealphablending($clippedImage, false);
283: imagesavealpha($clippedImage, true);
284:
285: imagecopy($clippedImage , $rotatedImage , 0 , 0 , $newx , $newy , $this->image_width , $this->image_height );
286: imagepng($clippedImage , $clippedImageName);
287:
288: unlink($tempdir.'/tempimage'.$k);
289: }
290:
291: $finalimagename = $tempdir.'/mergedimage.png';
292: $finalImage = imagecreatetruecolor($this->image_width, $this->image_height);
293: $bg = ImageColorAllocate($finalImage, 255, 255, 255);
294: imagefilledrectangle($finalImage,0,0,$this->image_width, $this->image_height,$bg);
295: imagepng($finalImage , $finalimagename);
296: foreach ($this->layer_urls as $k => $url)
297: {
298: $dest = imagecreatefrompng($finalimagename);
299: $src = imagecreatefrompng($tempdir.'/clipped_image'.$k.'.png');
300: imagecopy($dest, $src, 0, 0, 0, 0, $this->image_width , $this->image_height);
301: imagepng($dest , $finalimagename);
302: unlink($tempdir.'/clipped_image'.$k.'.png');
303: }
304: }
305:
306: 307: 308: 309:
310: private function buildPdf()
311: {
312: require('PDF_ImageAlpha.php');
313: $tempdir = $this->tempdir;
314: $resource_dir = $this->container->getParameter('kernel.root_dir') . '/Resources/MapbenderPrintBundle';
315: $format = substr($this->data['template'],0,2);
316: $this->pdf = new PDF_ImageAlpha($this->orientation,'mm',$format);
317:
318: $pdf = $this->pdf;
319: $template = $this->data['template'];
320: $pdffile = $resource_dir.'/templates/'.$template.'.pdf';
321: $pagecount = $pdf->setSourceFile($pdffile);
322: $tplidx = $pdf->importPage(1);
323:
324: $pdf->addPage();
325: $pdf->useTemplate($tplidx);
326:
327: foreach ($this->conf['fields'] as $k => $v) {
328: $pdf->SetFont('Arial','',$this->conf['fields'][$k]['fontsize']);
329: $pdf->SetXY($this->conf['fields'][$k]['x']*10, $this->conf['fields'][$k]['y']*10);
330: switch($k) {
331: case 'date' :
332: $date = new \DateTime;
333: $pdf->Cell($this->conf['fields']['date']['width']*10,$this->conf['fields']['date']['height']*10,$date->format('d.m.Y'));
334: break;
335: case 'scale' :
336: if (isset($this->data['scale_select']))
337: {
338: $pdf->Cell($this->conf['fields']['scale']['width']*10,$this->conf['fields']['scale']['height']*10,'1 : '.$this->data['scale_select']);
339: }else{
340: $pdf->Cell($this->conf['fields']['scale']['width']*10,$this->conf['fields']['scale']['height']*10,'1 : '.$this->data['scale_text']);
341: }
342: break;
343: default:
344: if (isset($this->data['extra'][$k]))
345: {
346: $pdf->Cell($this->conf['fields'][$k]['width']*10,$this->conf['fields'][$k]['height']*10,utf8_decode($this->data['extra'][$k]));
347: }
348: break;
349: }
350: }
351:
352: if ($this->data['rotation'] == 0)
353: {
354: $tempdir = sys_get_temp_dir();
355: foreach ($this->layer_urls as $k => $url)
356:
357:
358:
359:
360:
361:
362:
363:
364:
365: $pdf->Image($tempdir.'/mergedimage.png',
366: $this->x_ul,
367: $this->y_ul,
368: $this->width,
369: $this->height,
370: 'png','',false,0,5,-1*0);
371:
372: $pdf->Rect($this->x_ul, $this->y_ul, $this->width, $this->height);
373: $pdf->Image($resource_dir.'/images/northarrow.png',
374: $this->conf['northarrow']['x']*10,
375: $this->conf['northarrow']['y']*10,
376: $this->conf['northarrow']['width']*10,
377: $this->conf['northarrow']['height']*10);
378:
379: }else{
380: $this->rotateNorthArrow();
381:
382:
383:
384:
385:
386:
387:
388:
389:
390: $pdf->Image($tempdir.'/mergedimage.png',
391: $this->x_ul,
392: $this->y_ul,
393: $this->width,
394: $this->height,
395: 'png','',false,0,5,-1*0);
396:
397: $pdf->Rect($this->x_ul, $this->y_ul, $this->width, $this->height);
398: }
399:
400:
401: $pdf->Output();
402: }
403:
404: 405: 406: 407:
408: private function rotateNorthArrow()
409: {
410: $tempdir = $this->tempdir;
411: $resource_dir = $this->container->getParameter('kernel.root_dir') . '/Resources/MapbenderPrintBundle';
412: $rotation = $this->data['rotation'];
413: $northarrow = $resource_dir.'/images/northarrow.png';
414: $im = imagecreatefrompng($northarrow);
415: $transColor = imagecolorallocatealpha($im, 255, 255, 255, 127);
416: $rotated = imagerotate($im , $rotation ,$transColor);
417: imagepng($rotated , $tempdir.'/rotatednorth.png');
418:
419: if ($rotation == 90 || $rotation == 270)
420: {
421:
422: }else{
423: $src_img = imagecreatefrompng($tempdir.'/rotatednorth.png');
424: $srcsize = getimagesize($tempdir.'/rotatednorth.png');
425: $destsize = getimagesize($resource_dir.'/images/northarrow.png');
426: $x = ($srcsize[0] - $destsize[0]) / 2;
427: $y = ($srcsize[1] - $destsize[1]) / 2;
428: $dst_img = imagecreatetruecolor($destsize[0], $destsize[1]);
429: imagecopy($dst_img, $src_img, 0, 0, $x, $y,$srcsize[0], $srcsize[1]);
430: imagepng($dst_img, $tempdir.'/rotatednorth.png');
431: }
432:
433: $this->pdf->Image($tempdir.'/rotatednorth.png',
434: $this->conf['northarrow']['x']*10,
435: $this->conf['northarrow']['y']*10,
436: $this->conf['northarrow']['width']*10,
437: $this->conf['northarrow']['height']*10);
438: unlink($tempdir.'/rotatednorth.png');
439: }
440:
441: }
442: