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: imagesavealpha($im, true);
177: imagepng($im , $imagename);
178:
179: }
180:
181: $finalimagename = $tempdir.'/mergedimage.png';
182: $finalImage = imagecreatetruecolor($this->image_width, $this->image_height);
183: $bg = ImageColorAllocate($finalImage, 255, 255, 255);
184: imagefilledrectangle($finalImage,0,0,$this->image_width, $this->image_height,$bg);
185: imagepng($finalImage , $finalimagename);
186: foreach ($this->layer_urls as $k => $url)
187: {
188: $dest = imagecreatefrompng($finalimagename);
189: $src = imagecreatefrompng($tempdir.'/tempimage'.$k);
190: imagecopy($dest, $src, 0, 0, 0, 0, $this->image_width , $this->image_height);
191: imagepng($dest , $finalimagename);
192: unlink($tempdir.'/tempimage'.$k);
193: }
194: }
195:
196: 197: 198: 199:
200: private function rotate()
201: {
202: $tempdir = $this->tempdir;
203: $rotation = $this->data['rotation'];
204:
205: foreach ($this->layer_urls as $k => $url)
206: {
207: $map_width = $this->data['extent']['width'];
208: $map_height = $this->data['extent']['height'];
209: $centerx = $this->data['center']['x'];
210: $centery = $this->data['center']['y'];
211:
212:
213: $neededExtentWidth = round(abs(sin(deg2rad($rotation))*$map_height)+abs(cos(deg2rad($rotation))*$map_width));
214: $neededExtentHeight = round(abs(sin(deg2rad($rotation))*$map_width)+abs(cos(deg2rad($rotation))*$map_height));
215:
216: $ll_x = $centerx - $neededExtentWidth * 0.5;
217: $ll_y = $centery - $neededExtentHeight * 0.5;
218: $ur_x = $centerx + $neededExtentWidth * 0.5;
219: $ur_y = $centery + $neededExtentHeight * 0.5;
220:
221: $bbox = 'BBOX='.$ll_x.','.$ll_y.','.$ur_x.','.$ur_y;
222: $url .= $bbox;
223: $this->layer_urls[$k] = $url;
224:
225:
226: $neededImageWidth = round(abs(sin(deg2rad($rotation))*$this->image_height)+abs(cos(deg2rad($rotation))*$this->image_width));
227: $neededImageHeight = round(abs(sin(deg2rad($rotation))*$this->image_width)+abs(cos(deg2rad($rotation))*$this->image_height));
228:
229: $w = '&WIDTH='.$neededImageWidth;
230: $h = '&HEIGHT='.$neededImageHeight;
231: $url .= $w.$h;
232: $this->layer_urls[$k] = $url;
233:
234:
235: $attributes = array();
236: $attributes['_controller'] = 'OwsProxy3CoreBundle:OwsProxy:entryPoint';
237: $subRequest = new Request(array(
238: 'url' => $url
239: ), array(), $attributes, array(), array(), array(), '');
240: $response = $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
241:
242: $tempdir = $this->tempdir;
243: $imagename = $tempdir.'/tempimage'.$k;
244:
245: file_put_contents($imagename, $response->getContent());
246:
247: switch(trim($response->headers->get('content-type'))) {
248: case 'image/png' :
249: $im = imagecreatefrompng($imagename);
250: break;
251: case 'image/jpeg' :
252: $im = imagecreatefromjpeg($imagename);
253: break;
254: case 'image/gif' :
255: $im = imagecreatefromgif($imagename);
256: break;
257: default:
258: continue;
259:
260: }
261:
262:
263: $transColor = imagecolorallocatealpha($im, 255, 255, 255, 127);
264: $rotatedImage = imagerotate($im , $rotation, $transColor);
265: imagealphablending($rotatedImage, false);
266: imagesavealpha($rotatedImage, true);
267: imagepng($rotatedImage , $imagename);
268:
269:
270: $rotated_width = round(abs(sin(deg2rad($rotation))*$neededImageHeight)+abs(cos(deg2rad($rotation))*$neededImageWidth));
271: $rotated_height = round(abs(sin(deg2rad($rotation))*$neededImageWidth)+abs(cos(deg2rad($rotation))*$neededImageHeight));
272: $newx = ($rotated_width - $this->image_width ) / 2 ;
273: $newy = ($rotated_height - $this->image_height ) / 2 ;
274:
275: $clippedImageName = $tempdir.'/clipped_image'.$k.'.png';
276: $clippedImage = imagecreatetruecolor($this->image_width, $this->image_height);
277:
278: imagealphablending($clippedImage, false);
279: imagesavealpha($clippedImage, true);
280:
281: imagecopy($clippedImage , $rotatedImage , 0 , 0 , $newx , $newy , $this->image_width , $this->image_height );
282: imagepng($clippedImage , $clippedImageName);
283:
284: unlink($tempdir.'/tempimage'.$k);
285: }
286:
287: $finalimagename = $tempdir.'/mergedimage.png';
288: $finalImage = imagecreatetruecolor($this->image_width, $this->image_height);
289: $bg = ImageColorAllocate($finalImage, 255, 255, 255);
290: imagefilledrectangle($finalImage,0,0,$this->image_width, $this->image_height,$bg);
291: imagepng($finalImage , $finalimagename);
292: foreach ($this->layer_urls as $k => $url)
293: {
294: $dest = imagecreatefrompng($finalimagename);
295: $src = imagecreatefrompng($tempdir.'/clipped_image'.$k.'.png');
296: imagecopy($dest, $src, 0, 0, 0, 0, $this->image_width , $this->image_height);
297: imagepng($dest , $finalimagename);
298: unlink($tempdir.'/clipped_image'.$k.'.png');
299: }
300: }
301:
302: 303: 304: 305:
306: private function buildPdf()
307: {
308: require('PDF_ImageAlpha.php');
309: $tempdir = $this->tempdir;
310: $resource_dir = $this->container->getParameter('kernel.root_dir') . '/Resources/MapbenderPrintBundle';
311: $format = substr($this->data['template'],0,2);
312: $this->pdf = new PDF_ImageAlpha($this->orientation,'mm',$format);
313:
314: $pdf = $this->pdf;
315: $template = $this->data['template'];
316: $pdffile = $resource_dir.'/templates/'.$template.'.pdf';
317: $pagecount = $pdf->setSourceFile($pdffile);
318: $tplidx = $pdf->importPage(1);
319:
320: $pdf->addPage();
321: $pdf->useTemplate($tplidx);
322:
323: foreach ($this->conf['fields'] as $k => $v) {
324: $pdf->SetFont('Arial','',$this->conf['fields'][$k]['fontsize']);
325: $pdf->SetXY($this->conf['fields'][$k]['x']*10, $this->conf['fields'][$k]['y']*10);
326: switch($k) {
327: case 'date' :
328: $date = new \DateTime;
329: $pdf->Cell($this->conf['fields']['date']['width']*10,$this->conf['fields']['date']['height']*10,$date->format('d.m.Y'));
330: break;
331: case 'scale' :
332: if (isset($this->data['scale_select']))
333: {
334: $pdf->Cell($this->conf['fields']['scale']['width']*10,$this->conf['fields']['scale']['height']*10,'1 : '.$this->data['scale_select']);
335: }else{
336: $pdf->Cell($this->conf['fields']['scale']['width']*10,$this->conf['fields']['scale']['height']*10,'1 : '.$this->data['scale_text']);
337: }
338: break;
339: default:
340: if (isset($this->data['extra'][$k]))
341: {
342: $pdf->Cell($this->conf['fields'][$k]['width']*10,$this->conf['fields'][$k]['height']*10,$this->data['extra'][$k]);
343: }
344: break;
345: }
346: }
347:
348: if ($this->data['rotation'] == 0)
349: {
350: $tempdir = sys_get_temp_dir();
351: foreach ($this->layer_urls as $k => $url)
352:
353:
354:
355:
356:
357:
358:
359:
360:
361: $pdf->Image($tempdir.'/mergedimage.png',
362: $this->x_ul,
363: $this->y_ul,
364: $this->width,
365: $this->height,
366: 'png','',false,0,5,-1*0);
367:
368: $pdf->Rect($this->x_ul, $this->y_ul, $this->width, $this->height);
369: $pdf->Image($resource_dir.'/images/northarrow.png',
370: $this->conf['northarrow']['x']*10,
371: $this->conf['northarrow']['y']*10,
372: $this->conf['northarrow']['width']*10,
373: $this->conf['northarrow']['height']*10);
374:
375: }else{
376: $this->rotateNorthArrow();
377:
378:
379:
380:
381:
382:
383:
384:
385:
386: $pdf->Image($tempdir.'/mergedimage.png',
387: $this->x_ul,
388: $this->y_ul,
389: $this->width,
390: $this->height,
391: 'png','',false,0,5,-1*0);
392:
393: $pdf->Rect($this->x_ul, $this->y_ul, $this->width, $this->height);
394: }
395:
396:
397: $pdf->Output();
398: }
399:
400: 401: 402: 403:
404: private function rotateNorthArrow()
405: {
406: $tempdir = $this->tempdir;
407: $resource_dir = $this->container->getParameter('kernel.root_dir') . '/Resources/MapbenderPrintBundle';
408: $rotation = $this->data['rotation'];
409: $northarrow = $resource_dir.'/images/northarrow.png';
410: $im = imagecreatefrompng($northarrow);
411: $transColor = imagecolorallocatealpha($im, 255, 255, 255, 127);
412: $rotated = imagerotate($im , $rotation ,$transColor);
413: imagepng($rotated , $tempdir.'/rotatednorth.png');
414:
415: if ($rotation == 90 || $rotation == 270)
416: {
417:
418: }else{
419: $src_img = imagecreatefrompng($tempdir.'/rotatednorth.png');
420: $srcsize = getimagesize($tempdir.'/rotatednorth.png');
421: $destsize = getimagesize($resource_dir.'/images/northarrow.png');
422: $x = ($srcsize[0] - $destsize[0]) / 2;
423: $y = ($srcsize[1] - $destsize[1]) / 2;
424: $dst_img = imagecreatetruecolor($destsize[0], $destsize[1]);
425: imagecopy($dst_img, $src_img, 0, 0, $x, $y,$srcsize[0], $srcsize[1]);
426: imagepng($dst_img, $tempdir.'/rotatednorth.png');
427: }
428:
429: $this->pdf->Image($tempdir.'/rotatednorth.png',
430: $this->conf['northarrow']['x']*10,
431: $this->conf['northarrow']['y']*10,
432: $this->conf['northarrow']['width']*10,
433: $this->conf['northarrow']['height']*10);
434: unlink($tempdir.'/rotatednorth.png');
435: }
436: }