mirror of
https://github.com/atlanticbiomedical/portal-legacy.git
synced 2025-07-02 01:47:28 -04:00
initial commit
This commit is contained in:
426
html/phpmyad/libraries/import/shp.php
Normal file
426
html/phpmyad/libraries/import/shp.php
Normal file
@ -0,0 +1,426 @@
|
||||
<?php
|
||||
/**
|
||||
* ESRI Shape file import plugin for phpMyAdmin
|
||||
*
|
||||
* @package PhpMyAdmin-Import
|
||||
* @subpackage ESRI_Shape
|
||||
*/
|
||||
if (! defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Drizzle does not suppost GIS data types
|
||||
if (PMA_DRIZZLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($plugin_list)) {
|
||||
$plugin_list['shp'] = array(
|
||||
'text' => __('ESRI Shape File'),
|
||||
'extension' => 'shp',
|
||||
'options' => array(),
|
||||
'options_text' => __('Options'),
|
||||
);
|
||||
} else {
|
||||
|
||||
if ((int) ini_get('memory_limit') < 512) {
|
||||
@ini_set('memory_limit', '512M');
|
||||
}
|
||||
@set_time_limit(300);
|
||||
|
||||
|
||||
// Append the bfShapeFiles directory to the include path variable
|
||||
set_include_path(get_include_path() . PATH_SEPARATOR . getcwd() . '/libraries/bfShapeFiles/');
|
||||
include_once './libraries/bfShapeFiles/ShapeFile.lib.php';
|
||||
|
||||
$GLOBALS['finished'] = false;
|
||||
$buffer = '';
|
||||
$eof = false;
|
||||
|
||||
// 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.
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends ShapeFile class to cater the following phpMyAdmin
|
||||
* specific requirements.
|
||||
* 1) To load data from .dbf file only when the dBase extension is available.
|
||||
* 2) To use PMA_importGetNextChunk() functionality to read data, rather than
|
||||
* reading directly from a file. Using readFromBuffer() in place of fread().
|
||||
* This makes it possible to use compressions.
|
||||
*/
|
||||
class PMA_ShapeFile extends ShapeFile
|
||||
{
|
||||
function _isDbaseLoaded()
|
||||
{
|
||||
return extension_loaded('dbase');
|
||||
}
|
||||
|
||||
function loadFromFile($FileName)
|
||||
{
|
||||
$this->_loadHeaders();
|
||||
$this->_loadRecords();
|
||||
if ($this->_isDbaseLoaded()) {
|
||||
$this->_closeDBFFile();
|
||||
}
|
||||
}
|
||||
|
||||
function _loadHeaders()
|
||||
{
|
||||
readFromBuffer(24);
|
||||
$this->fileLength = loadData("N", readFromBuffer(4));
|
||||
|
||||
readFromBuffer(4);
|
||||
$this->shapeType = loadData("V", readFromBuffer(4));
|
||||
|
||||
$this->boundingBox = array();
|
||||
$this->boundingBox["xmin"] = loadData("d", readFromBuffer(8));
|
||||
$this->boundingBox["ymin"] = loadData("d", readFromBuffer(8));
|
||||
$this->boundingBox["xmax"] = loadData("d", readFromBuffer(8));
|
||||
$this->boundingBox["ymax"] = loadData("d", readFromBuffer(8));
|
||||
|
||||
if ($this->_isDbaseLoaded() && $this->_openDBFFile()) {
|
||||
$this->DBFHeader = $this->_loadDBFHeader();
|
||||
}
|
||||
}
|
||||
|
||||
function _loadRecords()
|
||||
{
|
||||
global $eof;
|
||||
readFromBuffer(32);
|
||||
while (true) {
|
||||
$record = new PMA_ShapeRecord(-1);
|
||||
$record->loadFromFile($this->SHPFile, $this->DBFFile);
|
||||
if ($record->lastError != "") {
|
||||
return false;
|
||||
}
|
||||
if ($eof) {
|
||||
break;
|
||||
}
|
||||
|
||||
$this->records[] = $record;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends ShapeRecord class to cater the following phpMyAdmin
|
||||
* specific requirements.
|
||||
* 1) To load data from .dbf file only when the dBase extension is available.
|
||||
* 2) To use PMA_importGetNextChunk() functionality to read data, rather than
|
||||
* reading directly from a file. Using readFromBuffer() in place of fread().
|
||||
* This makes it possible to use compressions.
|
||||
*/
|
||||
class PMA_ShapeRecord extends ShapeRecord
|
||||
{
|
||||
function loadFromFile(&$SHPFile, &$DBFFile)
|
||||
{
|
||||
$this->DBFFile = $DBFFile;
|
||||
$this->_loadHeaders();
|
||||
|
||||
switch ($this->shapeType) {
|
||||
case 0:
|
||||
$this->_loadNullRecord();
|
||||
break;
|
||||
case 1:
|
||||
$this->_loadPointRecord();
|
||||
break;
|
||||
case 3:
|
||||
$this->_loadPolyLineRecord();
|
||||
break;
|
||||
case 5:
|
||||
$this->_loadPolygonRecord();
|
||||
break;
|
||||
case 8:
|
||||
$this->_loadMultiPointRecord();
|
||||
break;
|
||||
default:
|
||||
$this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
|
||||
break;
|
||||
}
|
||||
if (extension_loaded('dbase') && isset($this->DBFFile)) {
|
||||
$this->_loadDBFData();
|
||||
}
|
||||
}
|
||||
|
||||
function _loadHeaders()
|
||||
{
|
||||
$this->recordNumber = loadData("N", readFromBuffer(4));
|
||||
//We read the length of the record
|
||||
$tmp = loadData("N", readFromBuffer(4));
|
||||
$this->shapeType = loadData("V", readFromBuffer(4));
|
||||
}
|
||||
|
||||
function _loadPoint()
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$data["x"] = loadData("d", readFromBuffer(8));
|
||||
$data["y"] = loadData("d", readFromBuffer(8));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
function _loadMultiPointRecord()
|
||||
{
|
||||
$this->SHPData = array();
|
||||
$this->SHPData["xmin"] = loadData("d", readFromBuffer(8));
|
||||
$this->SHPData["ymin"] = loadData("d", readFromBuffer(8));
|
||||
$this->SHPData["xmax"] = loadData("d", readFromBuffer(8));
|
||||
$this->SHPData["ymax"] = loadData("d", readFromBuffer(8));
|
||||
|
||||
$this->SHPData["numpoints"] = loadData("V", readFromBuffer(4));
|
||||
|
||||
for ($i = 0; $i <= $this->SHPData["numpoints"]; $i++) {
|
||||
$this->SHPData["points"][] = $this->_loadPoint();
|
||||
}
|
||||
}
|
||||
|
||||
function _loadPolyLineRecord()
|
||||
{
|
||||
$this->SHPData = array();
|
||||
$this->SHPData["xmin"] = loadData("d", readFromBuffer(8));
|
||||
$this->SHPData["ymin"] = loadData("d", readFromBuffer(8));
|
||||
$this->SHPData["xmax"] = loadData("d", readFromBuffer(8));
|
||||
$this->SHPData["ymax"] = loadData("d", readFromBuffer(8));
|
||||
|
||||
$this->SHPData["numparts"] = loadData("V", readFromBuffer(4));
|
||||
$this->SHPData["numpoints"] = loadData("V", readFromBuffer(4));
|
||||
|
||||
for ($i = 0; $i < $this->SHPData["numparts"]; $i++) {
|
||||
$this->SHPData["parts"][$i] = loadData("V", readFromBuffer(4));
|
||||
}
|
||||
|
||||
$readPoints = 0;
|
||||
reset($this->SHPData["parts"]);
|
||||
while (list($partIndex, $partData) = each($this->SHPData["parts"])) {
|
||||
if (! isset($this->SHPData["parts"][$partIndex]["points"])
|
||||
|| !is_array($this->SHPData["parts"][$partIndex]["points"])
|
||||
) {
|
||||
$this->SHPData["parts"][$partIndex] = array();
|
||||
$this->SHPData["parts"][$partIndex]["points"] = array();
|
||||
}
|
||||
while (! in_array($readPoints, $this->SHPData["parts"])
|
||||
&& ($readPoints < ($this->SHPData["numpoints"]))
|
||||
) {
|
||||
$this->SHPData["parts"][$partIndex]["points"][] = $this->_loadPoint();
|
||||
$readPoints++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$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($cfg['TempDir'])
|
||||
&& is_writable($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($cfg['TempDir']),
|
||||
array($dbf_file_name)
|
||||
);
|
||||
if ($extracted) {
|
||||
$dbf_file_path = realpath($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;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If file is in UploadDir, use .dbf file in the same UploadDir
|
||||
// to load extra data.
|
||||
elseif (! empty($local_import_file)
|
||||
&& ! empty($cfg['UploadDir'])
|
||||
&& $compression == 'none'
|
||||
) {
|
||||
// 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) {
|
||||
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',
|
||||
);
|
||||
|
||||
include_once './libraries/gis/pma_gis_geometry.php';
|
||||
switch ($shp->shapeType) {
|
||||
// ESRI Null Shape
|
||||
case 0:
|
||||
$gis_obj = null;
|
||||
break;
|
||||
// ESRI Point
|
||||
case 1:
|
||||
include_once './libraries/gis/pma_gis_point.php';
|
||||
$gis_obj = PMA_GIS_Point::singleton();
|
||||
break;
|
||||
// ESRI PolyLine
|
||||
case 3:
|
||||
include_once './libraries/gis/pma_gis_multilinestring.php';
|
||||
$gis_obj = PMA_GIS_Multilinestring::singleton();
|
||||
break;
|
||||
// ESRI Polygon
|
||||
case 5:
|
||||
include_once './libraries/gis/pma_gis_multipolygon.php';
|
||||
$gis_obj = PMA_GIS_Multipolygon::singleton();
|
||||
break;
|
||||
// ESRI MultiPoint
|
||||
case 8:
|
||||
include_once './libraries/gis/pma_gis_multipoint.php';
|
||||
$gis_obj = PMA_GIS_Multipoint::singleton();
|
||||
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($param);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$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 = PMA_DBI_fetch_result('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();
|
||||
}
|
||||
?>
|
Reference in New Issue
Block a user