PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/manage/db/libraries/plugins/import/ImportShp.class.php

https://bitbucket.org/kamegai_mp/dai-ichi-seimei
PHP | 343 lines | 284 code | 13 blank | 46 comment | 13 complexity | 99798e8bf741a3a4ac444a87e6a0eea2 MD5 | raw file
Possible License(s): GPL-2.0, MIT, BSD-3-Clause
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * ESRI Shape file import plugin for phpMyAdmin
  5. *
  6. * @package PhpMyAdmin-Import
  7. * @subpackage ESRI_Shape
  8. */
  9. if (! defined('PHPMYADMIN')) {
  10. exit;
  11. }
  12. // Drizzle does not support GIS data types
  13. if (PMA_DRIZZLE) {
  14. $GLOBALS['skip_import'] = true;
  15. return;
  16. }
  17. /* Get the import interface*/
  18. require_once 'libraries/plugins/ImportPlugin.class.php';
  19. /* Get the ShapeFile class */
  20. require_once 'libraries/bfShapeFiles/ShapeFile.lib.php';
  21. require_once 'libraries/plugins/import/ShapeFile.class.php';
  22. require_once 'libraries/plugins/import/ShapeRecord.class.php';
  23. /**
  24. * Handles the import for ESRI Shape files
  25. *
  26. * @package PhpMyAdmin-Import
  27. * @subpackage ESRI_Shape
  28. */
  29. class ImportShp extends ImportPlugin
  30. {
  31. /**
  32. * Constructor
  33. */
  34. public function __construct()
  35. {
  36. $this->setProperties();
  37. }
  38. /**
  39. * Sets the import plugin properties.
  40. * Called in the constructor.
  41. *
  42. * @return void
  43. */
  44. protected function setProperties()
  45. {
  46. $props = 'libraries/properties/';
  47. include_once "$props/plugins/ImportPluginProperties.class.php";
  48. $importPluginProperties = new ImportPluginProperties();
  49. $importPluginProperties->setText(__('ESRI Shape File'));
  50. $importPluginProperties->setExtension('shp');
  51. $importPluginProperties->setOptions(array());
  52. $importPluginProperties->setOptionsText(__('Options'));
  53. $this->properties = $importPluginProperties;
  54. }
  55. /**
  56. * This method is called when any PluginManager to which the observer
  57. * is attached calls PluginManager::notify()
  58. *
  59. * @param SplSubject $subject The PluginManager notifying the observer
  60. * of an update.
  61. *
  62. * @return void
  63. */
  64. public function update (SplSubject $subject)
  65. {
  66. }
  67. /**
  68. * Handles the whole import logic
  69. *
  70. * @return void
  71. */
  72. public function doImport()
  73. {
  74. global $db, $error, $finished, $compression,
  75. $import_file, $local_import_file;
  76. if ((int) ini_get('memory_limit') < 512) {
  77. @ini_set('memory_limit', '512M');
  78. }
  79. @set_time_limit(300);
  80. $GLOBALS['finished'] = false;
  81. $buffer = '';
  82. $eof = false;
  83. $shp = new PMA_ShapeFile(1);
  84. // If the zip archive has more than one file,
  85. // get the correct content to the buffer from .shp file.
  86. if ($compression == 'application/zip'
  87. && PMA_getNoOfFilesInZip($import_file) > 1
  88. ) {
  89. $zip_content = PMA_getZipContents($import_file, '/^.*\.shp$/i');
  90. $GLOBALS['import_text'] = $zip_content['data'];
  91. }
  92. $temp_dbf_file = false;
  93. // We need dbase extension to handle .dbf file
  94. if (extension_loaded('dbase')) {
  95. // If we can extract the zip archive to 'TempDir'
  96. // and use the files in it for import
  97. if ($compression == 'application/zip'
  98. && ! empty($GLOBALS['cfg']['TempDir'])
  99. && is_writable($GLOBALS['cfg']['TempDir'])
  100. ) {
  101. $dbf_file_name = PMA_findFileFromZipArchive(
  102. '/^.*\.dbf$/i', $import_file
  103. );
  104. // If the corresponding .dbf file is in the zip archive
  105. if ($dbf_file_name) {
  106. // Extract the .dbf file and point to it.
  107. $extracted = PMA_zipExtract(
  108. $import_file,
  109. realpath($GLOBALS['cfg']['TempDir']),
  110. array($dbf_file_name)
  111. );
  112. if ($extracted) {
  113. $dbf_file_path = realpath($GLOBALS['cfg']['TempDir'])
  114. . (PMA_IS_WINDOWS ? '\\' : '/') . $dbf_file_name;
  115. $temp_dbf_file = true;
  116. // Replace the .dbf with .*, as required
  117. // by the bsShapeFiles library.
  118. $file_name = substr(
  119. $dbf_file_path, 0, strlen($dbf_file_path) - 4
  120. ) . '.*';
  121. $shp->FileName = $file_name;
  122. }
  123. }
  124. } elseif (! empty($local_import_file)
  125. && ! empty($GLOBALS['cfg']['UploadDir'])
  126. && $compression == 'none'
  127. ) {
  128. // If file is in UploadDir, use .dbf file in the same UploadDir
  129. // to load extra data.
  130. // Replace the .shp with .*,
  131. // so the bsShapeFiles library correctly locates .dbf file.
  132. $file_name = substr($import_file, 0, strlen($import_file) - 4)
  133. . '.*';
  134. $shp->FileName = $file_name;
  135. }
  136. }
  137. // Load data
  138. $shp->loadFromFile('');
  139. if ($shp->lastError != "") {
  140. $error = true;
  141. $message = PMA_Message::error(
  142. __('There was an error importing the ESRI shape file: "%s".')
  143. );
  144. $message->addParam($shp->lastError);
  145. return;
  146. }
  147. // Delete the .dbf file extracted to 'TempDir'
  148. if ($temp_dbf_file
  149. && isset($dbf_file_path)
  150. && file_exists($dbf_file_path)
  151. ) {
  152. unlink($dbf_file_path);
  153. }
  154. $esri_types = array(
  155. 0 => 'Null Shape',
  156. 1 => 'Point',
  157. 3 => 'PolyLine',
  158. 5 => 'Polygon',
  159. 8 => 'MultiPoint',
  160. 11 => 'PointZ',
  161. 13 => 'PolyLineZ',
  162. 15 => 'PolygonZ',
  163. 18 => 'MultiPointZ',
  164. 21 => 'PointM',
  165. 23 => 'PolyLineM',
  166. 25 => 'PolygonM',
  167. 28 => 'MultiPointM',
  168. 31 => 'MultiPatch',
  169. );
  170. switch ($shp->shapeType) {
  171. // ESRI Null Shape
  172. case 0:
  173. break;
  174. // ESRI Point
  175. case 1:
  176. $gis_type = 'point';
  177. break;
  178. // ESRI PolyLine
  179. case 3:
  180. $gis_type = 'multilinestring';
  181. break;
  182. // ESRI Polygon
  183. case 5:
  184. $gis_type = 'multipolygon';
  185. break;
  186. // ESRI MultiPoint
  187. case 8:
  188. $gis_type = 'multipoint';
  189. break;
  190. default:
  191. $error = true;
  192. if (! isset($esri_types[$shp->shapeType])) {
  193. $message = PMA_Message::error(
  194. __(
  195. 'You tried to import an invalid file or the imported file'
  196. . ' contains invalid data'
  197. )
  198. );
  199. } else {
  200. $message = PMA_Message::error(
  201. __('MySQL Spatial Extension does not support ESRI type "%s".')
  202. );
  203. $message->addParam($param);
  204. }
  205. return;
  206. }
  207. if (isset($gis_type)) {
  208. include_once './libraries/gis/pma_gis_factory.php';
  209. $gis_obj = PMA_GIS_Factory::factory($gis_type);
  210. } else {
  211. $gis_obj = null;
  212. }
  213. $num_rows = count($shp->records);
  214. // If .dbf file is loaded, the number of extra data columns
  215. $num_data_cols = isset($shp->DBFHeader) ? count($shp->DBFHeader) : 0;
  216. $rows = array();
  217. $col_names = array();
  218. if ($num_rows != 0) {
  219. foreach ($shp->records as $record) {
  220. $tempRow = array();
  221. if ($gis_obj == null) {
  222. $tempRow[] = null;
  223. } else {
  224. $tempRow[] = "GeomFromText('"
  225. . $gis_obj->getShape($record->SHPData) . "')";
  226. }
  227. if (isset($shp->DBFHeader)) {
  228. foreach ($shp->DBFHeader as $c) {
  229. $cell = trim($record->DBFData[$c[0]]);
  230. if (! strcmp($cell, '')) {
  231. $cell = 'NULL';
  232. }
  233. $tempRow[] = $cell;
  234. }
  235. }
  236. $rows[] = $tempRow;
  237. }
  238. }
  239. if (count($rows) == 0) {
  240. $error = true;
  241. $message = PMA_Message::error(
  242. __('The imported file does not contain any data')
  243. );
  244. return;
  245. }
  246. // Column names for spatial column and the rest of the columns,
  247. // if they are available
  248. $col_names[] = 'SPATIAL';
  249. for ($n = 0; $n < $num_data_cols; $n++) {
  250. $col_names[] = $shp->DBFHeader[$n][0];
  251. }
  252. // Set table name based on the number of tables
  253. if (strlen($db)) {
  254. $result = PMA_DBI_fetch_result('SHOW TABLES');
  255. $table_name = 'TABLE '.(count($result) + 1);
  256. } else {
  257. $table_name = 'TBL_NAME';
  258. }
  259. $tables = array(array($table_name, $col_names, $rows));
  260. // Use data from shape file to chose best-fit MySQL types for each column
  261. $analyses = array();
  262. $analyses[] = PMA_analyzeTable($tables[0]);
  263. $table_no = 0; $spatial_col = 0;
  264. $analyses[$table_no][TYPES][$spatial_col] = GEOMETRY;
  265. $analyses[$table_no][FORMATTEDSQL][$spatial_col] = true;
  266. // Set database name to the currently selected one, if applicable
  267. if (strlen($db)) {
  268. $db_name = $db;
  269. $options = array('create_db' => false);
  270. } else {
  271. $db_name = 'SHP_DB';
  272. $options = null;
  273. }
  274. // Created and execute necessary SQL statements from data
  275. $null_param = null;
  276. PMA_buildSQL($db_name, $tables, $analyses, $null_param, $options);
  277. unset($tables);
  278. unset($analyses);
  279. $finished = true;
  280. $error = false;
  281. // Commit any possible data in buffers
  282. PMA_importRunQuery();
  283. }
  284. /**
  285. * Returns specified number of bytes from the buffer.
  286. * Buffer automatically fetches next chunk of data when the buffer
  287. * falls short.
  288. * Sets $eof when $GLOBALS['finished'] is set and the buffer falls short.
  289. *
  290. * @param int $length number of bytes
  291. *
  292. * @return string
  293. */
  294. public static function readFromBuffer($length)
  295. {
  296. global $buffer, $eof;
  297. if (strlen($buffer) < $length) {
  298. if ($GLOBALS['finished']) {
  299. $eof = true;
  300. } else {
  301. $buffer .= PMA_importGetNextChunk();
  302. }
  303. }
  304. $result = substr($buffer, 0, $length);
  305. $buffer = substr($buffer, $length);
  306. return $result;
  307. }
  308. }