GisMultiLineString.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Handles actions related to GIS MULTILINESTRING objects
  5. *
  6. * @package PhpMyAdmin-GIS
  7. */
  8. namespace PhpMyAdmin\Gis;
  9. use TCPDF;
  10. /**
  11. * Handles actions related to GIS MULTILINESTRING objects
  12. *
  13. * @package PhpMyAdmin-GIS
  14. */
  15. class GisMultiLineString extends GisGeometry
  16. {
  17. // Hold the singleton instance of the class
  18. private static $_instance;
  19. /**
  20. * A private constructor; prevents direct creation of object.
  21. *
  22. * @access private
  23. */
  24. private function __construct()
  25. {
  26. }
  27. /**
  28. * Returns the singleton.
  29. *
  30. * @return GisMultiLineString the singleton
  31. * @access public
  32. */
  33. public static function singleton()
  34. {
  35. if (!isset(self::$_instance)) {
  36. $class = __CLASS__;
  37. self::$_instance = new $class;
  38. }
  39. return self::$_instance;
  40. }
  41. /**
  42. * Scales each row.
  43. *
  44. * @param string $spatial spatial data of a row
  45. *
  46. * @return array an array containing the min, max values for x and y coordinates
  47. * @access public
  48. */
  49. public function scaleRow($spatial)
  50. {
  51. $min_max = array();
  52. // Trim to remove leading 'MULTILINESTRING((' and trailing '))'
  53. $multilinestirng
  54. = mb_substr(
  55. $spatial,
  56. 17,
  57. mb_strlen($spatial) - 19
  58. );
  59. // Separate each linestring
  60. $linestirngs = explode("),(", $multilinestirng);
  61. foreach ($linestirngs as $linestring) {
  62. $min_max = $this->setMinMax($linestring, $min_max);
  63. }
  64. return $min_max;
  65. }
  66. /**
  67. * Adds to the PNG image object, the data related to a row in the GIS dataset.
  68. *
  69. * @param string $spatial GIS MULTILINESTRING object
  70. * @param string $label Label for the GIS MULTILINESTRING object
  71. * @param string $line_color Color for the GIS MULTILINESTRING object
  72. * @param array $scale_data Array containing data related to scaling
  73. * @param object $image Image object
  74. *
  75. * @return object the modified image object
  76. * @access public
  77. */
  78. public function prepareRowAsPng(
  79. $spatial,
  80. $label,
  81. $line_color,
  82. array $scale_data,
  83. $image
  84. ) {
  85. // allocate colors
  86. $black = imagecolorallocate($image, 0, 0, 0);
  87. $red = hexdec(mb_substr($line_color, 1, 2));
  88. $green = hexdec(mb_substr($line_color, 3, 2));
  89. $blue = hexdec(mb_substr($line_color, 4, 2));
  90. $color = imagecolorallocate($image, $red, $green, $blue);
  91. // Trim to remove leading 'MULTILINESTRING((' and trailing '))'
  92. $multilinestirng
  93. = mb_substr(
  94. $spatial,
  95. 17,
  96. mb_strlen($spatial) - 19
  97. );
  98. // Separate each linestring
  99. $linestirngs = explode("),(", $multilinestirng);
  100. $first_line = true;
  101. foreach ($linestirngs as $linestring) {
  102. $points_arr = $this->extractPoints($linestring, $scale_data);
  103. foreach ($points_arr as $point) {
  104. if (!isset($temp_point)) {
  105. $temp_point = $point;
  106. } else {
  107. // draw line section
  108. imageline(
  109. $image,
  110. $temp_point[0],
  111. $temp_point[1],
  112. $point[0],
  113. $point[1],
  114. $color
  115. );
  116. $temp_point = $point;
  117. }
  118. }
  119. unset($temp_point);
  120. // print label if applicable
  121. if (isset($label) && trim($label) != '' && $first_line) {
  122. imagestring(
  123. $image,
  124. 1,
  125. $points_arr[1][0],
  126. $points_arr[1][1],
  127. trim($label),
  128. $black
  129. );
  130. }
  131. $first_line = false;
  132. }
  133. return $image;
  134. }
  135. /**
  136. * Adds to the TCPDF instance, the data related to a row in the GIS dataset.
  137. *
  138. * @param string $spatial GIS MULTILINESTRING object
  139. * @param string $label Label for the GIS MULTILINESTRING object
  140. * @param string $line_color Color for the GIS MULTILINESTRING object
  141. * @param array $scale_data Array containing data related to scaling
  142. * @param TCPDF $pdf TCPDF instance
  143. *
  144. * @return TCPDF the modified TCPDF instance
  145. * @access public
  146. */
  147. public function prepareRowAsPdf($spatial, $label, $line_color, array $scale_data, $pdf)
  148. {
  149. // allocate colors
  150. $red = hexdec(mb_substr($line_color, 1, 2));
  151. $green = hexdec(mb_substr($line_color, 3, 2));
  152. $blue = hexdec(mb_substr($line_color, 4, 2));
  153. $line = array('width' => 1.5, 'color' => array($red, $green, $blue));
  154. // Trim to remove leading 'MULTILINESTRING((' and trailing '))'
  155. $multilinestirng
  156. = mb_substr(
  157. $spatial,
  158. 17,
  159. mb_strlen($spatial) - 19
  160. );
  161. // Separate each linestring
  162. $linestirngs = explode("),(", $multilinestirng);
  163. $first_line = true;
  164. foreach ($linestirngs as $linestring) {
  165. $points_arr = $this->extractPoints($linestring, $scale_data);
  166. foreach ($points_arr as $point) {
  167. if (!isset($temp_point)) {
  168. $temp_point = $point;
  169. } else {
  170. // draw line section
  171. $pdf->Line(
  172. $temp_point[0],
  173. $temp_point[1],
  174. $point[0],
  175. $point[1],
  176. $line
  177. );
  178. $temp_point = $point;
  179. }
  180. }
  181. unset($temp_point);
  182. // print label
  183. if (isset($label) && trim($label) != '' && $first_line) {
  184. $pdf->SetXY($points_arr[1][0], $points_arr[1][1]);
  185. $pdf->SetFontSize(5);
  186. $pdf->Cell(0, 0, trim($label));
  187. }
  188. $first_line = false;
  189. }
  190. return $pdf;
  191. }
  192. /**
  193. * Prepares and returns the code related to a row in the GIS dataset as SVG.
  194. *
  195. * @param string $spatial GIS MULTILINESTRING object
  196. * @param string $label Label for the GIS MULTILINESTRING object
  197. * @param string $line_color Color for the GIS MULTILINESTRING object
  198. * @param array $scale_data Array containing data related to scaling
  199. *
  200. * @return string the code related to a row in the GIS dataset
  201. * @access public
  202. */
  203. public function prepareRowAsSvg($spatial, $label, $line_color, array $scale_data)
  204. {
  205. $line_options = array(
  206. 'name' => $label,
  207. 'class' => 'linestring vector',
  208. 'fill' => 'none',
  209. 'stroke' => $line_color,
  210. 'stroke-width' => 2,
  211. );
  212. // Trim to remove leading 'MULTILINESTRING((' and trailing '))'
  213. $multilinestirng
  214. = mb_substr(
  215. $spatial,
  216. 17,
  217. mb_strlen($spatial) - 19
  218. );
  219. // Separate each linestring
  220. $linestirngs = explode("),(", $multilinestirng);
  221. $row = '';
  222. foreach ($linestirngs as $linestring) {
  223. $points_arr = $this->extractPoints($linestring, $scale_data);
  224. $row .= '<polyline points="';
  225. foreach ($points_arr as $point) {
  226. $row .= $point[0] . ',' . $point[1] . ' ';
  227. }
  228. $row .= '"';
  229. $line_options['id'] = $label . rand();
  230. foreach ($line_options as $option => $val) {
  231. $row .= ' ' . $option . '="' . trim($val) . '"';
  232. }
  233. $row .= '/>';
  234. }
  235. return $row;
  236. }
  237. /**
  238. * Prepares JavaScript related to a row in the GIS dataset
  239. * to visualize it with OpenLayers.
  240. *
  241. * @param string $spatial GIS MULTILINESTRING object
  242. * @param int $srid Spatial reference ID
  243. * @param string $label Label for the GIS MULTILINESTRING object
  244. * @param string $line_color Color for the GIS MULTILINESTRING object
  245. * @param array $scale_data Array containing data related to scaling
  246. *
  247. * @return string JavaScript related to a row in the GIS dataset
  248. * @access public
  249. */
  250. public function prepareRowAsOl($spatial, $srid, $label, $line_color, array $scale_data)
  251. {
  252. $style_options = array(
  253. 'strokeColor' => $line_color,
  254. 'strokeWidth' => 2,
  255. 'label' => $label,
  256. 'fontSize' => 10,
  257. );
  258. if ($srid == 0) {
  259. $srid = 4326;
  260. }
  261. $row = $this->getBoundsForOl($srid, $scale_data);
  262. // Trim to remove leading 'MULTILINESTRING((' and trailing '))'
  263. $multilinestirng
  264. = mb_substr(
  265. $spatial,
  266. 17,
  267. mb_strlen($spatial) - 19
  268. );
  269. // Separate each linestring
  270. $linestirngs = explode("),(", $multilinestirng);
  271. $row .= 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
  272. . 'new OpenLayers.Geometry.MultiLineString('
  273. . $this->getLineArrayForOpenLayers($linestirngs, $srid)
  274. . '), null, ' . json_encode($style_options) . '));';
  275. return $row;
  276. }
  277. /**
  278. * Generate the WKT with the set of parameters passed by the GIS editor.
  279. *
  280. * @param array $gis_data GIS data
  281. * @param int $index Index into the parameter object
  282. * @param string $empty Value for empty points
  283. *
  284. * @return string WKT with the set of parameters passed by the GIS editor
  285. * @access public
  286. */
  287. public function generateWkt(array $gis_data, $index, $empty = '')
  288. {
  289. $data_row = $gis_data[$index]['MULTILINESTRING'];
  290. $no_of_lines = isset($data_row['no_of_lines'])
  291. ? $data_row['no_of_lines'] : 1;
  292. if ($no_of_lines < 1) {
  293. $no_of_lines = 1;
  294. }
  295. $wkt = 'MULTILINESTRING(';
  296. for ($i = 0; $i < $no_of_lines; $i++) {
  297. $no_of_points = isset($data_row[$i]['no_of_points'])
  298. ? $data_row[$i]['no_of_points'] : 2;
  299. if ($no_of_points < 2) {
  300. $no_of_points = 2;
  301. }
  302. $wkt .= '(';
  303. for ($j = 0; $j < $no_of_points; $j++) {
  304. $wkt .= ((isset($data_row[$i][$j]['x'])
  305. && trim($data_row[$i][$j]['x']) != '')
  306. ? $data_row[$i][$j]['x'] : $empty)
  307. . ' ' . ((isset($data_row[$i][$j]['y'])
  308. && trim($data_row[$i][$j]['y']) != '')
  309. ? $data_row[$i][$j]['y'] : $empty) . ',';
  310. }
  311. $wkt
  312. = mb_substr(
  313. $wkt,
  314. 0, mb_strlen($wkt) - 1
  315. );
  316. $wkt .= '),';
  317. }
  318. $wkt
  319. = mb_substr(
  320. $wkt,
  321. 0,
  322. mb_strlen($wkt) - 1
  323. );
  324. $wkt .= ')';
  325. return $wkt;
  326. }
  327. /**
  328. * Generate the WKT for the data from ESRI shape files.
  329. *
  330. * @param array $row_data GIS data
  331. *
  332. * @return string the WKT for the data from ESRI shape files
  333. * @access public
  334. */
  335. public function getShape(array $row_data)
  336. {
  337. $wkt = 'MULTILINESTRING(';
  338. for ($i = 0; $i < $row_data['numparts']; $i++) {
  339. $wkt .= '(';
  340. foreach ($row_data['parts'][$i]['points'] as $point) {
  341. $wkt .= $point['x'] . ' ' . $point['y'] . ',';
  342. }
  343. $wkt
  344. = mb_substr(
  345. $wkt,
  346. 0,
  347. mb_strlen($wkt) - 1
  348. );
  349. $wkt .= '),';
  350. }
  351. $wkt
  352. = mb_substr(
  353. $wkt,
  354. 0,
  355. mb_strlen($wkt) - 1
  356. );
  357. $wkt .= ')';
  358. return $wkt;
  359. }
  360. /**
  361. * Generate parameters for the GIS data editor from the value of the GIS column.
  362. *
  363. * @param string $value Value of the GIS column
  364. * @param int $index Index of the geometry
  365. *
  366. * @return array params for the GIS data editor from the value of the GIS column
  367. * @access public
  368. */
  369. public function generateParams($value, $index = -1)
  370. {
  371. $params = array();
  372. if ($index == -1) {
  373. $index = 0;
  374. $data = GisGeometry::generateParams($value);
  375. $params['srid'] = $data['srid'];
  376. $wkt = $data['wkt'];
  377. } else {
  378. $params[$index]['gis_type'] = 'MULTILINESTRING';
  379. $wkt = $value;
  380. }
  381. // Trim to remove leading 'MULTILINESTRING((' and trailing '))'
  382. $multilinestirng
  383. = mb_substr(
  384. $wkt,
  385. 17,
  386. mb_strlen($wkt) - 19
  387. );
  388. // Separate each linestring
  389. $linestirngs = explode("),(", $multilinestirng);
  390. $params[$index]['MULTILINESTRING']['no_of_lines'] = count($linestirngs);
  391. $j = 0;
  392. foreach ($linestirngs as $linestring) {
  393. $points_arr = $this->extractPoints($linestring, null);
  394. $no_of_points = count($points_arr);
  395. $params[$index]['MULTILINESTRING'][$j]['no_of_points'] = $no_of_points;
  396. for ($i = 0; $i < $no_of_points; $i++) {
  397. $params[$index]['MULTILINESTRING'][$j][$i]['x'] = $points_arr[$i][0];
  398. $params[$index]['MULTILINESTRING'][$j][$i]['y'] = $points_arr[$i][1];
  399. }
  400. $j++;
  401. }
  402. return $params;
  403. }
  404. }