From 0e52941faa573b8cf01e7ed00ea0d253df19d602 Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Fri, 3 Jun 2011 22:28:56 +0530 Subject: [PATCH] GIS visualization to PDF --- libraries/gis/pma_gis_geometrycollection.php | 40 +++++++++++-- libraries/gis/pma_gis_linestring.php | 35 +++++++++++ libraries/gis/pma_gis_multilinestring.php | 40 +++++++++++++ libraries/gis/pma_gis_multipoint.php | 30 ++++++++++ libraries/gis/pma_gis_multipolygon.php | 48 +++++++++++++++ libraries/gis/pma_gis_point.php | 28 +++++++++ libraries/gis/pma_gis_polygon.php | 45 ++++++++++++++ libraries/gis/pma_gis_visualization.php | 62 ++++++++++++++++++-- 8 files changed, 318 insertions(+), 10 deletions(-) diff --git a/libraries/gis/pma_gis_geometrycollection.php b/libraries/gis/pma_gis_geometrycollection.php index 8825e783aa..00c87494ac 100644 --- a/libraries/gis/pma_gis_geometrycollection.php +++ b/libraries/gis/pma_gis_geometrycollection.php @@ -84,13 +84,13 @@ class PMA_GIS_Geometrycollection extends PMA_GIS_Geometry * * @param string $spatial GIS GEOMETRYCOLLECTION object * @param string $label Label for the GIS GEOMETRYCOLLECTION object - * @param string $line_color Color for the GIS GEOMETRYCOLLECTION object + * @param string $color Color for the GIS GEOMETRYCOLLECTION object * @param array $scale_data Array containing data related to scaling * @param image $image Image object * * @return the code related to a row in the GIS dataset */ - public function prepareRowAsPng($spatial, $label, $line_color, $scale_data, $image) + public function prepareRowAsPng($spatial, $label, $color, $scale_data, $image) { // Trim to remove leading 'GEOMETRYCOLLECTION(' and trailing ')' $goem_col = substr($spatial, 19, (strlen($spatial) - 20)); @@ -102,22 +102,50 @@ class PMA_GIS_Geometrycollection extends PMA_GIS_Geometry $type = substr($sub_part, 0, $type_pos); $gis_obj = PMA_GIS_Factory::factory($type); - $image = $gis_obj->prepareRowAsPng($sub_part, $label, $line_color, $scale_data, $image); + $image = $gis_obj->prepareRowAsPng($sub_part, $label, $color, $scale_data, $image); } return $image; } + /** + * Adds to the PDF object, the data related to a row in the GIS dataset. + * + * @param string $spatial GIS GEOMETRYCOLLECTION object + * @param string $label Label for the GIS GEOMETRYCOLLECTION object + * @param string $color Color for the GIS GEOMETRYCOLLECTION object + * @param array $scale_data Array containing data related to scaling + * @param image $pdf Pdf object + * + * @return the code related to a row in the GIS dataset + */ + public function prepareRowAsPdf($spatial, $label, $color, $scale_data, $pdf) + { + // Trim to remove leading 'GEOMETRYCOLLECTION(' and trailing ')' + $goem_col = substr($spatial, 19, (strlen($spatial) - 20)); + // Split the geometry collection object to get its constituents. + $sub_parts = $this->_explodeGeomCol($goem_col); + + foreach ($sub_parts as $sub_part) { + $type_pos = stripos($sub_part, '('); + $type = substr($sub_part, 0, $type_pos); + + $gis_obj = PMA_GIS_Factory::factory($type); + $image = $gis_obj->prepareRowAsPdf($sub_part, $label, $color, $scale_data, $pdf); + } + return $pdf; + } + /** * Prepares and returns the code related to a row in the GIS dataset as SVG. * * @param string $spatial GIS GEOMETRYCOLLECTION object * @param string $label Label for the GIS GEOMETRYCOLLECTION object - * @param string $line_color Color for the GIS GEOMETRYCOLLECTION object + * @param string $color Color for the GIS GEOMETRYCOLLECTION object * @param array $scale_data Array containing data related to scaling * * @return the code related to a row in the GIS dataset */ - public function prepareRowAsSvg($spatial, $label, $line_color, $scale_data) + public function prepareRowAsSvg($spatial, $label, $color, $scale_data) { $row = ''; @@ -131,7 +159,7 @@ class PMA_GIS_Geometrycollection extends PMA_GIS_Geometry $type = substr($sub_part, 0, $type_pos); $gis_obj = PMA_GIS_Factory::factory($type); - $row .= $gis_obj->prepareRowAsSvg($sub_part, $label, $line_color, $scale_data); + $row .= $gis_obj->prepareRowAsSvg($sub_part, $label, $color, $scale_data); } return $row; } diff --git a/libraries/gis/pma_gis_linestring.php b/libraries/gis/pma_gis_linestring.php index a4dd57da15..145d923ba3 100644 --- a/libraries/gis/pma_gis_linestring.php +++ b/libraries/gis/pma_gis_linestring.php @@ -80,6 +80,41 @@ class PMA_GIS_Linestring extends PMA_GIS_Geometry return $image; } + /** + * Adds to the PDF object, the data related to a row in the GIS dataset. + * + * @param string $spatial GIS LINESTRING object + * @param string $label Label for the GIS LINESTRING object + * @param string $line_color Color for the GIS LINESTRING object + * @param array $scale_data Array containing data related to scaling + * @param image $pdf Pdf object + * + * @return the code related to a row in the GIS dataset + */ + public function prepareRowAsPdf($spatial, $label, $line_color, $scale_data, $pdf) + { + // allocate colors + $r = hexdec(substr($line_color, 1, 2)); + $g = hexdec(substr($line_color, 3, 2)); + $b = hexdec(substr($line_color, 4, 2)); + $line = array('width' => 1.5, 'color' => array($r, $g, $b)); + + // Trim to remove leading 'LINESTRING(' and trailing ')' + $linesrting = substr($spatial, 11, (strlen($spatial) - 12)); + $points_arr = $this->extractPoints($linesrting, $scale_data); + + foreach ($points_arr as $point) { + if (! isset($temp_point)) { + $temp_point = $point; + } else { + // draw line section + $pdf->Line($temp_point[0], $temp_point[1], $point[0], $point[1], $line); + $temp_point = $point; + } + } + return $pdf; + } + /** * Prepares and returns the code related to a row in the GIS dataset as SVG. * diff --git a/libraries/gis/pma_gis_multilinestring.php b/libraries/gis/pma_gis_multilinestring.php index 882f1452e5..f5dde9ab29 100644 --- a/libraries/gis/pma_gis_multilinestring.php +++ b/libraries/gis/pma_gis_multilinestring.php @@ -94,6 +94,46 @@ class PMA_GIS_Multilinestring extends PMA_GIS_Geometry return $image; } + /** + * Adds to the PDF object, the data related to a row in the GIS dataset. + * + * @param string $spatial GIS MULTILINESTRING object + * @param string $label Label for the GIS MULTILINESTRING object + * @param string $line_color Color for the GIS MULTILINESTRING object + * @param array $scale_data Array containing data related to scaling + * @param image $pdf Pdf object + * + * @return the code related to a row in the GIS dataset + */ + public function prepareRowAsPdf($spatial, $label, $line_color, $scale_data, $pdf) + { + // allocate colors + $r = hexdec(substr($line_color, 1, 2)); + $g = hexdec(substr($line_color, 3, 2)); + $b = hexdec(substr($line_color, 4, 2)); + $line = array('width' => 1.5, 'color' => array($r, $g, $b)); + + // Trim to remove leading 'MULTILINESTRING((' and trailing '))' + $multilinestirng = substr($spatial, 17, (strlen($spatial) - 19)); + // Seperate each linestring + $linestirngs = explode("),(", $multilinestirng); + + foreach ($linestirngs as $linestring) { + $points_arr = $this->extractPoints($linestring, $scale_data); + foreach ($points_arr as $point) { + if (! isset($temp_point)) { + $temp_point = $point; + } else { + // draw line section + $pdf->Line($temp_point[0], $temp_point[1], $point[0], $point[1], $line); + $temp_point = $point; + } + } + unset($temp_point); + } + return $pdf; + } + /** * Prepares and returns the code related to a row in the GIS dataset as SVG. * diff --git a/libraries/gis/pma_gis_multipoint.php b/libraries/gis/pma_gis_multipoint.php index 57406bafb7..df9d7c2abf 100644 --- a/libraries/gis/pma_gis_multipoint.php +++ b/libraries/gis/pma_gis_multipoint.php @@ -75,6 +75,36 @@ class PMA_GIS_Multipoint extends PMA_GIS_Geometry return $image; } + /** + * Adds to the PDF object, the data related to a row in the GIS dataset. + * + * @param string $spatial GIS MULTIPOINT object + * @param string $label Label for the GIS MULTIPOINT object + * @param string $line_color Color for the GIS MULTIPOINT object + * @param array $scale_data Array containing data related to scaling + * @param image $pdf Pdf object + * + * @return the code related to a row in the GIS dataset + */ + public function prepareRowAsPdf($spatial, $label, $line_color, $scale_data, $pdf) + { + // allocate colors + $r = hexdec(substr($line_color, 1, 2)); + $g = hexdec(substr($line_color, 3, 2)); + $b = hexdec(substr($line_color, 4, 2)); + $line = array('width' => 1.25, 'color' => array($r, $g, $b)); + + // Trim to remove leading 'MULTIPOINT(' and trailing ')' + $multipoint = substr($spatial, 11, (strlen($spatial) - 12)); + $points_arr = $this->extractPoints($multipoint, $scale_data); + + foreach ($points_arr as $point) { + // draw a small circle to mark the point + $pdf->Circle($point[0], $point[1], 2, 0, 360, 'D', $line); + } + return $pdf; + } + /** * Prepares and returns the code related to a row in the GIS dataset as SVG. * diff --git a/libraries/gis/pma_gis_multipolygon.php b/libraries/gis/pma_gis_multipolygon.php index f38c0d9726..24536de3d8 100644 --- a/libraries/gis/pma_gis_multipolygon.php +++ b/libraries/gis/pma_gis_multipolygon.php @@ -116,6 +116,54 @@ class PMA_GIS_Multipolygon extends PMA_GIS_Geometry return $image; } + /** + * Adds to the PDF object, the data related to a row in the GIS dataset. + * + * @param string $spatial GIS MULTIPOLYGON object + * @param string $label Label for the GIS MULTIPOLYGON object + * @param string $fill_color Color for the GIS MULTIPOLYGON object + * @param array $scale_data Array containing data related to scaling + * @param image $pdf Pdf object + * + * @return the code related to a row in the GIS dataset + */ + public function prepareRowAsPdf($spatial, $label, $fill_color, $scale_data, $pdf) + { + // allocate colors + $r = hexdec(substr($fill_color, 1, 2)); + $g = hexdec(substr($fill_color, 3, 2)); + $b = hexdec(substr($fill_color, 4, 2)); + $color = array($r, $g, $b); + + // Trim to remove leading 'MULTIPOLYGON(((' and trailing ')))' + $multipolygon = substr($spatial, 15, (strlen($spatial) - 18)); + // Seperate each polygon + $polygons = explode(")),((", $multipolygon); + + foreach ($polygons as $polygon) { + // If the polygon doesnt have an inner polygon + if (strpos($polygon, "),(") === false) { + $points_arr = $this->extractPoints($polygon, $scale_data, true); + } else { + // Seperate outer and inner polygons + $parts = explode("),(", $polygon); + $outer = $parts[0]; + $inner = array_slice($parts, 1); + + $points_arr = $this->extractPoints($outer, $scale_data, true); + + foreach ($inner as $inner_poly) { + $points_arr = array_merge( + $points_arr, $this->extractPoints($inner_poly, $scale_data, true) + ); + } + } + // draw polygon + $pdf->Polygon($points_arr, 'F*', array(), $color, true); + } + return $pdf; + } + /** * Prepares and returns the code related to a row in the GIS dataset as SVG. * diff --git a/libraries/gis/pma_gis_point.php b/libraries/gis/pma_gis_point.php index c1a2ec7717..0ed8beaa70 100644 --- a/libraries/gis/pma_gis_point.php +++ b/libraries/gis/pma_gis_point.php @@ -73,6 +73,34 @@ class PMA_GIS_Point extends PMA_GIS_Geometry return $image; } + /** + * Adds to the PDF object, the data related to a row in the GIS dataset. + * + * @param string $spatial GIS POINT object + * @param string $label Label for the GIS POINT object + * @param string $line_color Color for the GIS POINT object + * @param array $scale_data Array containing data related to scaling + * @param image $pdf Pdf object + * + * @return the code related to a row in the GIS dataset + */ + public function prepareRowAsPdf($spatial, $label, $line_color, $scale_data, $pdf) + { + // allocate colors + $r = hexdec(substr($line_color, 1, 2)); + $g = hexdec(substr($line_color, 3, 2)); + $b = hexdec(substr($line_color, 4, 2)); + $line = array('width' => 1.25, 'color' => array($r, $g, $b)); + + // Trim to remove leading 'POINT(' and trailing ')' + $point = substr($spatial, 6, (strlen($spatial) - 7)); + $points_arr = $this->extractPoints($point, $scale_data); + + // draw a small circle to mark the point + $pdf->Circle($points_arr[0][0], $points_arr[0][1], 2, 0, 360, 'D', $line); + return $pdf; + } + /** * Prepares and returns the code related to a row in the GIS dataset as SVG. * diff --git a/libraries/gis/pma_gis_polygon.php b/libraries/gis/pma_gis_polygon.php index 742a44fbe0..5cff40042c 100644 --- a/libraries/gis/pma_gis_polygon.php +++ b/libraries/gis/pma_gis_polygon.php @@ -108,6 +108,51 @@ class PMA_GIS_Polygon extends PMA_GIS_Geometry return $image; } + /** + * Adds to the PDF object, the data related to a row in the GIS dataset. + * + * @param string $spatial GIS POLYGON object + * @param string $label Label for the GIS POLYGON object + * @param string $fill_color Color for the GIS POLYGON object + * @param array $scale_data Array containing data related to scaling + * @param image $pdf Pdf object + * + * @return the code related to a row in the GIS dataset + */ + public function prepareRowAsPdf($spatial, $label, $fill_color, $scale_data, $pdf) + { + // allocate colors + $r = hexdec(substr($fill_color, 1, 2)); + $g = hexdec(substr($fill_color, 3, 2)); + $b = hexdec(substr($fill_color, 4, 2)); + $color = array($r, $g, $b); + + // Trim to remove leading 'POLYGON((' and trailing '))' + $polygon = substr($spatial, 9, (strlen($spatial) - 11)); + + // If the polygon doesnt have an inner polygon + if (strpos($polygon, "),(") === false) { + $points_arr = $this->extractPoints($polygon, $scale_data, true); + } else { + // Seperate outer and inner polygons + $parts = explode("),(", $polygon); + $outer = $parts[0]; + $inner = array_slice($parts, 1); + + $points_arr = $this->extractPoints($outer, $scale_data, true); + + foreach ($inner as $inner_poly) { + $points_arr = array_merge( + $points_arr, $this->extractPoints($inner_poly, $scale_data, true) + ); + } + } + + // draw polygon + $pdf->Polygon($points_arr, 'F*', array(), $color, true); + return $pdf; + } + /** * Prepares and returns the code related to a row in the GIS dataset as SVG. * diff --git a/libraries/gis/pma_gis_visualization.php b/libraries/gis/pma_gis_visualization.php index d3d788eb05..1b63085325 100644 --- a/libraries/gis/pma_gis_visualization.php +++ b/libraries/gis/pma_gis_visualization.php @@ -92,16 +92,17 @@ class PMA_GIS_Visualization } /** - * Handles common tasks of writing the visualization to file for various formats. + * Sanitizes the file name. * * @param string $file_name file name - * @param string $type mime type * @param string $ext extension of the file + * + * @return the sanitized file name */ - private function _toFile($file_name, $type, $ext) + private function _sanitizeName($file_name, $ext) { // convert filename to iso-8859-1, it is safer - $file_name = PMA_convert_string('', 'iso-8859-1', $file_name); + $file_name = PMA_convert_string('utf-8', 'iso-8859-1', $file_name); // Check if the user already added extension; // get the substring where the extension would be if it was included @@ -111,6 +112,19 @@ class PMA_GIS_Visualization if (strtolower($user_extension) != $required_extension) { $file_name .= $required_extension; } + return $file_name; + } + + /** + * Handles common tasks of writing the visualization to file for various formats. + * + * @param string $file_name file name + * @param string $type mime type + * @param string $ext extension of the file + */ + private function _toFile($file_name, $type, $ext) + { + $file_name = $this->_sanitizeName($file_name); ob_clean(); @@ -229,6 +243,40 @@ class PMA_GIS_Visualization imagedestroy($img); } + /** + * Saves as a PDF to a file. + * + * @param string $file_name File name + */ + public function toFileAsPdf($file_name) + { + $this->init(); + + include_once './libraries/tcpdf/tcpdf.php'; + + // create pdf + $pdf = new TCPDF('', 'pt', 'A4', true, 'UTF-8', false); + + // disable header and footer + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); + + //set auto page breaks + $pdf->SetAutoPageBreak(false); + + // add a page + $pdf->AddPage(); + + $scale_data = $this->_scaleDataSet($this->_data); + $pdf = $this->_prepareDataSet($this->_data, 0, $scale_data, 'pdf', $pdf); + + // sanitize file name + $file_name = $this->_sanitizeName($file_name, 'pdf'); + + ob_clean(); + $pdf->Output($file_name, 'D'); + } + /** * Calculates the scale, horizontal and vertical offset that should be used. * @@ -340,6 +388,11 @@ class PMA_GIS_Visualization $row[$this->_settings['spatialColumn']], $label, $this->_settings['colors'][$index], $scale_data, $results ); + } elseif ($format == 'pdf') { + $results = $gis_obj->prepareRowAsPdf( + $row[$this->_settings['spatialColumn']], $label, + $this->_settings['colors'][$index], $scale_data, $results + ); } $color_number++; } @@ -347,3 +400,4 @@ class PMA_GIS_Visualization } } ?> +