1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/phpmyadmin_ynh.git synced 2024-09-03 19:56:46 +02:00
phpmyadmin_ynh/sources/libraries/plugins/import/ImportShp.class.php
2014-01-14 12:28:06 +01:00

335 lines
10 KiB
PHP

<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* ESRI Shape file import plugin for phpMyAdmin
*
* @package PhpMyAdmin-Import
* @subpackage ESRI_Shape
*/
if (! defined('PHPMYADMIN')) {
exit;
}
// Drizzle does not support GIS data types
if (PMA_DRIZZLE) {
$GLOBALS['skip_import'] = true;
return;
}
/* Get the import interface*/
require_once 'libraries/plugins/ImportPlugin.class.php';
/* Get the ShapeFile class */
require_once 'libraries/bfShapeFiles/ShapeFile.lib.php';
require_once 'libraries/plugins/import/ShapeFile.class.php';
require_once 'libraries/plugins/import/ShapeRecord.class.php';
/**
* Handles the import for ESRI Shape files
*
* @package PhpMyAdmin-Import
* @subpackage ESRI_Shape
*/
class ImportShp extends ImportPlugin
{
/**
* Constructor
*/
public function __construct()
{
$this->setProperties();
}
/**
* Sets the import plugin properties.
* Called in the constructor.
*
* @return void
*/
protected function setProperties()
{
$props = 'libraries/properties/';
include_once "$props/plugins/ImportPluginProperties.class.php";
$importPluginProperties = new ImportPluginProperties();
$importPluginProperties->setText(__('ESRI Shape File'));
$importPluginProperties->setExtension('shp');
$importPluginProperties->setOptions(array());
$importPluginProperties->setOptionsText(__('Options'));
$this->properties = $importPluginProperties;
}
/**
* This method is called when any PluginManager to which the observer
* is attached calls PluginManager::notify()
*
* @param SplSubject $subject The PluginManager notifying the observer
* of an update.
*
* @return void
*/
public function update (SplSubject $subject)
{
}
/**
* Handles the whole import logic
*
* @return void
*/
public function doImport()
{
global $db, $error, $finished, $compression,
$import_file, $local_import_file, $message;
$GLOBALS['finished'] = false;
$shp = new PMA_ShapeFile(1);
// If the zip archive has more than one file,
// get the correct content to the buffer from .shp file.
if ($compression == 'application/zip'
&& PMA_getNoOfFilesInZip($import_file) > 1
) {
$zip_content = PMA_getZipContents($import_file, '/^.*\.shp$/i');
$GLOBALS['import_text'] = $zip_content['data'];
}
$temp_dbf_file = false;
// We need dbase extension to handle .dbf file
if (extension_loaded('dbase')) {
// If we can extract the zip archive to 'TempDir'
// and use the files in it for import
if ($compression == 'application/zip'
&& ! empty($GLOBALS['cfg']['TempDir'])
&& is_writable($GLOBALS['cfg']['TempDir'])
) {
$dbf_file_name = PMA_findFileFromZipArchive(
'/^.*\.dbf$/i', $import_file
);
// If the corresponding .dbf file is in the zip archive
if ($dbf_file_name) {
// Extract the .dbf file and point to it.
$extracted = PMA_zipExtract(
$import_file,
realpath($GLOBALS['cfg']['TempDir']),
array($dbf_file_name)
);
if ($extracted) {
$dbf_file_path = realpath($GLOBALS['cfg']['TempDir'])
. (PMA_IS_WINDOWS ? '\\' : '/') . $dbf_file_name;
$temp_dbf_file = true;
// Replace the .dbf with .*, as required
// by the bsShapeFiles library.
$file_name = substr(
$dbf_file_path, 0, strlen($dbf_file_path) - 4
) . '.*';
$shp->FileName = $file_name;
}
}
} elseif (! empty($local_import_file)
&& ! empty($GLOBALS['cfg']['UploadDir'])
&& $compression == 'none'
) {
// If file is in UploadDir, use .dbf file in the same UploadDir
// to load extra data.
// Replace the .shp with .*,
// so the bsShapeFiles library correctly locates .dbf file.
$file_name = substr($import_file, 0, strlen($import_file) - 4)
. '.*';
$shp->FileName = $file_name;
}
}
// Load data
$shp->loadFromFile('');
if ($shp->lastError != "") {
$error = true;
$message = PMA_Message::error(
__('There was an error importing the ESRI shape file: "%s".')
);
$message->addParam($shp->lastError);
return;
}
// Delete the .dbf file extracted to 'TempDir'
if ($temp_dbf_file
&& isset($dbf_file_path)
&& file_exists($dbf_file_path)
) {
unlink($dbf_file_path);
}
$esri_types = array(
0 => 'Null Shape',
1 => 'Point',
3 => 'PolyLine',
5 => 'Polygon',
8 => 'MultiPoint',
11 => 'PointZ',
13 => 'PolyLineZ',
15 => 'PolygonZ',
18 => 'MultiPointZ',
21 => 'PointM',
23 => 'PolyLineM',
25 => 'PolygonM',
28 => 'MultiPointM',
31 => 'MultiPatch',
);
switch ($shp->shapeType) {
// ESRI Null Shape
case 0:
break;
// ESRI Point
case 1:
$gis_type = 'point';
break;
// ESRI PolyLine
case 3:
$gis_type = 'multilinestring';
break;
// ESRI Polygon
case 5:
$gis_type = 'multipolygon';
break;
// ESRI MultiPoint
case 8:
$gis_type = 'multipoint';
break;
default:
$error = true;
if (! isset($esri_types[$shp->shapeType])) {
$message = PMA_Message::error(
__(
'You tried to import an invalid file or the imported file'
. ' contains invalid data'
)
);
} else {
$message = PMA_Message::error(
__('MySQL Spatial Extension does not support ESRI type "%s".')
);
$message->addParam($esri_types[$shp->shapeType]);
}
return;
}
if (isset($gis_type)) {
include_once './libraries/gis/pma_gis_factory.php';
$gis_obj = PMA_GIS_Factory::factory($gis_type);
} else {
$gis_obj = null;
}
$num_rows = count($shp->records);
// If .dbf file is loaded, the number of extra data columns
$num_data_cols = isset($shp->DBFHeader) ? count($shp->DBFHeader) : 0;
$rows = array();
$col_names = array();
if ($num_rows != 0) {
foreach ($shp->records as $record) {
$tempRow = array();
if ($gis_obj == null) {
$tempRow[] = null;
} else {
$tempRow[] = "GeomFromText('"
. $gis_obj->getShape($record->SHPData) . "')";
}
if (isset($shp->DBFHeader)) {
foreach ($shp->DBFHeader as $c) {
$cell = trim($record->DBFData[$c[0]]);
if (! strcmp($cell, '')) {
$cell = 'NULL';
}
$tempRow[] = $cell;
}
}
$rows[] = $tempRow;
}
}
if (count($rows) == 0) {
$error = true;
$message = PMA_Message::error(
__('The imported file does not contain any data')
);
return;
}
// Column names for spatial column and the rest of the columns,
// if they are available
$col_names[] = 'SPATIAL';
for ($n = 0; $n < $num_data_cols; $n++) {
$col_names[] = $shp->DBFHeader[$n][0];
}
// Set table name based on the number of tables
if (strlen($db)) {
$result = $GLOBALS['dbi']->fetchResult('SHOW TABLES');
$table_name = 'TABLE '.(count($result) + 1);
} else {
$table_name = 'TBL_NAME';
}
$tables = array(array($table_name, $col_names, $rows));
// Use data from shape file to chose best-fit MySQL types for each column
$analyses = array();
$analyses[] = PMA_analyzeTable($tables[0]);
$table_no = 0; $spatial_col = 0;
$analyses[$table_no][TYPES][$spatial_col] = GEOMETRY;
$analyses[$table_no][FORMATTEDSQL][$spatial_col] = true;
// Set database name to the currently selected one, if applicable
if (strlen($db)) {
$db_name = $db;
$options = array('create_db' => false);
} else {
$db_name = 'SHP_DB';
$options = null;
}
// Created and execute necessary SQL statements from data
$null_param = null;
PMA_buildSQL($db_name, $tables, $analyses, $null_param, $options);
unset($tables);
unset($analyses);
$finished = true;
$error = false;
// Commit any possible data in buffers
PMA_importRunQuery();
}
/**
* Returns specified number of bytes from the buffer.
* Buffer automatically fetches next chunk of data when the buffer
* falls short.
* Sets $eof when $GLOBALS['finished'] is set and the buffer falls short.
*
* @param int $length number of bytes
*
* @return string
*/
public static function readFromBuffer($length)
{
global $buffer, $eof;
if (strlen($buffer) < $length) {
if ($GLOBALS['finished']) {
$eof = true;
} else {
$buffer .= PMA_importGetNextChunk();
}
}
$result = substr($buffer, 0, $length);
$buffer = substr($buffer, $length);
return $result;
}
}