GisMultiPoint.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Handles actions related to GIS MULTIPOINT objects
  5. *
  6. * @package PhpMyAdmin-GIS
  7. */
  8. namespace PhpMyAdmin\Gis;
  9. use TCPDF;
  10. /**
  11. * Handles actions related to GIS MULTIPOINT objects
  12. *
  13. * @package PhpMyAdmin-GIS
  14. */
  15. class GisMultiPoint 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 GisMultiPoint 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. // Trim to remove leading 'MULTIPOINT(' and trailing ')'
  52. $multipoint
  53. = mb_substr(
  54. $spatial,
  55. 11,
  56. mb_strlen($spatial) - 12
  57. );
  58. return $this->setMinMax($multipoint, array());
  59. }
  60. /**
  61. * Adds to the PNG image object, the data related to a row in the GIS dataset.
  62. *
  63. * @param string $spatial GIS MULTIPOINT object
  64. * @param string $label Label for the GIS MULTIPOINT object
  65. * @param string $point_color Color for the GIS MULTIPOINT object
  66. * @param array $scale_data Array containing data related to scaling
  67. * @param object $image Image object
  68. *
  69. * @return object the modified image object
  70. * @access public
  71. */
  72. public function prepareRowAsPng(
  73. $spatial,
  74. $label,
  75. $point_color,
  76. array $scale_data,
  77. $image
  78. ) {
  79. // allocate colors
  80. $black = imagecolorallocate($image, 0, 0, 0);
  81. $red = hexdec(mb_substr($point_color, 1, 2));
  82. $green = hexdec(mb_substr($point_color, 3, 2));
  83. $blue = hexdec(mb_substr($point_color, 4, 2));
  84. $color = imagecolorallocate($image, $red, $green, $blue);
  85. // Trim to remove leading 'MULTIPOINT(' and trailing ')'
  86. $multipoint
  87. = mb_substr(
  88. $spatial,
  89. 11,
  90. mb_strlen($spatial) - 12
  91. );
  92. $points_arr = $this->extractPoints($multipoint, $scale_data);
  93. foreach ($points_arr as $point) {
  94. // draw a small circle to mark the point
  95. if ($point[0] != '' && $point[1] != '') {
  96. imagearc($image, $point[0], $point[1], 7, 7, 0, 360, $color);
  97. }
  98. }
  99. // print label for each point
  100. if ((isset($label) && trim($label) != '')
  101. && ($points_arr[0][0] != '' && $points_arr[0][1] != '')
  102. ) {
  103. imagestring(
  104. $image,
  105. 1,
  106. $points_arr[0][0],
  107. $points_arr[0][1],
  108. trim($label),
  109. $black
  110. );
  111. }
  112. return $image;
  113. }
  114. /**
  115. * Adds to the TCPDF instance, the data related to a row in the GIS dataset.
  116. *
  117. * @param string $spatial GIS MULTIPOINT object
  118. * @param string $label Label for the GIS MULTIPOINT object
  119. * @param string $point_color Color for the GIS MULTIPOINT object
  120. * @param array $scale_data Array containing data related to scaling
  121. * @param TCPDF $pdf TCPDF instance
  122. *
  123. * @return TCPDF the modified TCPDF instance
  124. * @access public
  125. */
  126. public function prepareRowAsPdf(
  127. $spatial,
  128. $label,
  129. $point_color,
  130. array $scale_data,
  131. $pdf
  132. ) {
  133. // allocate colors
  134. $red = hexdec(mb_substr($point_color, 1, 2));
  135. $green = hexdec(mb_substr($point_color, 3, 2));
  136. $blue = hexdec(mb_substr($point_color, 4, 2));
  137. $line = array('width' => 1.25, 'color' => array($red, $green, $blue));
  138. // Trim to remove leading 'MULTIPOINT(' and trailing ')'
  139. $multipoint
  140. = mb_substr(
  141. $spatial,
  142. 11,
  143. mb_strlen($spatial) - 12
  144. );
  145. $points_arr = $this->extractPoints($multipoint, $scale_data);
  146. foreach ($points_arr as $point) {
  147. // draw a small circle to mark the point
  148. if ($point[0] != '' && $point[1] != '') {
  149. $pdf->Circle($point[0], $point[1], 2, 0, 360, 'D', $line);
  150. }
  151. }
  152. // print label for each point
  153. if ((isset($label) && trim($label) != '')
  154. && ($points_arr[0][0] != '' && $points_arr[0][1] != '')
  155. ) {
  156. $pdf->SetXY($points_arr[0][0], $points_arr[0][1]);
  157. $pdf->SetFontSize(5);
  158. $pdf->Cell(0, 0, trim($label));
  159. }
  160. return $pdf;
  161. }
  162. /**
  163. * Prepares and returns the code related to a row in the GIS dataset as SVG.
  164. *
  165. * @param string $spatial GIS MULTIPOINT object
  166. * @param string $label Label for the GIS MULTIPOINT object
  167. * @param string $point_color Color for the GIS MULTIPOINT object
  168. * @param array $scale_data Array containing data related to scaling
  169. *
  170. * @return string the code related to a row in the GIS dataset
  171. * @access public
  172. */
  173. public function prepareRowAsSvg($spatial, $label, $point_color, array $scale_data)
  174. {
  175. $point_options = array(
  176. 'name' => $label,
  177. 'class' => 'multipoint vector',
  178. 'fill' => 'white',
  179. 'stroke' => $point_color,
  180. 'stroke-width' => 2,
  181. );
  182. // Trim to remove leading 'MULTIPOINT(' and trailing ')'
  183. $multipoint
  184. = mb_substr(
  185. $spatial,
  186. 11,
  187. mb_strlen($spatial) - 12
  188. );
  189. $points_arr = $this->extractPoints($multipoint, $scale_data);
  190. $row = '';
  191. foreach ($points_arr as $point) {
  192. if ($point[0] != '' && $point[1] != '') {
  193. $row .= '<circle cx="' . $point[0] . '" cy="'
  194. . $point[1] . '" r="3"';
  195. $point_options['id'] = $label . rand();
  196. foreach ($point_options as $option => $val) {
  197. $row .= ' ' . $option . '="' . trim($val) . '"';
  198. }
  199. $row .= '/>';
  200. }
  201. }
  202. return $row;
  203. }
  204. /**
  205. * Prepares JavaScript related to a row in the GIS dataset
  206. * to visualize it with OpenLayers.
  207. *
  208. * @param string $spatial GIS MULTIPOINT object
  209. * @param int $srid Spatial reference ID
  210. * @param string $label Label for the GIS MULTIPOINT object
  211. * @param string $point_color Color for the GIS MULTIPOINT object
  212. * @param array $scale_data Array containing data related to scaling
  213. *
  214. * @return string JavaScript related to a row in the GIS dataset
  215. * @access public
  216. */
  217. public function prepareRowAsOl(
  218. $spatial,
  219. $srid,
  220. $label,
  221. $point_color,
  222. array $scale_data
  223. ) {
  224. $style_options = array(
  225. 'pointRadius' => 3,
  226. 'fillColor' => '#ffffff',
  227. 'strokeColor' => $point_color,
  228. 'strokeWidth' => 2,
  229. 'label' => $label,
  230. 'labelYOffset' => -8,
  231. 'fontSize' => 10,
  232. );
  233. if ($srid == 0) {
  234. $srid = 4326;
  235. }
  236. $result = $this->getBoundsForOl($srid, $scale_data);
  237. // Trim to remove leading 'MULTIPOINT(' and trailing ')'
  238. $multipoint
  239. = mb_substr(
  240. $spatial,
  241. 11,
  242. mb_strlen($spatial) - 12
  243. );
  244. $points_arr = $this->extractPoints($multipoint, null);
  245. $result .= 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
  246. . 'new OpenLayers.Geometry.MultiPoint('
  247. . $this->getPointsArrayForOpenLayers($points_arr, $srid)
  248. . '), null, ' . json_encode($style_options) . '));';
  249. return $result;
  250. }
  251. /**
  252. * Generate the WKT with the set of parameters passed by the GIS editor.
  253. *
  254. * @param array $gis_data GIS data
  255. * @param int $index Index into the parameter object
  256. * @param string $empty Multipoint does not adhere to this
  257. *
  258. * @return string WKT with the set of parameters passed by the GIS editor
  259. * @access public
  260. */
  261. public function generateWkt(array $gis_data, $index, $empty = '')
  262. {
  263. $no_of_points = isset($gis_data[$index]['MULTIPOINT']['no_of_points'])
  264. ? $gis_data[$index]['MULTIPOINT']['no_of_points'] : 1;
  265. if ($no_of_points < 1) {
  266. $no_of_points = 1;
  267. }
  268. $wkt = 'MULTIPOINT(';
  269. for ($i = 0; $i < $no_of_points; $i++) {
  270. $wkt .= ((isset($gis_data[$index]['MULTIPOINT'][$i]['x'])
  271. && trim($gis_data[$index]['MULTIPOINT'][$i]['x']) != '')
  272. ? $gis_data[$index]['MULTIPOINT'][$i]['x'] : '')
  273. . ' ' . ((isset($gis_data[$index]['MULTIPOINT'][$i]['y'])
  274. && trim($gis_data[$index]['MULTIPOINT'][$i]['y']) != '')
  275. ? $gis_data[$index]['MULTIPOINT'][$i]['y'] : '') . ',';
  276. }
  277. $wkt
  278. = mb_substr(
  279. $wkt,
  280. 0,
  281. mb_strlen($wkt) - 1
  282. );
  283. $wkt .= ')';
  284. return $wkt;
  285. }
  286. /**
  287. * Generate the WKT for the data from ESRI shape files.
  288. *
  289. * @param array $row_data GIS data
  290. *
  291. * @return string the WKT for the data from ESRI shape files
  292. * @access public
  293. */
  294. public function getShape(array $row_data)
  295. {
  296. $wkt = 'MULTIPOINT(';
  297. for ($i = 0; $i < $row_data['numpoints']; $i++) {
  298. $wkt .= $row_data['points'][$i]['x'] . ' '
  299. . $row_data['points'][$i]['y'] . ',';
  300. }
  301. $wkt
  302. = mb_substr(
  303. $wkt,
  304. 0,
  305. mb_strlen($wkt) - 1
  306. );
  307. $wkt .= ')';
  308. return $wkt;
  309. }
  310. /**
  311. * Generate parameters for the GIS data editor from the value of the GIS column.
  312. *
  313. * @param string $value Value of the GIS column
  314. * @param integer $index Index of the geometry
  315. *
  316. * @return array params for the GIS data editor from the value of the GIS column
  317. * @access public
  318. */
  319. public function generateParams($value, $index = -1)
  320. {
  321. $params = array();
  322. if ($index == -1) {
  323. $index = 0;
  324. $data = GisGeometry::generateParams($value);
  325. $params['srid'] = $data['srid'];
  326. $wkt = $data['wkt'];
  327. } else {
  328. $params[$index]['gis_type'] = 'MULTIPOINT';
  329. $wkt = $value;
  330. }
  331. // Trim to remove leading 'MULTIPOINT(' and trailing ')'
  332. $points
  333. = mb_substr(
  334. $wkt,
  335. 11,
  336. mb_strlen($wkt) - 12
  337. );
  338. $points_arr = $this->extractPoints($points, null);
  339. $no_of_points = count($points_arr);
  340. $params[$index]['MULTIPOINT']['no_of_points'] = $no_of_points;
  341. for ($i = 0; $i < $no_of_points; $i++) {
  342. $params[$index]['MULTIPOINT'][$i]['x'] = $points_arr[$i][0];
  343. $params[$index]['MULTIPOINT'][$i]['y'] = $points_arr[$i][1];
  344. }
  345. return $params;
  346. }
  347. /**
  348. * Overridden to make sure that only the points having valid values
  349. * for x and y coordinates are added.
  350. *
  351. * @param array $points_arr x and y coordinates for each point
  352. * @param string $srid spatial reference id
  353. *
  354. * @return string JavaScript for adding an array of points to OpenLayers
  355. * @access protected
  356. */
  357. protected function getPointsArrayForOpenLayers(array $points_arr, $srid)
  358. {
  359. $ol_array = 'new Array(';
  360. foreach ($points_arr as $point) {
  361. if ($point[0] != '' && $point[1] != '') {
  362. $ol_array .= $this->getPointForOpenLayers($point, $srid) . ', ';
  363. }
  364. }
  365. $olArrayLength = mb_strlen($ol_array);
  366. if (mb_substr($ol_array, $olArrayLength - 2) == ', ') {
  367. $ol_array = mb_substr($ol_array, 0, $olArrayLength - 2);
  368. }
  369. $ol_array .= ')';
  370. return $ol_array;
  371. }
  372. }