Merge remote-tracking branch 'origin/master'

This commit is contained in:
Pootle server 2011-08-17 16:40:13 +02:00
commit cf8803fd44
45 changed files with 5090 additions and 262 deletions

View File

@ -44,6 +44,9 @@ phpMyAdmin - ChangeLog
- bug #3380946 [export] no uid Query result export (Suhosin limit)
+ Grid editing in browse mode (replaces row inline edit)
+ Zoom-search in table Search
+ [interface] Editor for GIS data
+ [import] Import GIS data from ESRI Shapefiles
+ [interface] 'Function based search' for GIS data
3.4.5.0 (not yet released)
- bug #3375325 [interface] Page list in navigation frame looks odd

View File

@ -2088,9 +2088,10 @@ $cfg['TrustedProxies'] =
The name of the directory where temporary files can be stored.
<br /><br />
This is needed to work around limitations of <tt>open_basedir</tt>
for uploaded files, see
<a href="#faq1_11"><abbr title="Frequently Asked Questions">FAQ</abbr>
This is needed for importing ESRI Shapefiles, see
<a href="#faq6_30"><abbr title="Frequently Asked Questions">FAQ</abbr>
6.30</a> and to work around limitations of <tt>open_basedir</tt> for uploaded
files, see <a href="#faq1_11"><abbr title="Frequently Asked Questions">FAQ</abbr>
1.11</a>.
<br /><br />
@ -4373,6 +4374,41 @@ INSERT INTO REL_towns VALUES ('M', 'Montr&eacute;al');
<p> Not every table can be put to the chart. Only tables with one, two or three columns can be visualised as a chart. Moreover the table must be in a special format for chart script to understand it. Currently supported formats can be found in the <a href="http://wiki.phpmyadmin.net/pma/Charts#Data_formats_for_query_results_chart">wiki</a>.</p>
<h4 id="faq6_30">
<a href="#faq6_30">6.30 Import: How can I import ESRI Shapefiles</a></h4>
<p>
An ESRI Shapefile is actually a set of several files, where .shp file contains
geometry data and .dbf file contains data related to those geometry data.
To read data from .dbf file you need to have PHP compiled with the dBase extension
(--enable-dbase). Otherwise only geometry data will be imported.
</p>
<p>To upload these set of files you can use either of the following methods:</p>
<ul>
<li>
<p>
Configure upload directory with
<a href="#cfg_UploadDir" class="configrule">$cfg['UploadDir']</a>, upload both
.shp and .dbf files with the same filename and chose the .shp file from the import page.
</p>
</li>
<li>
<p>
Create a Zip archive with .shp and .dbf files and import it. For this to work,
you need to set <a href="#cfg_TempDir" class="configrule">$cfg['TempDir']</a> to a
place where the web server user can write (for example <tt>'./tmp'</tt>).
</p>
<p> To create the temporary directory on a UNIX-based system, you can do:</p>
<pre>
cd phpMyAdmin
mkdir tmp
chmod o+rwx tmp
</pre>
</li>
</ul>
<h3 id="faqproject">phpMyAdmin project</h3>
<h4 id="faq7_1">

335
gis_data_editor.php Normal file
View File

@ -0,0 +1,335 @@
<?php
require_once './libraries/common.inc.php';
if (! isset($_REQUEST['get_gis_editor']) && ! isset($_REQUEST['generate'])) {
require_once './libraries/header_http.inc.php';
require_once './libraries/header_meta_style.inc.php';
}
require_once './libraries/gis/pma_gis_factory.php';
require_once './libraries/gis_visualization.lib.php';
// Get data if any posted
$gis_data = array();
if (PMA_isValid($_REQUEST['gis_data'], 'array')) {
$gis_data = $_REQUEST['gis_data'];
}
$gis_types = array(
'POINT',
'MULTIPOINT',
'LINESTRING',
'MULTILINESTRING',
'POLYGON',
'MULTIPOLYGON',
'GEOMETRYCOLLECTION'
);
// Extract type from the initial call and make sure that it's a valid one.
// Extract from field's values if availbale, if not use the column type passed.
if (! isset($gis_data['gis_type'])) {
if (isset($_REQUEST['type']) && $_REQUEST['type'] != '') {
$gis_data['gis_type'] = strtoupper($_REQUEST['type']);
}
if (isset($_REQUEST['value']) && trim($_REQUEST['value']) != '') {
$start = (substr($_REQUEST['value'], 0, 1) == "'") ? 1 : 0;
$gis_data['gis_type'] = substr($_REQUEST['value'], $start, strpos($_REQUEST['value'], "(") - $start);
}
if((! isset($gis_data['gis_type'])) || (! in_array($gis_data['gis_type'], $gis_types))) {
$gis_data['gis_type'] = $gis_types[0];
}
}
$geom_type = $gis_data['gis_type'];
// Generate parameters from value passed.
$gis_obj = PMA_GIS_Factory::factory($geom_type);
if (isset($_REQUEST['value'])) {
$gis_data = array_merge($gis_data, $gis_obj->generateParams($_REQUEST['value']));
}
// Generate Well Known Text
$srid = (isset($gis_data['srid']) && $gis_data['srid'] != '') ? htmlspecialchars($gis_data['srid']) : 0;
$wkt = $gis_obj->generateWkt($gis_data, 0);
$wkt_with_zero = $gis_obj->generateWkt($gis_data, 0, '0');
$result = "'" . $wkt . "'," . $srid;
// Gererate PNG or SVG based visualization
$format = (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER <= 8) ? 'png' : 'svg';
$visualizationSettings = array('width' => 450, 'height' => 300, 'spatialColumn' => 'wkt');
$data = array(array('wkt' => $wkt_with_zero, 'srid' => $srid));
$visualization = PMA_GIS_visualizationResults($data, $visualizationSettings, $format);
$open_layers = PMA_GIS_visualizationResults($data, $visualizationSettings, 'ol');
// If the call is to update the WKT and visualization make an AJAX response
if(isset($_REQUEST['generate']) && $_REQUEST['generate'] == true) {
$extra_data = array(
'result' => $result,
'visualization' => $visualization,
'openLayers' => $open_layers,
);
PMA_ajaxResponse(null, true, $extra_data);
}
// If the call is to get the whole content, start buffering, skipping </head> and <body> tags
if(isset($_REQUEST['get_gis_editor']) && $_REQUEST['get_gis_editor'] == true) {
ob_start();
} else {
?>
</head>
<body>
<?php
}
?>
<form id="gis_data_editor_form" action="gis_data_editor.php" method="post">
<input type="hidden" id="pmaThemeImage" value="<?php echo($GLOBALS['pmaThemeImage']); ?>" />
<div id="gis_data_editor">
<h3><?php printf(__('Value for the column "%s"'), htmlspecialchars($_REQUEST['field'])); ?></h3>
<?php echo('<input type="hidden" name="field" value="' . htmlspecialchars($_REQUEST['field']) . '" />');
// The input field to which the final result should be added and corresponding null checkbox
if (isset($_REQUEST['input_name'])) {
echo('<input type="hidden" name="input_name" value="' . htmlspecialchars($_REQUEST['input_name']) . '" />');
}
echo PMA_generate_common_hidden_inputs();
?>
<!-- Visualization section -->
<div id="placeholder" style="width:450px;height:300px;
<?php if ($srid != 0) {
echo('display:none;');
}
?> ">
<?php echo ($visualization);
?> </div>
<div id="openlayersmap" style="width:450px;height:300px;
<?php if ($srid == 0) {
echo('display:none;');
}
?> ">
</div>
<div class="choice" style="float:right;clear:right;">
<input type="checkbox" id="choice" value="useBaseLayer"
<?php if ($srid != 0) {
echo(' checked="checked"');
}
?> />
<label for="choice"><?php echo __("Use OpenStreetMaps as Base Layer"); ?></label>
</div>
<script language="javascript" type="text/javascript">
<?php echo($open_layers); ?>
</script>
<!-- End of visualization section -->
<!-- Header section - Inclueds GIS type selector and input field for SRID -->
<div id="gis_data_header">
<select name="gis_data[gis_type]" class="gis_type">
<?php
foreach ($gis_types as $gis_type) {
echo('<option value="' . $gis_type . '"');
if ($geom_type == $gis_type) {
echo(' selected="selected"');
}
echo('>' . $gis_type . '</option>');
}
?>
</select>
<input type="submit" name="gis_data[go]" class="go" value="<?php echo __("Go")?>" />
<label for="srid"><?php echo __("SRID"); ?>:&nbsp;</label>
<input name="gis_data[srid]" type="text" value="<?php echo($srid); ?>" />
</div>
<!-- End of header section -->
<!-- Data section -->
<div id="gis_data">
<?php $geom_count = 1;
if ($geom_type == 'GEOMETRYCOLLECTION') {
$geom_count = (isset($gis_data[$geom_type]['geom_count'])) ? $gis_data[$geom_type]['geom_count'] : 1;
if (isset($gis_data[$geom_type]['add_geom'])) {
$geom_count++;
}
echo('<input type="hidden" name="gis_data[GEOMETRYCOLLECTION][geom_count]" value="' . $geom_count . '">');
}
for ($a = 0; $a < $geom_count; $a++) {
if ($geom_type == 'GEOMETRYCOLLECTION') {
echo('<br/><br/>'); echo __("Geometry"); echo($a + 1 . ':<br/>');
if (isset($gis_data[$a]['gis_type'])) {
$type = $gis_data[$a]['gis_type'];
} else {
$type = $gis_types[0];
}
echo('<select name="gis_data[' . $a . '][gis_type]" class="gis_type">');
foreach (array_slice($gis_types, 0, 6) as $gis_type) {
echo('<option value="' . $gis_type . '"');
if ($type == $gis_type) {
echo(' selected="selected"');
}
echo('>' . $gis_type . '</option>');
}
echo('</select>');
echo('<input type="submit" name="gis_data[' . $a . '][go]" class="go" value="'); echo __("Go"); echo('">');
} else {
$type = $geom_type;
}
if ($type == 'POINT') {
echo('<br/>'); echo __("Point"); echo(' :');
?> <label for="x"><?php echo __("X"); ?></label>
<input name="gis_data[<?php echo($a); ?>][POINT][x]" type="text" value="<?php echo(isset($gis_data[$a]['POINT']['x']) ? htmlspecialchars($gis_data[$a]['POINT']['x']) : ''); ?>" />
<label for="y"><?php echo __("Y"); ?></label>
<input name="gis_data[<?php echo($a); ?>][POINT][y]" type="text" value="<?php echo(isset($gis_data[$a]['POINT']['y']) ? htmlspecialchars($gis_data[$a]['POINT']['y']) : ''); ?>" />
<?php
} elseif ($type == 'MULTIPOINT' || $type == 'LINESTRING') {
$no_of_points = isset($gis_data[$a][$type]['no_of_points']) ? $gis_data[$a][$type]['no_of_points'] : 1;
if ($type == 'LINESTRING' && $no_of_points < 2) {
$no_of_points = 2;
}
if ($type == 'MULTIPOINT' && $no_of_points < 1) {
$no_of_points = 1;
}
if (isset($gis_data[$a][$type]['add_point'])) {
$no_of_points++;
}
echo('<input type="hidden" name="gis_data[' . $a . '][' . $type . '][no_of_points]" value="' . $no_of_points . '">');
for ($i = 0; $i < $no_of_points; $i++) {
echo('<br/>'); echo __("Point"); echo($i + 1 . ':');
?> <label for="x"><?php echo __("X"); ?></label>
<input type="text" name="gis_data[<?php echo($a); ?>][<?php echo($type); ?>][<?php echo($i); ?>][x]" value="<?php echo(isset($gis_data[$a][$type][$i]['x']) ? htmlspecialchars($gis_data[$a][$type][$i]['x']) : ''); ?>" />
<label for="y"><?php echo __("Y"); ?></label>
<input type="text" name="gis_data[<?php echo($a); ?>][<?php echo($type); ?>][<?php echo($i); ?>][y]" value="<?php echo(isset($gis_data[$a][$type][$i]['y']) ? htmlspecialchars($gis_data[$a][$type][$i]['y']) : ''); ?>" />
<?php
}
?>
<input type="submit" name="gis_data[<?php echo($a); ?>][<?php echo($type); ?>][add_point]" class="add addPoint" value="<?php echo __("Add a point"); ?>">
<?php
} elseif ($type == 'MULTILINESTRING' || $type == 'POLYGON') {
$no_of_lines = isset($gis_data[$a][$type]['no_of_lines']) ? $gis_data[$a][$type]['no_of_lines'] : 1;
if ($no_of_lines < 1) {
$no_of_lines = 1;
}
if (isset($gis_data[$a][$type]['add_line'])) {
$no_of_lines++;
}
echo('<input type="hidden" name="gis_data[' . $a . '][' . $type . '][no_of_lines]" value="' . $no_of_lines . '">');
for ($i = 0; $i < $no_of_lines; $i++) {
echo('<br/>');
if ($type == 'MULTILINESTRING') {
echo __("Linestring"); echo($i + 1 . ':');
} else {
if ($i == 0) {
echo __("Outer Ring:");
} else {
echo __("Inner Ring"); echo($i . ':');
}
}
$no_of_points = isset($gis_data[$a][$type][$i]['no_of_points']) ? $gis_data[$a][$type][$i]['no_of_points'] : 2;
if ($type == 'MULTILINESTRING' && $no_of_points < 2) {
$no_of_points = 2;
}
if ($type == 'POLYGON' && $no_of_points < 4) {
$no_of_points = 4;
}
if (isset($gis_data[$a][$type][$i]['add_point'])) {
$no_of_points++;
}
echo('<input type="hidden" name="gis_data[' . $a . '][' . $type . '][' . $i . '][no_of_points]" value="' . $no_of_points . '">');
for ($j = 0; $j < $no_of_points; $j++) {
echo('<br/>'); echo __("Point"); echo($j + 1 . ':');
?> <label for="x"><?php echo __("X"); ?></label>
<input type="text" name="gis_data[<?php echo($a); ?>][<?php echo($type); ?>][<?php echo($i); ?>][<?php echo($j); ?>][x]" value="<?php echo(isset($gis_data[$a][$type][$i][$j]['x']) ? htmlspecialchars($gis_data[$a][$type][$i][$j]['x']) : ''); ?>" />
<label for="y"><?php echo __("Y"); ?></label>
<input type="text" name="gis_data[<?php echo($a); ?>][<?php echo($type); ?>][<?php echo($i); ?>][<?php echo($j); ?>][y]" value="<?php echo(isset($gis_data[$a][$type][$i][$j]['x']) ? htmlspecialchars($gis_data[$a][$type][$i][$j]['y']) : ''); ?>" />
<?php }
?> <input type="submit" name="gis_data[<?php echo($a); ?>][<?php echo($type); ?>][<?php echo($i); ?>][add_point]" class="add addPoint" value="<?php echo __("Add a point"); ?>">
<?php }
$caption = ($type == 'MULTILINESTRING') ? __('Add a linestring') : __('Add an inner ring');
?> <br/><input type="submit" name="gis_data[<?php echo($a); ?>][<?php echo($type); ?>][add_line]" class="add addLine" value="<?php echo($caption); ?>">
<?php
} elseif ($type == 'MULTIPOLYGON') {
$no_of_polygons = isset($gis_data[$a][$type]['no_of_polygons']) ? $gis_data[$a][$type]['no_of_polygons'] : 1;
if ($no_of_polygons < 1) {
$no_of_polygons = 1;
}
if (isset($gis_data[$a][$type]['add_polygon'])) {
$no_of_polygons++;
}
echo('<input type="hidden" name="gis_data[' . $a . '][' . $type . '][no_of_polygons]" value="' . $no_of_polygons . '">');
for ($k = 0; $k < $no_of_polygons; $k++) {
echo('<br/>'); echo __("Polygon"); echo($k + 1 . ':');
$no_of_lines = isset($gis_data[$a][$type][$k]['no_of_lines']) ? $gis_data[$a][$type][$k]['no_of_lines'] : 1;
if ($no_of_lines < 1) {
$no_of_lines = 1;
}
if (isset($gis_data[$a][$type][$k]['add_line'])) {
$no_of_lines++;
}
echo('<input type="hidden" name="gis_data[' . $a . '][' . $type . '][' . $k . '][no_of_lines]" value="' . $no_of_lines . '">');
for ($i = 0; $i < $no_of_lines; $i++) {
echo('<br/><br/>');
if ($i == 0) {
echo __("Outer Ring:");
} else {
echo __("Inner Ring"); echo($i . ':');
}
$no_of_points = isset($gis_data[$a][$type][$k][$i]['no_of_points']) ? $gis_data[$a][$type][$k][$i]['no_of_points'] : 4;
if ($no_of_points < 4) {
$no_of_points = 4;
}
if (isset($gis_data[$a][$type][$k][$i]['add_point'])) {
$no_of_points++;
}
echo('<input type="hidden" name="gis_data[' . $a . '][' . $type . '][' . $k . '][' . $i . '][no_of_points]" value="' . $no_of_points . '">');
for ($j = 0; $j < $no_of_points; $j++) {
echo('<br/>'); echo __("Point"); echo($j + 1 . ':');
?> <label for="x"><?php echo __("X"); ?></label>
<input type="text" name="<?php echo("gis_data[" . $a . "][" . $type . "][" . $k . "][" . $i . "][" . $j . "][x]"); ?>" value="<?php echo(isset($gis_data[$a][$type][$k][$i][$j]['x']) ? htmlspecialchars($gis_data[$a][$type][$k][$i][$j]['x']) : ''); ?>" />
<label for="y"><?php echo __("Y"); ?></label>
<input type="text" name="<?php echo("gis_data[" . $a . "][" . $type . "][" . $k . "][" . $i . "][" . $j . "][y]"); ?>" value="<?php echo(isset($gis_data[$a][$type][$k][$i][$j]['y']) ? htmlspecialchars($gis_data[$a][$type][$k][$i][$j]['y']) : ''); ?>" />
<?php }
?> <input type="submit" name="<?php echo("gis_data[" . $a . "][" . $type . "][" . $k . "][" . $i . "][add_point]"); ?>" class="add addPoint" value="<?php echo __("Add a point"); ?>">
<?php }
?> <br/><input type="submit" name="<?php echo("gis_data[" . $a . "][" . $type . "][" . $k . "][add_line]"); ?>" class="add addLine" value="<?php echo __('Add an inner ring') ?>"><br/>
<?php }
?> <br/><input type="submit" name="<?php echo("gis_data[" . $a . "][" . $type . "][add_polygon]"); ?>" class="add addPolygon" value="<?php echo __('Add a polygon') ?>">
<?php }
}
if ($geom_type == 'GEOMETRYCOLLECTION') {
?> <br/><br/><input type="submit" name="gis_data[GEOMETRYCOLLECTION][add_geom]" class="add addGeom" value="<?php echo __("Add geometry"); ?>" />
<?php }
?> </div>
<!-- End of data section -->
<br/><input type="submit" name="gis_data[save]" value="<?php echo __('Go') ?>">
<div id="gis_data_output">
<h3><?php echo __('Output'); ?></h3>
<p><?php echo __('Chose "GeomFromText" from the "Function" column and paste the below string into the "Value" field'); ?></p>
<textarea id="gis_data_textarea" cols="95" rows="5">
<?php echo($result);
?> </textarea>
</div>
</div>
</form>
<?php
// If the call is to get the whole content, get the content in the buffer and make and AJAX response.
if(isset($_REQUEST['get_gis_editor']) && $_REQUEST['get_gis_editor'] == true) {
$extra_data['gis_editor'] = ob_get_contents();
PMA_ajaxResponse(NULL, ob_end_clean(), $extra_data);
}
?>
</body>
<?php
/**
* Displays the footer
*/
require './libraries/footer.inc.php';
?>

125
js/OpenStreetMap.js Normal file
View File

@ -0,0 +1,125 @@
/**
* Namespace: Util.OSM
*/
OpenLayers.Util.OSM = {};
/**
* Constant: MISSING_TILE_URL
* {String} URL of image to display for missing tiles
*/
OpenLayers.Util.OSM.MISSING_TILE_URL = "http://www.openstreetmap.org/openlayers/img/404.png";
/**
* Property: originalOnImageLoadError
* {Function} Original onImageLoadError function.
*/
OpenLayers.Util.OSM.originalOnImageLoadError = OpenLayers.Util.onImageLoadError;
/**
* Function: onImageLoadError
*/
OpenLayers.Util.onImageLoadError = function() {
if (this.src.match(/^http:\/\/[abc]\.[a-z]+\.openstreetmap\.org\//)) {
this.src = OpenLayers.Util.OSM.MISSING_TILE_URL;
} else if (this.src.match(/^http:\/\/[def]\.tah\.openstreetmap\.org\//)) {
// do nothing - this layer is transparent
} else {
OpenLayers.Util.OSM.originalOnImageLoadError;
}
};
/**
* Class: OpenLayers.Layer.OSM.Mapnik
*
* Inherits from:
* - <OpenLayers.Layer.OSM>
*/
OpenLayers.Layer.OSM.Mapnik = OpenLayers.Class(OpenLayers.Layer.OSM, {
/**
* Constructor: OpenLayers.Layer.OSM.Mapnik
*
* Parameters:
* name - {String}
* options - {Object} Hashtable of extra options to tag onto the layer
*/
initialize: function(name, options) {
var url = [
"http://a.tile.openstreetmap.org/${z}/${x}/${y}.png",
"http://b.tile.openstreetmap.org/${z}/${x}/${y}.png",
"http://c.tile.openstreetmap.org/${z}/${x}/${y}.png"
];
options = OpenLayers.Util.extend({
numZoomLevels: 19,
buffer: 0,
transitionEffect: "resize"
}, options);
var newArguments = [name, url, options];
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
},
CLASS_NAME: "OpenLayers.Layer.OSM.Mapnik"
});
/**
* Class: OpenLayers.Layer.OSM.Osmarender
*
* Inherits from:
* - <OpenLayers.Layer.OSM>
*/
OpenLayers.Layer.OSM.Osmarender = OpenLayers.Class(OpenLayers.Layer.OSM, {
/**
* Constructor: OpenLayers.Layer.OSM.Osmarender
*
* Parameters:
* name - {String}
* options - {Object} Hashtable of extra options to tag onto the layer
*/
initialize: function(name, options) {
var url = [
"http://a.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png",
"http://b.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png",
"http://c.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png"
];
options = OpenLayers.Util.extend({
numZoomLevels: 18,
buffer: 0,
transitionEffect: "resize"
}, options);
var newArguments = [name, url, options];
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
},
CLASS_NAME: "OpenLayers.Layer.OSM.Osmarender"
});
/**
* Class: OpenLayers.Layer.OSM.CycleMap
*
* Inherits from:
* - <OpenLayers.Layer.OSM>
*/
OpenLayers.Layer.OSM.CycleMap = OpenLayers.Class(OpenLayers.Layer.OSM, {
/**
* Constructor: OpenLayers.Layer.OSM.CycleMap
*
* Parameters:
* name - {String}
* options - {Object} Hashtable of extra options to tag onto the layer
*/
initialize: function(name, options) {
var url = [
"http://a.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png",
"http://b.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png",
"http://c.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png"
];
options = OpenLayers.Util.extend({
numZoomLevels: 19,
buffer: 0,
transitionEffect: "resize"
}, options);
var newArguments = [name, url, options];
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
},
CLASS_NAME: "OpenLayers.Layer.OSM.CycleMap"
});

309
js/gis_data_editor.js Normal file
View File

@ -0,0 +1,309 @@
/**
* @fileoverview functions used in GIS data editor
*
* @requires jQuery
*
*/
/**
* Closes the GIS data editor and perform necessary clean up work.
*/
function closeGISEditor(){
$("#popup_background").fadeOut("fast");
$("#gis_editor").fadeOut("fast");
$("#gis_editor").html('');
}
/**
* Prepares the HTML recieved via AJAX.
*/
function prepareJSVersion() {
// Hide 'Go' buttons associated with the dropdowns
$('.go').hide();
// Change the text on the submit button
$("input[name='gis_data[save]']")
.attr('value', PMA_messages['strCopy'])
.insertAfter($('#gis_data_textarea'))
.before('<br><br>');
// Add close and cancel links
$('#gis_data_editor').prepend('<a class="close_gis_editor">' + PMA_messages['strClose'] + '</a>');
$('<a class="cancel_gis_editor"> ' + PMA_messages['strCancel'] + '</a>')
.insertAfter($("input[name='gis_data[save]']"));
// Remove the unnecessary text
$('div#gis_data_output p').remove();
// Remove 'add' buttons and add links
$('.add').each(function(e) {
var $button = $(this);
$button.addClass('addJs').removeClass('add');
var classes = $button.attr('class');
$button
.after('<a class="' + classes + '" name="' + $button.attr('name')
+ '">+ ' + $button.attr('value') + '</a>')
.remove();
});
}
/**
* Returns the HTML for a data point.
*
* @param pointNumber point number
* @param prefix prefix of the name
* @returns the HTML for a data point
*/
function addDataPoint(pointNumber, prefix) {
return '<br>' + PMA_messages['strPoint'] + (pointNumber + 1) + ':'
+ '<label for="x"> ' + PMA_messages['strX'] + ' </label>'
+ '<input type="text" name="' + prefix + '[' + pointNumber + '][x]" value="">'
+ '<label for="y"> ' + PMA_messages['strY'] + ' </label>'
+ '<input type="text" name="' + prefix + '[' + pointNumber + '][y]" value="">';
}
/**
* Initialize the visualization in the GIS data editor.
*/
function initGISEditorVisualization() {
// Loads either SVG or OSM visualization based on the choice
selectVisualization();
// Adds necessary styles to the div that coontains the openStreetMap
styleOSM();
// Loads the SVG element and make a reference to it
loadSVG();
// Adds controllers for zooming and panning
addZoomPanControllers();
zoomAndPan();
}
/**
* Opens up the GIS data editor.
*
* @param value current value of the geometry field
* @param field field name
* @param type geometry type
* @param input_name name of the input field
* @param token token
*/
function openGISEditor(value, field, type, input_name, token) {
// Center the popup
var windowWidth = document.documentElement.clientWidth;
var windowHeight = document.documentElement.clientHeight;
var popupWidth = windowWidth * 0.9;
var popupHeight = windowHeight * 0.9;
var popupOffsetTop = windowHeight / 2 - popupHeight / 2;
var popupOffsetLeft = windowWidth / 2 - popupWidth / 2;
var $gis_editor = $("#gis_editor");
$gis_editor.css({"top": popupOffsetTop, "left": popupOffsetLeft, "width": popupWidth, "height": popupHeight});
$.post('gis_data_editor.php', {
'field' : field,
'value' : value,
'type' : type,
'input_name' : input_name,
'get_gis_editor' : true,
'token' : token
}, function(data) {
if(data.success == true) {
$gis_editor.html(data.gis_editor);
initGISEditorVisualization();
prepareJSVersion();
} else {
PMA_ajaxShowMessage(data.error);
}
}, 'json');
// Make it appear
$("#popup_background").css({"opacity":"0.7"});
$("#popup_background").fadeIn("fast");
$gis_editor.fadeIn("fast");
}
/**
* Prepare and insert the GIS data in Well Known Text format
* to the input field.
*/
function insertDataAndClose() {
var $form = $('form#gis_data_editor_form');
var input_name = $form.find("input[name='input_name']").val();
$.post('gis_data_editor.php', $form.serialize() + "&generate=true", function(data) {
if(data.success == true) {
$("input[name='" + input_name + "']").val(data.result);
} else {
PMA_ajaxShowMessage(data.error);
}
}, 'json');
closeGISEditor();
}
$(document).ready(function() {
// Remove the class that is added due to the URL being too long.
$('.open_gis_editor a').removeClass('formLinkSubmit');
/**
* Prepares and insert the GIS data to the input field on clicking 'copy'.
*/
$("input[name='gis_data[save]']").live('click', function(event) {
event.preventDefault();
insertDataAndClose();
});
/**
* Prepares and insert the GIS data to the input field on pressing 'enter'.
*/
$('#gis_editor').live('submit', function(event) {
event.preventDefault();
insertDataAndClose();
});
/**
* Trigger asynchronous calls on data change and update the output.
*/
$('#gis_editor').find("input[type='text']").live('change', function() {
var $form = $('form#gis_data_editor_form');
$.post('gis_data_editor.php', $form.serialize() + "&generate=true", function(data) {
if(data.success == true) {
$('#gis_data_textarea').val(data.result);
$('#placeholder').empty().removeClass('hasSVG').html(data.visualization);
$('#openlayersmap').empty();
eval(data.openLayers);
initGISEditorVisualization();
} else {
PMA_ajaxShowMessage(data.error);
}
}, 'json');
});
/**
* Update the form on change of the GIS type.
*/
$(".gis_type").live('change', function(event) {
var $gis_editor = $("#gis_editor");
var $form = $('form#gis_data_editor_form');
$.post('gis_data_editor.php', $form.serialize() + "&get_gis_editor=true", function(data) {
if(data.success == true) {
$gis_editor.html(data.gis_editor);
initGISEditorVisualization();
prepareJSVersion();
} else {
PMA_ajaxShowMessage(data.error);
}
}, 'json');
});
/**
* Handles closing of the GIS data editor.
*/
$('.close_gis_editor, .cancel_gis_editor').live('click', function() {
closeGISEditor();
});
/**
* Handles adding data points
*/
$('.addJs.addPoint').live('click', function() {
var $a = $(this);
var name = $a.attr('name');
// Eg. name = gis_data[0][MULTIPOINT][add_point] => prefix = gis_data[0][MULTIPOINT]
var prefix = name.substr(0, name.length - 11);
// Find the number of points
var $noOfPointsInput = $("input[name='" + prefix + "[no_of_points]" + "']");
var noOfPoints = parseInt($noOfPointsInput.attr('value'));
// Add the new data point
var html = addDataPoint(noOfPoints, prefix);
$a.before(html);
$noOfPointsInput.attr('value', noOfPoints + 1);
});
/**
* Handles adding linestrings and inner rings
*/
$('.addLine.addJs').live('click', function() {
var $a = $(this);
var name = $a.attr('name');
// Eg. name = gis_data[0][MULTILINESTRING][add_line] => prefix = gis_data[0][MULTILINESTRING]
var prefix = name.substr(0, name.length - 10);
var type = prefix.slice(prefix.lastIndexOf('[') + 1, prefix.lastIndexOf(']'));
// Find the number of lines
var $noOfLinesInput = $("input[name='" + prefix + "[no_of_lines]" + "']");
var noOfLines = parseInt($noOfLinesInput.attr('value'));
// Add the new linesting of inner ring based on the type
var html = '<br>';
if (type == 'MULTILINESTRING') {
html += PMA_messages['strLineString'] + (noOfLines + 1) + ':';
var noOfPoints = 2;
} else {
html += PMA_messages['strInnerRing'] + noOfLines + ':';
var noOfPoints = 4;
}
html += '<input type="hidden" name="' + prefix + '[' + noOfLines + '][no_of_points]" value="' + noOfPoints + '">';
for (i = 0; i < noOfPoints; i++) {
html += addDataPoint(i, (prefix + '[' + noOfLines + ']'));
}
html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfLines + '][add_point]">+ '
+ PMA_messages['strAddPoint'] + '</a><br>';
$a.before(html);
$noOfLinesInput.attr('value', noOfLines + 1);
});
/**
* Handles adding polygons
*/
$('.addJs.addPolygon').live('click', function() {
var $a = $(this);
var name = $a.attr('name');
// Eg. name = gis_data[0][MULTIPOLYGON][add_polygon] => prefix = gis_data[0][MULTIPOLYGON]
var prefix = name.substr(0, name.length - 13);
// Find the number of polygons
var $noOfPolygonsInput = $("input[name='" + prefix + "[no_of_polygons]" + "']");
var noOfPolygons = parseInt($noOfPolygonsInput.attr('value'));
// Add the new polygon
var html = PMA_messages['strPolygon'] + (noOfPolygons + 1) + ':<br>';
html += '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][no_of_lines]" value="1">';
+ '<br>' + PMA_messages['strOuterRing'] + ':';
+ '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][0][no_of_points]" value="4">';
for (i = 0; i < 4; i++) {
html += addDataPoint(i, (prefix + '[' + noOfPolygons + '][0]'));
}
html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfPolygons + '][0][add_point]">+ '
+ PMA_messages['strAddPoint'] + '</a><br>'
+ '<a class="addLine addJs" name="' + prefix + '[' + noOfPolygons + '][add_line]">+ '
+ PMA_messages['strAddInnerRing'] + '</a><br><br>';
$a.before(html);
$noOfPolygonsInput.attr('value', noOfPolygons + 1);
});
/**
* Handles adding geoms
*/
$('.addJs.addGeom').live('click', function() {
var $a = $(this);
var prefix = 'gis_data[GEOMETRYCOLLECTION]';
// Find the number of geoms
var $noOfGeomsInput = $("input[name='" + prefix + "[geom_count]" + "']");
var noOfGeoms = parseInt($noOfGeomsInput.attr('value'));
var html1 = PMA_messages['strGeometry'] + (noOfGeoms + 1) + ':<br>';
var $geomType = $("select[name='gis_data[" + (noOfGeoms - 1) + "][gis_type]']").clone();
$geomType.attr('name', 'gis_data[' + noOfGeoms + '][gis_type]').val('POINT');
var html2 = '<br>' + PMA_messages['strPoint'] + ' :'
+ '<label for="x"> ' + PMA_messages['strX'] + ' </label>'
+ '<input type="text" name="gis_data[' + noOfGeoms + '][POINT][x]" value="">'
+ '<label for="y"> ' + PMA_messages['strY'] + ' </label>'
+ '<input type="text" name="gis_data[' + noOfGeoms + '][POINT][y]" value="">'
+ '<br><br>';
$a.before(html1); $geomType.insertBefore($a); $a.before(html2);
$noOfGeomsInput.attr('value', noOfGeoms + 1);
});
});

View File

@ -280,6 +280,18 @@ $js_messages['strSameInputs'] = '<strong>' . __('Select two different columns')
/* For tbl_change.js */
$js_messages['strIgnore'] = __('Ignore');
$js_messages['strCopy'] = __('Copy');
$js_messages['strX'] = __('X');
$js_messages['strY'] = __('Y');
$js_messages['strPoint'] = __('Point');
$js_messages['strLineString'] = __('Linestring');
$js_messages['strPolygon'] = __('Polygon');
$js_messages['strGeometry'] = __('Geometry');
$js_messages['strInnerRing'] = __('Inner Ring');
$js_messages['strOuterRing'] = __('Outer Ring');
$js_messages['strAddPoint'] = __('Add a point');
$js_messages['strAddInnerRing'] = __('Add an inner ring');
$js_messages['strAddPolygon'] = __('Add a polygon');
/* For tbl_structure.js */
$js_messages['strAddColumns'] = __('Add columns');

View File

@ -334,10 +334,10 @@ $(document).ready(function() {
*/
var button_options = {};
// in the following function we need to use $(this)
button_options[PMA_messages['strCancel']] = function() {$(this).parent().dialog('close').remove();}
button_options[PMA_messages['strCancel']] = function() {$(this).dialog('close').remove();}
var button_options_error = {};
button_options_error[PMA_messages['strOK']] = function() {$(this).parent().dialog('close').remove();}
button_options_error[PMA_messages['strOK']] = function() {$(this).dialog('close').remove();}
var $form = $("#resultsForm");
var $msgbox = PMA_ajaxShowMessage();
@ -351,6 +351,9 @@ $(document).ready(function() {
height: 230,
width: 900,
open: PMA_verifyTypeOfAllColumns,
close: function(event, ui) {
$('#change_row_dialog').remove();
},
buttons : button_options_error
})// end dialog options
} else {
@ -361,6 +364,9 @@ $(document).ready(function() {
height: 600,
width: 900,
open: PMA_verifyTypeOfAllColumns,
close: function(event, ui) {
$('#change_row_dialog').remove();
},
buttons : button_options
})
//Remove the top menu container from the dialog

View File

@ -218,11 +218,38 @@ function verificationsAfterFieldChange(urlField, multi_edit, theType)
* Ajax handlers for Change Table page
*
* Actions Ajaxified here:
* Submit Data to be inserted into the table
* Submit Data to be inserted into the table.
* Restart insertion with 'N' rows.
*/
$(document).ready(function() {
$('.open_gis_editor').live('click', function(event) {
event.preventDefault();
var $span = $(this);
// Current value
var value = $span.parent('td').children("input[type='text']").val();
// Field name
var field = $span.parents('tr').children('td:first').find("input[type='hidden']").val();
// Column type
var type = $span.parents('tr').find('span.column_type').text();
// Names of input field and null checkbox
var input_name = $span.parent('td').children("input[type='text']").attr('name');
//Token
var token = $("input[name='token']").val();
openGISEditor(value, field, type, input_name, token);
});
/**
* Uncheck the null checkbox as geometry data is placed on the input field
*/
$("input[name='gis_data[save]']").live('click', function(event) {
var input_name = $('form#gis_data_editor_form').find("input[name='input_name']").val();
var $null_checkbox = $("input[name='" + input_name + "']").parents('tr').find('.checkbox_null');
$null_checkbox.attr('checked', false);
});
// these were hidden via the "hide" class
$('.foreign_values_anchor').show();

View File

@ -8,7 +8,9 @@
*/
var x = 0;
var default_x = 0;
var y = 0;
var default_y = 0;
var scale = 1;
var svg;
@ -51,56 +53,52 @@ function zoomAndPan()
}
/**
* Ajax handlers for GIS visualization page
*
* Actions Ajaxified here:
*
* Zooming in and zooming out on mousewheel movement.
* Panning the visualization on dragging.
* Zooming in on double clicking.
* Zooming out on clicking the zoom out button.
* Panning on clicking the arrow buttons.
* Displaying tooltips for GIS objects.
* Initially loads either SVG or OSM visualization based on the choice.
*/
$(document).ready(function() {
var $placeholder = $('#placeholder');
var $openlayersmap = $('#openlayersmap');
if ($('#choice').prop('checked') != true) {
$openlayersmap.hide();
function selectVisualization() {
if ($('#choice').prop('checked') != true) {
$('#openlayersmap').hide();
} else {
$placeholder.hide();
$('#placeholder').hide();
}
$('.choice').show();
}
/**
* Adds necessary styles to the div that coontains the openStreetMap.
*/
function styleOSM() {
var $placeholder = $('#placeholder');
var cssObj = {
'border' : '1px solid #aaa',
'width' : $placeholder.width(),
'height' : $placeholder.height(),
'float' : 'right'
};
$openlayersmap.css(cssObj);
drawOpenLayers();
$('#openlayersmap').css(cssObj);
}
$('.choice').show();
$('#choice').bind('click', function() {
if ($(this).prop('checked') == false) {
$placeholder.show();
$openlayersmap.hide();
} else {
$placeholder.hide();
$openlayersmap.show();
}
});
/**
* Loads the SVG element and make a reference to it.
*/
function loadSVG() {
var $placeholder = $('#placeholder');
$('#placeholder').svg({
$placeholder.svg({
onLoad: function(svg_ref) {
svg = svg_ref;
}
});
// Removes the second SVG element unnecessarily added due to the above command.
$('#placeholder').find('svg:nth-child(2)').remove();
// Removes the second SVG element unnecessarily added due to the above command
$placeholder.find('svg:nth-child(2)').remove();
}
/**
* Adds controllers for zooming and panning.
*/
function addZoomPanControllers() {
var $placeholder = $('#placeholder');
if ($("#placeholder svg").length > 0) {
var pmaThemeImage = $('#pmaThemeImage').attr('value');
// add panning arrows
@ -113,7 +111,81 @@ $(document).ready(function() {
$('<img class="button" id="zoom_world" src="' + pmaThemeImage + 'zoom-world-mini.png">').appendTo($placeholder);
$('<img class="button" id="zoom_out" src="' + pmaThemeImage + 'zoom-minus-mini.png">').appendTo($placeholder);
}
}
/**
* Resizes the GIS visualization to fit into the space available.
*/
function resizeGISVisualization() {
var $placeholder = $('#placeholder');
// Hide inputs for width and height
$("input[name='visualizationSettings[width]']").parents('tr').remove();
$("input[name='visualizationSettings[height]']").parents('tr').remove();
var old_width = $placeholder.width();
var extraPadding = 100;
var leftWidth = $('.gis_table').width();
var windowWidth = document.documentElement.clientWidth;
var visWidth = windowWidth - extraPadding - leftWidth;
// Assign new value for width
$placeholder.width(visWidth);
$('svg').attr('width', visWidth);
// Assign the offset created due to resizing to default_x and center the svg.
default_x = (visWidth - old_width) / 2;
x = default_x;
}
/**
* Initialize the GIS visualization.
*/
function initGISVisualization() {
// Loads either SVG or OSM visualization based on the choice
selectVisualization();
// Resizes the GIS visualization to fit into the space available
resizeGISVisualization();
// Adds necessary styles to the div that coontains the openStreetMap
styleOSM();
// Draws openStreetMap with openLayers
drawOpenLayers();
// Loads the SVG element and make a reference to it
loadSVG();
// Adds controllers for zooming and panning
addZoomPanControllers();
zoomAndPan();
}
/**
* Ajax handlers for GIS visualization page
*
* Actions Ajaxified here:
*
* Zooming in and zooming out on mousewheel movement.
* Panning the visualization on dragging.
* Zooming in on double clicking.
* Zooming out on clicking the zoom out button.
* Panning on clicking the arrow buttons.
* Displaying tooltips for GIS objects.
*/
$(document).ready(function() {
// If we are in GIS visualization, initialize it
if ($('.gis_table').length > 0) {
initGISVisualization();
}
$('#choice').live('click', function() {
if ($(this).prop('checked') == false) {
$('#placeholder').show();
$('#openlayersmap').hide();
} else {
$('#placeholder').hide();
$('#openlayersmap').show();
}
});
$('#placeholder').live('mousewheel', function(event, delta) {
if (delta > 0) {
//zoom in
@ -135,13 +207,13 @@ $(document).ready(function() {
var dragX = 0; var dragY = 0;
$('svg').live('dragstart', function(event, dd) {
$placeholder.addClass('placeholderDrag');
$('#placeholder').addClass('placeholderDrag');
dragX = Math.round(dd.offsetX);
dragY = Math.round(dd.offsetY);
});
$('svg').live('mouseup', function(event) {
$placeholder.removeClass('placeholderDrag');
$('#placeholder').removeClass('placeholderDrag');
});
$('svg').live('drag', function(event, dd) {
@ -178,8 +250,8 @@ $(document).ready(function() {
$('#zoom_world').live('click', function(e) {
e.preventDefault();
scale = 1;
x = 0;
y = 0;
x = default_x;
y = default_y;
zoomAndPan();
});
@ -225,7 +297,7 @@ $(document).ready(function() {
*/
$('.polygon, .multipolygon, .point, .multipoint, .linestring, .multilinestring, '
+ '.geometrycollection').live('mousemove', function(event) {
contents = $(this).attr('name');
contents = $.trim($(this).attr('name'));
$("#tooltip").remove();
if (contents != '') {
$('<div id="tooltip">' + contents + '</div>').css({

View File

@ -68,7 +68,7 @@ $(document).ready(function() {
$("#sqlqueryresults").html(response);
$("#sqlqueryresults").trigger('appendAnchor');
$('#tbl_search_form')
// work around for bug #3168569 - Issue on toggling the "Hide search criteria" in chrome.
// workaround for bug #3168569 - Issue on toggling the "Hide search criteria" in chrome.
.slideToggle()
.hide();
$('#togglesearchformlink')
@ -87,4 +87,91 @@ $(document).ready(function() {
});
}) // end $.post()
})
// Following section is related to the 'function based search' for geometry data types.
// Initialy hide all the open_gis_editor spans
$('.open_search_gis_editor').hide();
$('.geom_func').bind('change', function() {
var $geomFuncSelector = $(this);
var binaryFunctions = [
'Contains',
'Crosses',
'Disjoint',
'Equals',
'Intersects',
'Overlaps',
'Touches',
'Within',
'MBRContains',
'MBRDisjoint',
'MBREquals',
'MBRIntersects',
'MBROverlaps',
'MBRTouches',
'MBRWithin',
'ST_Contains',
'ST_Crosses',
'ST_Disjoint',
'ST_Equals',
'ST_Intersects',
'ST_Overlaps',
'ST_Touches',
'ST_Within',
];
var tempArray = [
'Envelope',
'EndPoint',
'StartPoint',
'ExteriorRing',
'Centroid',
'PointOnSurface'
];
var outputGeomFunctions = binaryFunctions.concat(tempArray);
// If the chosen function takes two geomerty objects as parameters
var $operator = $geomFuncSelector.parents('tr').find('td:nth-child(5)').find('select');
if ($.inArray($geomFuncSelector.val(), binaryFunctions) >= 0){
$operator.attr('readonly', true);
} else {
$operator.attr('readonly', false);
}
// if the chosen function's output is a geometry, enable GIS editor
var $editorSpan = $geomFuncSelector.parents('tr').find('.open_search_gis_editor');
if ($.inArray($geomFuncSelector.val(), outputGeomFunctions) >= 0){
$editorSpan.show();
} else {
$editorSpan.hide();
}
});
$('.open_search_gis_editor').live('click', function(event) {
event.preventDefault();
var $span = $(this);
// Current value
var value = $span.parent('td').children("input[type='text']").val();
// Field name
var field = 'Parameter';
// Column type
var geom_func = $span.parents('tr').find('.geom_func').val();
if (geom_func == 'Envelope') {
var type = 'polygon';
} else if (geom_func == 'ExteriorRing') {
var type = 'linestring';
} else {
var type = 'point';
}
// Names of input field and null checkbox
var input_name = $span.parent('td').children("input[type='text']").attr('name');
//Token
var token = $("input[name='token']").val();
openGISEditor(value, field, type, input_name, token);
});
}, 'top.frame_content'); // end $(document).ready()

View File

@ -0,0 +1,649 @@
<?php
function loadData($type, $data) {
if (!$data) return $data;
$tmp = unpack($type, $data);
return current($tmp);
}
function swap($binValue) {
$result = $binValue{strlen($binValue) - 1};
for($i = strlen($binValue) - 2; $i >= 0 ; $i--) {
$result .= $binValue{$i};
}
return $result;
}
function packDouble($value, $mode = 'LE') {
$value = (double)$value;
$bin = pack("d", $value);
//We test if the conversion of an integer (1) is done as LE or BE by default
switch (pack ('L', 1)) {
case pack ('V', 1): //Little Endian
$result = ($mode == 'LE') ? $bin : swap($bin);
break;
case pack ('N', 1): //Big Endian
$result = ($mode == 'BE') ? $bin : swap($bin);
break;
default: //Some other thing, we just return false
$result = FALSE;
}
return $result;
}
class ShapeFile {
var $FileName;
var $SHPFile;
var $SHXFile;
var $DBFFile;
var $DBFHeader;
var $lastError = "";
var $boundingBox = array("xmin" => 0.0, "ymin" => 0.0, "xmax" => 0.0, "ymax" => 0.0);
var $fileLength = 0;
var $shapeType = 0;
var $records;
function ShapeFile($shapeType, $boundingBox = array("xmin" => 0.0, "ymin" => 0.0, "xmax" => 0.0, "ymax" => 0.0), $FileName = NULL) {
$this->shapeType = $shapeType;
$this->boundingBox = $boundingBox;
$this->FileName = $FileName;
$this->fileLength = 50;
}
function loadFromFile($FileName) {
$this->FileName = $FileName;
if (($this->_openSHPFile()) && ($this->_openDBFFile())) {
$this->_loadHeaders();
$this->_loadRecords();
$this->_closeSHPFile();
$this->_closeDBFFile();
} else {
return false;
}
}
function saveToFile($FileName = NULL) {
if ($FileName != NULL) $this->FileName = $FileName;
if (($this->_openSHPFile(TRUE)) && ($this->_openSHXFile(TRUE)) && ($this->_openDBFFile(TRUE))) {
$this->_saveHeaders();
$this->_saveRecords();
$this->_closeSHPFile();
$this->_closeSHXFile();
$this->_closeDBFFile();
} else {
return false;
}
}
function addRecord($record) {
if ((isset($this->DBFHeader)) && (is_array($this->DBFHeader))) {
$record->updateDBFInfo($this->DBFHeader);
}
$this->fileLength += ($record->getContentLength() + 4);
$this->records[] = $record;
$this->records[count($this->records) - 1]->recordNumber = count($this->records);
return (count($this->records) - 1);
}
function deleteRecord($index) {
if (isset($this->records[$index])) {
$this->fileLength -= ($this->records[$index]->getContentLength() + 4);
for ($i = $index; $i < (count($this->records) - 1); $i++) {
$this->records[$i] = $this->records[$i + 1];
}
unset($this->records[count($this->records) - 1]);
$this->_deleteRecordFromDBF($index);
}
}
function getDBFHeader() {
return $this->DBFHeader;
}
function setDBFHeader($header) {
$this->DBFHeader = $header;
for ($i = 0; $i < count($this->records); $i++) {
$this->records[$i]->updateDBFInfo($header);
}
}
function getIndexFromDBFData($field, $value) {
$result = -1;
for ($i = 0; $i < (count($this->records) - 1); $i++) {
if (isset($this->records[$i]->DBFData[$field]) && (strtoupper($this->records[$i]->DBFData[$field]) == strtoupper($value))) {
$result = $i;
}
}
return $result;
}
function _loadDBFHeader() {
$DBFFile = fopen(str_replace('.*', '.dbf', $this->FileName), 'r');
$result = array();
$buff32 = array();
$i = 1;
$inHeader = true;
while ($inHeader) {
if (!feof($DBFFile)) {
$buff32 = fread($DBFFile, 32);
if ($i > 1) {
if (substr($buff32, 0, 1) == chr(13)) {
$inHeader = false;
} else {
$pos = strpos(substr($buff32, 0, 10), chr(0));
$pos = ($pos == 0 ? 10 : $pos);
$fieldName = substr($buff32, 0, $pos);
$fieldType = substr($buff32, 11, 1);
$fieldLen = ord(substr($buff32, 16, 1));
$fieldDec = ord(substr($buff32, 17, 1));
array_push($result, array($fieldName, $fieldType, $fieldLen, $fieldDec));
}
}
$i++;
} else {
$inHeader = false;
}
}
fclose($DBFFile);
return($result);
}
function _deleteRecordFromDBF($index) {
if (@dbase_delete_record($this->DBFFile, $index)) {
@dbase_pack($this->DBFFile);
}
}
function _loadHeaders() {
fseek($this->SHPFile, 24, SEEK_SET);
$this->fileLength = loadData("N", fread($this->SHPFile, 4));
fseek($this->SHPFile, 32, SEEK_SET);
$this->shapeType = loadData("V", fread($this->SHPFile, 4));
$this->boundingBox = array();
$this->boundingBox["xmin"] = loadData("d", fread($this->SHPFile, 8));
$this->boundingBox["ymin"] = loadData("d", fread($this->SHPFile, 8));
$this->boundingBox["xmax"] = loadData("d", fread($this->SHPFile, 8));
$this->boundingBox["ymax"] = loadData("d", fread($this->SHPFile, 8));
$this->DBFHeader = $this->_loadDBFHeader();
}
function _saveHeaders() {
fwrite($this->SHPFile, pack("NNNNNN", 9994, 0, 0, 0, 0, 0));
fwrite($this->SHPFile, pack("N", $this->fileLength));
fwrite($this->SHPFile, pack("V", 1000));
fwrite($this->SHPFile, pack("V", $this->shapeType));
fwrite($this->SHPFile, packDouble($this->boundingBox['xmin']));
fwrite($this->SHPFile, packDouble($this->boundingBox['ymin']));
fwrite($this->SHPFile, packDouble($this->boundingBox['xmax']));
fwrite($this->SHPFile, packDouble($this->boundingBox['ymax']));
fwrite($this->SHPFile, pack("dddd", 0, 0, 0, 0));
fwrite($this->SHXFile, pack("NNNNNN", 9994, 0, 0, 0, 0, 0));
fwrite($this->SHXFile, pack("N", 50 + 4*count($this->records)));
fwrite($this->SHXFile, pack("V", 1000));
fwrite($this->SHXFile, pack("V", $this->shapeType));
fwrite($this->SHXFile, packDouble($this->boundingBox['xmin']));
fwrite($this->SHXFile, packDouble($this->boundingBox['ymin']));
fwrite($this->SHXFile, packDouble($this->boundingBox['xmax']));
fwrite($this->SHXFile, packDouble($this->boundingBox['ymax']));
fwrite($this->SHXFile, pack("dddd", 0, 0, 0, 0));
}
function _loadRecords() {
fseek($this->SHPFile, 100);
while (!feof($this->SHPFile)) {
$bByte = ftell($this->SHPFile);
$record = new ShapeRecord(-1);
$record->loadFromFile($this->SHPFile, $this->DBFFile);
$eByte = ftell($this->SHPFile);
if (($eByte <= $bByte) || ($record->lastError != "")) {
return false;
}
$this->records[] = $record;
}
}
function _saveRecords() {
if (file_exists(str_replace('.*', '.dbf', $this->FileName))) {
@unlink(str_replace('.*', '.dbf', $this->FileName));
}
if (!($this->DBFFile = @dbase_create(str_replace('.*', '.dbf', $this->FileName), $this->DBFHeader))) {
return $this->setError(sprintf("It wasn't possible to create the DBase file '%s'", str_replace('.*', '.dbf', $this->FileName)));
}
$offset = 50;
if (is_array($this->records) && (count($this->records) > 0)) {
reset($this->records);
while (list($index, $record) = each($this->records)) {
//Save the record to the .shp file
$record->saveToFile($this->SHPFile, $this->DBFFile, $index + 1);
//Save the record to the .shx file
fwrite($this->SHXFile, pack("N", $offset));
fwrite($this->SHXFile, pack("N", $record->getContentLength()));
$offset += (4 + $record->getContentLength());
}
}
@dbase_pack($this->DBFFile);
}
function _openSHPFile($toWrite = false) {
$this->SHPFile = @fopen(str_replace('.*', '.shp', $this->FileName), ($toWrite ? "wb+" : "rb"));
if (!$this->SHPFile) {
return $this->setError(sprintf("It wasn't possible to open the Shape file '%s'", str_replace('.*', '.shp', $this->FileName)));
}
return TRUE;
}
function _closeSHPFile() {
if ($this->SHPFile) {
fclose($this->SHPFile);
$this->SHPFile = NULL;
}
}
function _openSHXFile($toWrite = false) {
$this->SHXFile = @fopen(str_replace('.*', '.shx', $this->FileName), ($toWrite ? "wb+" : "rb"));
if (!$this->SHXFile) {
return $this->setError(sprintf("It wasn't possible to open the Index file '%s'", str_replace('.*', '.shx', $this->FileName)));
}
return TRUE;
}
function _closeSHXFile() {
if ($this->SHXFile) {
fclose($this->SHXFile);
$this->SHXFile = NULL;
}
}
function _openDBFFile($toWrite = false) {
$checkFunction = $toWrite ? "is_writable" : "is_readable";
if (($toWrite) && (!file_exists(str_replace('.*', '.dbf', $this->FileName)))) {
if (!@dbase_create(str_replace('.*', '.dbf', $this->FileName), $this->DBFHeader)) {
return $this->setError(sprintf("It wasn't possible to create the DBase file '%s'", str_replace('.*', '.dbf', $this->FileName)));
}
}
if ($checkFunction(str_replace('.*', '.dbf', $this->FileName))) {
$this->DBFFile = dbase_open(str_replace('.*', '.dbf', $this->FileName), ($toWrite ? 2 : 0));
if (!$this->DBFFile) {
return $this->setError(sprintf("It wasn't possible to open the DBase file '%s'", str_replace('.*', '.dbf', $this->FileName)));
}
} else {
return $this->setError(sprintf("It wasn't possible to find the DBase file '%s'", str_replace('.*', '.dbf', $this->FileName)));
}
return TRUE;
}
function _closeDBFFile() {
if ($this->DBFFile) {
dbase_close($this->DBFFile);
$this->DBFFile = NULL;
}
}
function setError($error) {
$this->lastError = $error;
return false;
}
}
class ShapeRecord {
var $SHPFile = NULL;
var $DBFFile = NULL;
var $recordNumber = NULL;
var $shapeType = NULL;
var $lastError = "";
var $SHPData = array();
var $DBFData = array();
function ShapeRecord($shapeType) {
$this->shapeType = $shapeType;
}
function loadFromFile(&$SHPFile, &$DBFFile) {
$this->SHPFile = $SHPFile;
$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;
}
$this->_loadDBFData();
}
function saveToFile(&$SHPFile, &$DBFFile, $recordNumber) {
$this->SHPFile = $SHPFile;
$this->DBFFile = $DBFFile;
$this->recordNumber = $recordNumber;
$this->_saveHeaders();
switch ($this->shapeType) {
case 0:
$this->_saveNullRecord();
break;
case 1:
$this->_savePointRecord();
break;
case 3:
$this->_savePolyLineRecord();
break;
case 5:
$this->_savePolygonRecord();
break;
case 8:
$this->_saveMultiPointRecord();
break;
default:
$this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
break;
}
$this->_saveDBFData();
}
function updateDBFInfo($header) {
$tmp = $this->DBFData;
unset($this->DBFData);
$this->DBFData = array();
reset($header);
while (list($key, $value) = each($header)) {
$this->DBFData[$value[0]] = (isset($tmp[$value[0]])) ? $tmp[$value[0]] : "";
}
}
function _loadHeaders() {
$this->recordNumber = loadData("N", fread($this->SHPFile, 4));
$tmp = loadData("N", fread($this->SHPFile, 4)); //We read the length of the record
$this->shapeType = loadData("V", fread($this->SHPFile, 4));
}
function _saveHeaders() {
fwrite($this->SHPFile, pack("N", $this->recordNumber));
fwrite($this->SHPFile, pack("N", $this->getContentLength()));
fwrite($this->SHPFile, pack("V", $this->shapeType));
}
function _loadPoint() {
$data = array();
$data["x"] = loadData("d", fread($this->SHPFile, 8));
$data["y"] = loadData("d", fread($this->SHPFile, 8));
return $data;
}
function _savePoint($data) {
fwrite($this->SHPFile, packDouble($data["x"]));
fwrite($this->SHPFile, packDouble($data["y"]));
}
function _loadNullRecord() {
$this->SHPData = array();
}
function _saveNullRecord() {
//Don't save anything
}
function _loadPointRecord() {
$this->SHPData = $this->_loadPoint();
}
function _savePointRecord() {
$this->_savePoint($this->SHPData);
}
function _loadMultiPointRecord() {
$this->SHPData = array();
$this->SHPData["xmin"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["ymin"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["xmax"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["ymax"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["numpoints"] = loadData("V", fread($this->SHPFile, 4));
for ($i = 0; $i <= $this->SHPData["numpoints"]; $i++) {
$this->SHPData["points"][] = $this->_loadPoint();
}
}
function _saveMultiPointRecord() {
fwrite($this->SHPFile, pack("dddd", $this->SHPData["xmin"], $this->SHPData["ymin"], $this->SHPData["xmax"], $this->SHPData["ymax"]));
fwrite($this->SHPFile, pack("V", $this->SHPData["numpoints"]));
for ($i = 0; $i <= $this->SHPData["numpoints"]; $i++) {
$this->_savePoint($this->SHPData["points"][$i]);
}
}
function _loadPolyLineRecord() {
$this->SHPData = array();
$this->SHPData["xmin"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["ymin"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["xmax"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["ymax"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["numparts"] = loadData("V", fread($this->SHPFile, 4));
$this->SHPData["numpoints"] = loadData("V", fread($this->SHPFile, 4));
for ($i = 0; $i < $this->SHPData["numparts"]; $i++) {
$this->SHPData["parts"][$i] = loadData("V", fread($this->SHPFile, 4));
}
$firstIndex = ftell($this->SHPFile);
$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"])) && !feof($this->SHPFile)) {
$this->SHPData["parts"][$partIndex]["points"][] = $this->_loadPoint();
$readPoints++;
}
}
fseek($this->SHPFile, $firstIndex + ($readPoints*16));
}
function _savePolyLineRecord() {
fwrite($this->SHPFile, pack("dddd", $this->SHPData["xmin"], $this->SHPData["ymin"], $this->SHPData["xmax"], $this->SHPData["ymax"]));
fwrite($this->SHPFile, pack("VV", $this->SHPData["numparts"], $this->SHPData["numpoints"]));
for ($i = 0; $i < $this->SHPData["numparts"]; $i++) {
fwrite($this->SHPFile, pack("V", count($this->SHPData["parts"][$i])));
}
reset($this->SHPData["parts"]);
foreach ($this->SHPData["parts"] as $partData){
reset($partData["points"]);
while (list($pointIndex, $pointData) = each($partData["points"])) {
$this->_savePoint($pointData);
}
}
}
function _loadPolygonRecord() {
$this->_loadPolyLineRecord();
}
function _savePolygonRecord() {
$this->_savePolyLineRecord();
}
function addPoint($point, $partIndex = 0) {
switch ($this->shapeType) {
case 0:
//Don't add anything
break;
case 1:
//Substitutes the value of the current point
$this->SHPData = $point;
break;
case 3:
case 5:
//Adds a new point to the selected part
if (!isset($this->SHPData["xmin"]) || ($this->SHPData["xmin"] > $point["x"])) $this->SHPData["xmin"] = $point["x"];
if (!isset($this->SHPData["ymin"]) || ($this->SHPData["ymin"] > $point["y"])) $this->SHPData["ymin"] = $point["y"];
if (!isset($this->SHPData["xmax"]) || ($this->SHPData["xmax"] < $point["x"])) $this->SHPData["xmax"] = $point["x"];
if (!isset($this->SHPData["ymax"]) || ($this->SHPData["ymax"] < $point["y"])) $this->SHPData["ymax"] = $point["y"];
$this->SHPData["parts"][$partIndex]["points"][] = $point;
$this->SHPData["numparts"] = count($this->SHPData["parts"]);
$this->SHPData["numpoints"]++;
break;
case 8:
//Adds a new point
if (!isset($this->SHPData["xmin"]) || ($this->SHPData["xmin"] > $point["x"])) $this->SHPData["xmin"] = $point["x"];
if (!isset($this->SHPData["ymin"]) || ($this->SHPData["ymin"] > $point["y"])) $this->SHPData["ymin"] = $point["y"];
if (!isset($this->SHPData["xmax"]) || ($this->SHPData["xmax"] < $point["x"])) $this->SHPData["xmax"] = $point["x"];
if (!isset($this->SHPData["ymax"]) || ($this->SHPData["ymax"] < $point["y"])) $this->SHPData["ymax"] = $point["y"];
$this->SHPData["points"][] = $point;
$this->SHPData["numpoints"]++;
break;
default:
$this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
break;
}
}
function deletePoint($pointIndex = 0, $partIndex = 0) {
switch ($this->shapeType) {
case 0:
//Don't delete anything
break;
case 1:
//Sets the value of the point to zero
$this->SHPData["x"] = 0.0;
$this->SHPData["y"] = 0.0;
break;
case 3:
case 5:
//Deletes the point from the selected part, if exists
if (isset($this->SHPData["parts"][$partIndex]) && isset($this->SHPData["parts"][$partIndex]["points"][$pointIndex])) {
for ($i = $pointIndex; $i < (count($this->SHPData["parts"][$partIndex]["points"]) - 1); $i++) {
$this->SHPData["parts"][$partIndex]["points"][$i] = $this->SHPData["parts"][$partIndex]["points"][$i + 1];
}
unset($this->SHPData["parts"][$partIndex]["points"][count($this->SHPData["parts"][$partIndex]["points"]) - 1]);
$this->SHPData["numparts"] = count($this->SHPData["parts"]);
$this->SHPData["numpoints"]--;
}
break;
case 8:
//Deletes the point, if exists
if (isset($this->SHPData["points"][$pointIndex])) {
for ($i = $pointIndex; $i < (count($this->SHPData["points"]) - 1); $i++) {
$this->SHPData["points"][$i] = $this->SHPData["points"][$i + 1];
}
unset($this->SHPData["points"][count($this->SHPData["points"]) - 1]);
$this->SHPData["numpoints"]--;
}
break;
default:
$this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
break;
}
}
function getContentLength() {
switch ($this->shapeType) {
case 0:
$result = 0;
break;
case 1:
$result = 10;
break;
case 3:
case 5:
$result = 22 + 2*count($this->SHPData["parts"]);
for ($i = 0; $i < count($this->SHPData["parts"]); $i++) {
$result += 8*count($this->SHPData["parts"][$i]["points"]);
}
break;
case 8:
$result = 20 + 8*count($this->SHPData["points"]);
break;
default:
$result = false;
$this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
break;
}
return $result;
}
function _loadDBFData() {
$this->DBFData = @dbase_get_record_with_names($this->DBFFile, $this->recordNumber);
unset($this->DBFData["deleted"]);
}
function _saveDBFData() {
unset($this->DBFData["deleted"]);
if ($this->recordNumber <= dbase_numrecords($this->DBFFile)) {
if (!dbase_replace_record($this->DBFFile, array_values($this->DBFData), $this->recordNumber)) {
$this->setError("I wasn't possible to update the information in the DBF file.");
}
} else {
if (!dbase_add_record($this->DBFFile, array_values($this->DBFData))) {
$this->setError("I wasn't possible to add the information to the DBF file.");
}
}
}
function setError($error) {
$this->lastError = $error;
return false;
}
}
?>

View File

@ -2073,6 +2073,13 @@ function PMA_getUniqueCondition($handle, $fields_cnt, $fields_meta, $row, $force
// this blob won't be part of the final condition
$con_val = null;
}
} elseif (in_array($meta->type, PMA_getGISDatatypes()) && ! empty($row[$i])) {
// do not build a too big condition
if (strlen($row[$i]) < 5000) {
$condition .= '=0x' . bin2hex($row[$i]) . ' AND';
} else {
$condition = '';
}
} elseif ($meta->type == 'bit') {
$con_val = "= b'" . PMA_printable_bit_value($row[$i], $meta->length) . "'";
} else {
@ -2854,6 +2861,31 @@ function PMA_replace_binary_contents($content)
return $result;
}
/**
* Converts GIS data to Well Known Text format
*
* @param $data GIS data
* @param $includeSRID Add SRID to the WKT
* @return GIS data in Well Know Text format
*/
function PMA_asWKT($data, $includeSRID = false) {
// Convert to WKT format
$hex = bin2hex($data);
$wktsql = "SELECT ASTEXT(x'" . $hex . "')";
if ($includeSRID) {
$wktsql .= ", SRID(x'" . $hex . "')";
}
$wktresult = PMA_DBI_try_query($wktsql, null, PMA_DBI_QUERY_STORE);
$wktarr = PMA_DBI_fetch_row($wktresult, 0);
$wktval = $wktarr[0];
if ($includeSRID) {
$srid = $wktarr[1];
$wktval = "'" . $wktval . "'," . $srid;
}
@PMA_DBI_free_result($wktresult);
return $wktval;
}
/**
* If the string starts with a \r\n pair (0x0d0a) add an extra \n
*
@ -3166,22 +3198,157 @@ function PMA_getSupportedDatatypes($html = false, $selected = '')
* @return array list of datatypes
*/
function PMA_unsupportedDatatypes()
{
// These GIS data types are not yet supported.
$no_support_types = array('geometry',
'point',
'linestring',
'polygon',
'multipoint',
'multilinestring',
'multipolygon',
'geometrycollection'
);
function PMA_unsupportedDatatypes() {
$no_support_types = array();
return $no_support_types;
}
function PMA_getGISDatatypes($upper_case = false) {
$gis_data_types = array('geometry',
'point',
'linestring',
'polygon',
'multipoint',
'multilinestring',
'multipolygon',
'geometrycollection'
);
if ($upper_case) {
for ($i = 0; $i < count($gis_data_types); $i++) {
$gis_data_types[$i] = strtoupper($gis_data_types[$i]);
}
}
return $gis_data_types;
}
/**
* Generates GIS data based on the string passed.
*
* @param string $gis_string GIS string
*/
function PMA_createGISData($gis_string) {
$gis_string = trim($gis_string);
$geom_types = '(POINT|MULTIPOINT|LINESTRING|MULTILINESTRING|POLYGON|MULTIPOLYGON|GEOMETRYCOLLECTION)';
if (preg_match("/^'" . $geom_types . "\(.*\)',[0-9]*$/i", $gis_string)) {
return 'GeomFromText(' . $gis_string . ')';
} elseif (preg_match("/^" . $geom_types . "\(.*\)$/i", $gis_string)) {
return "GeomFromText('" . $gis_string . "')";
} else {
return $gis_string;
}
}
/**
* Returns the names and details of the functions
* that can be applied on geometry data typess.
*
* @param string $geom_type if provided the output is limited to the functions
* that are applicable to the provided geometry type.
* @param bool $binary if set to false functions that take two geometries
* as arguments will not be included.
* @param bool $display if set to true seperators will be added to the
* output array.
*
* @return array names and details of the functions that can be applied on
* geometry data typess.
*/
function PMA_getGISFunctions($geom_type = null, $binary = true, $display = false) {
$funcs = array();
if ($display) {
$funcs[] = array('display' => ' ');
}
// Unary functions common to all geomety types
$funcs['Dimension'] = array('params' => 1, 'type' => 'int');
$funcs['Envelope'] = array('params' => 1, 'type' => 'Polygon');
$funcs['GeometryType'] = array('params' => 1, 'type' => 'text');
$funcs['SRID'] = array('params' => 1, 'type' => 'int');
$funcs['IsEmpty'] = array('params' => 1, 'type' => 'int');
$funcs['IsSimple'] = array('params' => 1, 'type' => 'int');
$geom_type = trim(strtolower($geom_type));
if ($display && $geom_type != 'geometry' && $geom_type != 'multipoint') {
$funcs[] = array('display' => '--------');
}
// Unary functions that are specific to each geomety type
if ($geom_type == 'point') {
$funcs['X'] = array('params' => 1, 'type' => 'float');
$funcs['Y'] = array('params' => 1, 'type' => 'float');
} elseif ($geom_type == 'multipoint') {
// no fucntions here
} elseif ($geom_type == 'linestring') {
$funcs['EndPoint'] = array('params' => 1, 'type' => 'point');
$funcs['GLength'] = array('params' => 1, 'type' => 'float');
$funcs['NumPoints'] = array('params' => 1, 'type' => 'int');
$funcs['StartPoint'] = array('params' => 1, 'type' => 'point');
$funcs['IsRing'] = array('params' => 1, 'type' => 'int');
} elseif ($geom_type == 'multilinestring') {
$funcs['GLength'] = array('params' => 1, 'type' => 'float');
$funcs['IsClosed'] = array('params' => 1, 'type' => 'int');
} elseif ($geom_type == 'polygon') {
$funcs['Area'] = array('params' => 1, 'type' => 'float');
$funcs['ExteriorRing'] = array('params' => 1, 'type' => 'linestring');
$funcs['NumInteriorRings'] = array('params' => 1, 'type' => 'int');
} elseif ($geom_type == 'multipolygon') {
$funcs['Area'] = array('params' => 1, 'type' => 'float');
$funcs['Centroid'] = array('params' => 1, 'type' => 'point');
// Not yet implemented in MySQL
//$funcs['PointOnSurface'] = array('params' => 1, 'type' => 'point');
} elseif ($geom_type == 'geometrycollection') {
$funcs['NumGeometries'] = array('params' => 1, 'type' => 'int');
}
// If we are asked for binary functions as well
if ($binary) {
// section seperator
if ($display) {
$funcs[] = array('display' => '--------');
}
if (PMA_MYSQL_INT_VERSION < 50601) {
$funcs['Crosses'] = array('params' => 2, 'type' => 'int');
$funcs['Contains'] = array('params' => 2, 'type' => 'int');
$funcs['Disjoint'] = array('params' => 2, 'type' => 'int');
$funcs['Equals'] = array('params' => 2, 'type' => 'int');
$funcs['Intersects'] = array('params' => 2, 'type' => 'int');
$funcs['Overlaps'] = array('params' => 2, 'type' => 'int');
$funcs['Touches'] = array('params' => 2, 'type' => 'int');
$funcs['Within'] = array('params' => 2, 'type' => 'int');
} else {
// If MySQl version is greaeter than or equal 5.6.1, use the ST_ prefix.
$funcs['ST_Crosses'] = array('params' => 2, 'type' => 'int');
$funcs['ST_Contains'] = array('params' => 2, 'type' => 'int');
$funcs['ST_Disjoint'] = array('params' => 2, 'type' => 'int');
$funcs['ST_Equals'] = array('params' => 2, 'type' => 'int');
$funcs['ST_Intersects'] = array('params' => 2, 'type' => 'int');
$funcs['ST_Overlaps'] = array('params' => 2, 'type' => 'int');
$funcs['ST_Touches'] = array('params' => 2, 'type' => 'int');
$funcs['ST_Within'] = array('params' => 2, 'type' => 'int');
}
if ($display) {
$funcs[] = array('display' => '--------');
}
// Minimum bounding rectangle functions
$funcs['MBRContains'] = array('params' => 2, 'type' => 'int');
$funcs['MBRDisjoint'] = array('params' => 2, 'type' => 'int');
$funcs['MBREquals'] = array('params' => 2, 'type' => 'int');
$funcs['MBRIntersects'] = array('params' => 2, 'type' => 'int');
$funcs['MBROverlaps'] = array('params' => 2, 'type' => 'int');
$funcs['MBRTouches'] = array('params' => 2, 'type' => 'int');
$funcs['MBRWithin'] = array('params' => 2, 'type' => 'int');
}
return $funcs;
}
/**
* Creates a dropdown box with MySQL functions for a particular column.
*

View File

@ -2806,6 +2806,7 @@ if ($cfg['ShowFunctionFields']) {
'FUNC_CHAR' => '',
'FUNC_DATE' => '',
'FUNC_NUMBER' => '',
'FUNC_SPATIAL' => 'GeomFromText',
'first_timestamp' => 'NOW',
'pk_char36' => 'UUID',
);

View File

@ -1555,65 +1555,67 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql)
// Remove 'grid_edit' from $class as we do not allow to inline-edit geometry data.
$class = str_replace('grid_edit', '', $class);
// Display as [GEOMETRY - (size)]
if ('GEOM' == $_SESSION['tmp_user_values']['geometry_display']) {
$geometry_text = PMA_handle_non_printable_contents(
'GEOMETRY', (isset($row[$i]) ? $row[$i] : ''), $transform_function,
$transform_options, $default_function, $meta
);
$vertical_display['data'][$row_no][$i] = PMA_buildValueDisplay(
$class, $condition_field, $geometry_text
);
if (! isset($row[$i]) || is_null($row[$i])) {
$vertical_display['data'][$row_no][$i] = PMA_buildNullDisplay($class, $condition_field);
} elseif ($row[$i] != '') {
// Display as [GEOMETRY - (size)]
if ('GEOM' == $_SESSION['tmp_user_values']['geometry_display']) {
$geometry_text = PMA_handle_non_printable_contents(
'GEOMETRY', (isset($row[$i]) ? $row[$i] : ''), $transform_function,
$transform_options, $default_function, $meta
);
$vertical_display['data'][$row_no][$i] = PMA_buildValueDisplay(
$class, $condition_field, $geometry_text
);
// Display in Well Known Text(WKT) format.
} elseif ('WKT' == $_SESSION['tmp_user_values']['geometry_display']) {
// Convert to WKT format
$wktsql = "SELECT ASTEXT (GeomFromWKB(x'" . PMA_substr(bin2hex($row[$i]), 8) . "'))";
$wktresult = PMA_DBI_try_query($wktsql, null, PMA_DBI_QUERY_STORE);
$wktarr = PMA_DBI_fetch_row($wktresult, 0);
$wktval = $wktarr[0];
@PMA_DBI_free_result($wktresult);
// Display in Well Known Text(WKT) format.
} elseif ('WKT' == $_SESSION['tmp_user_values']['geometry_display']) {
// Convert to WKT format
$wktval = PMA_asWKT($row[$i]);
if (PMA_strlen($wktval) > $GLOBALS['cfg']['LimitChars']
&& $_SESSION['tmp_user_values']['display_text'] == 'P'
) {
$wktval = PMA_substr($wktval, 0, $GLOBALS['cfg']['LimitChars']) . '...';
$is_field_truncated = true;
}
$vertical_display['data'][$row_no][$i] = '<td ' . PMA_prepare_row_data(
$class, $condition_field, $analyzed_sql, $meta, $map, $wktval, $transform_function,
$default_function, $nowrap, $where_comparison, $transform_options, $is_field_truncated
);
// Display in Well Known Binary(WKB) format.
} else {
if ($_SESSION['tmp_user_values']['display_binary']) {
if ($_SESSION['tmp_user_values']['display_binary_as_hex']
&& PMA_contains_nonprintable_ascii($row[$i])
) {
$wkbval = PMA_substr(bin2hex($row[$i]), 8);
} else {
$wkbval = htmlspecialchars(PMA_replace_binary_contents($row[$i]));
}
if (PMA_strlen($wkbval) > $GLOBALS['cfg']['LimitChars']
if (PMA_strlen($wktval) > $GLOBALS['cfg']['LimitChars']
&& $_SESSION['tmp_user_values']['display_text'] == 'P'
) {
$wkbval = PMA_substr($wkbval, 0, $GLOBALS['cfg']['LimitChars']) . '...';
$wktval = PMA_substr($wktval, 0, $GLOBALS['cfg']['LimitChars']) . '...';
$is_field_truncated = true;
}
$vertical_display['data'][$row_no][$i] = '<td ' . PMA_prepare_row_data(
$class, $condition_field, $analyzed_sql, $meta, $map, $wkbval, $transform_function,
$class, $condition_field, $analyzed_sql, $meta, $map, $wktval, $transform_function,
$default_function, $nowrap, $where_comparison, $transform_options, $is_field_truncated
);
// Display in Well Known Binary(WKB) format.
} else {
$wkbval = PMA_handle_non_printable_contents(
'BINARY', $row[$i], $transform_function, $transform_options, $default_function, $meta, $_url_params
);
$vertical_display['data'][$row_no][$i] = PMA_buildValueDisplay($class, $condition_field, $wkbval);
if ($_SESSION['tmp_user_values']['display_binary']) {
if ($_SESSION['tmp_user_values']['display_binary_as_hex']
&& PMA_contains_nonprintable_ascii($row[$i])
) {
$wkbval = PMA_substr(bin2hex($row[$i]), 8);
} else {
$wkbval = htmlspecialchars(PMA_replace_binary_contents($row[$i]));
}
if (PMA_strlen($wkbval) > $GLOBALS['cfg']['LimitChars']
&& $_SESSION['tmp_user_values']['display_text'] == 'P'
) {
$wkbval = PMA_substr($wkbval, 0, $GLOBALS['cfg']['LimitChars']) . '...';
$is_field_truncated = true;
}
$vertical_display['data'][$row_no][$i] = '<td ' . PMA_prepare_row_data(
$class, $condition_field, $analyzed_sql, $meta, $map, $wkbval, $transform_function,
$default_function, $nowrap, $where_comparison, $transform_options, $is_field_truncated
);
} else {
$wkbval = PMA_handle_non_printable_contents(
'BINARY', $row[$i], $transform_function, $transform_options, $default_function, $meta, $_url_params
);
$vertical_display['data'][$row_no][$i] = PMA_buildValueDisplay($class, $condition_field, $wkbval);
}
}
} else {
$vertical_display['data'][$row_no][$i] = PMA_buildEmptyDisplay($class, $condition_field, $meta);
}
// n o t n u m e r i c a n d n o t B L O B

View File

@ -20,6 +20,9 @@ class PMA_GIS_Factory
include_once './libraries/gis/pma_gis_geometry.php';
$type_lower = strtolower($type);
if (! file_exists('./libraries/gis/pma_gis_' . $type_lower . '.php')) {
return false;
}
if (include_once './libraries/gis/pma_gis_' . $type_lower . '.php') {
switch($type) {
case 'MULTIPOLYGON' :
@ -37,10 +40,10 @@ class PMA_GIS_Factory
case 'GEOMETRYCOLLECTION' :
return PMA_GIS_Geometrycollection::singleton();
default :
throw new Exception('Unknown GIS data type');
return false;
}
} else {
throw new Exception('File not found');
return false;
}
}
}

View File

@ -67,6 +67,17 @@ abstract class PMA_GIS_Geometry
*/
public abstract function scaleRow($spatial);
/**
* Generate the WKT with the set of parameters passed by the GIS editor.
*
* @param array $gis_data GIS data
* @param int $index Index into the parameter object
* @param string $empty Value for empty points
*
* @return WKT with the set of parameters passed by the GIS editor
*/
public abstract function generateWkt($gis_data, $index, $empty);
/**
* Returns OpenLayers.Bounds object that correspond to the bounds of GIS data.
*
@ -121,6 +132,30 @@ abstract class PMA_GIS_Geometry
return $min_max;
}
/**
* Generate parameters for the GIS data editor from the value of the GIS column.
* This method performs common work.
* More specific work is performed by each of the geom classes.
*
* @param $gis_string $value of the GIS column
*
* @return array parameters for the GIS editor from the value of the GIS column
*/
protected function generateParams($value)
{
$geom_types = '(POINT|MULTIPOINT|LINESTRING|MULTILINESTRING|POLYGON|MULTIPOLYGON|GEOMETRYCOLLECTION)';
$srid = 0;
$wkt = '';
if (preg_match("/^'" . $geom_types . "\(.*\)',[0-9]*$/i", $value)) {
$last_comma = strripos($value, ",");
$srid = trim(substr($value, $last_comma + 1));
$wkt = trim(substr($value, 1, $last_comma - 2));
} elseif (preg_match("/^" . $geom_types . "\(.*\)$/i", $value)) {
$wkt = $value;
}
return array('srid' => $srid, 'wkt' => $wkt);
}
/**
* Extracts points, scales and returns them as an array.
*
@ -141,14 +176,22 @@ abstract class PMA_GIS_Geometry
// Extract cordinates of the point
$cordinates = explode(" ", $point);
if ($scale_data != null) {
$x = ($cordinates[0] - $scale_data['x']) * $scale_data['scale'];
$y = $scale_data['height'] - ($cordinates[1] - $scale_data['y']) * $scale_data['scale'];
if (isset($cordinates[0]) && trim($cordinates[0]) != ''
&& isset($cordinates[1]) && trim($cordinates[1]) != ''
) {
if ($scale_data != null) {
$x = ($cordinates[0] - $scale_data['x']) * $scale_data['scale'];
$y = $scale_data['height'] - ($cordinates[1] - $scale_data['y']) * $scale_data['scale'];
} else {
$x = trim($cordinates[0]);
$y = trim($cordinates[1]);
}
} else {
$x = $cordinates[0];
$y = $cordinates[1];
$x = '';
$y = '';
}
if (! $linear) {
$points_arr[] = array($x, $y);
} else {

View File

@ -53,6 +53,9 @@ class PMA_GIS_Geometrycollection extends PMA_GIS_Geometry
$type = substr($sub_part, 0, $type_pos);
$gis_obj = PMA_GIS_Factory::factory($type);
if (! $gis_obj) {
continue;
}
$scale_data = $gis_obj->scaleRow($sub_part);
// Upadate minimum/maximum values for x and y cordinates.
@ -102,6 +105,9 @@ class PMA_GIS_Geometrycollection extends PMA_GIS_Geometry
$type = substr($sub_part, 0, $type_pos);
$gis_obj = PMA_GIS_Factory::factory($type);
if (! $gis_obj) {
continue;
}
$image = $gis_obj->prepareRowAsPng($sub_part, $label, $color, $scale_data, $image);
}
return $image;
@ -130,6 +136,9 @@ class PMA_GIS_Geometrycollection extends PMA_GIS_Geometry
$type = substr($sub_part, 0, $type_pos);
$gis_obj = PMA_GIS_Factory::factory($type);
if (! $gis_obj) {
continue;
}
$pdf = $gis_obj->prepareRowAsPdf($sub_part, $label, $color, $scale_data, $pdf);
}
return $pdf;
@ -159,6 +168,9 @@ class PMA_GIS_Geometrycollection extends PMA_GIS_Geometry
$type = substr($sub_part, 0, $type_pos);
$gis_obj = PMA_GIS_Factory::factory($type);
if (! $gis_obj) {
continue;
}
$row .= $gis_obj->prepareRowAsSvg($sub_part, $label, $color, $scale_data);
}
return $row;
@ -190,6 +202,9 @@ class PMA_GIS_Geometrycollection extends PMA_GIS_Geometry
$type = substr($sub_part, 0, $type_pos);
$gis_obj = PMA_GIS_Factory::factory($type);
if (! $gis_obj) {
continue;
}
$row .= $gis_obj->prepareRowAsOl($sub_part, $srid, $label, $color, $scale_data);
}
return $row;
@ -222,5 +237,71 @@ class PMA_GIS_Geometrycollection extends PMA_GIS_Geometry
}
return $sub_parts;
}
/**
* Generate the WKT with the set of parameters passed by the GIS editor.
*
* @param array $gis_data GIS data
* @param int $index Index into the parameter object
* @param string $empty Value for empty points
*
* @return WKT with the set of parameters passed by the GIS editor
*/
public function generateWkt($gis_data, $index, $empty = '')
{
$geom_count = (isset($gis_data['GEOMETRYCOLLECTION']['geom_count']))
? $gis_data['GEOMETRYCOLLECTION']['geom_count'] : 1;
$wkt = 'GEOMETRYCOLLECTION(';
for ($i = 0; $i < $geom_count; $i++) {
if (isset($gis_data[$i]['gis_type'])) {
$type = $gis_data[$i]['gis_type'];
$gis_obj = PMA_GIS_Factory::factory($type);
if (! $gis_obj) {
continue;
}
$wkt .= $gis_obj->generateWkt($gis_data, $i, $empty) . ',';
}
}
if (isset($gis_data[0]['gis_type'])) {
$wkt = substr($wkt, 0, strlen($wkt) - 1);
}
$wkt .= ')';
return $wkt;
}
/** Generate parameters for the GIS data editor from the value of the GIS column.
*
* @param string $value of the GIS column
* @param index $index of the geometry
*
* @return parameters for the GIS data editor from the value of the GIS column
*/
public function generateParams($value)
{
$params = array();
$data = PMA_GIS_Geometry::generateParams($value);
$params['srid'] = $data['srid'];
$wkt = $data['wkt'];
// Trim to remove leading 'GEOMETRYCOLLECTION(' and trailing ')'
$goem_col = substr($wkt, 19, (strlen($wkt) - 20));
// Split the geometry collection object to get its constituents.
$sub_parts = $this->_explodeGeomCol($goem_col);
$params['GEOMETRYCOLLECTION']['geom_count'] = count($sub_parts);
$i = 0;
foreach ($sub_parts as $sub_part) {
$type_pos = stripos($sub_part, '(');
$type = substr($sub_part, 0, $type_pos);
$gis_obj = PMA_GIS_Factory::factory($type);
if (! $gis_obj) {
continue;
}
$params = array_merge($params, $gis_obj->generateParams($sub_part, $i));
$i++;
}
return $params;
}
}
?>

View File

@ -59,6 +59,7 @@ class PMA_GIS_Linestring extends PMA_GIS_Geometry
public function prepareRowAsPng($spatial, $label, $line_color, $scale_data, $image)
{
// allocate colors
$black = imagecolorallocate($image, 0, 0, 0);
$red = hexdec(substr($line_color, 1, 2));
$green = hexdec(substr($line_color, 3, 2));
$blue = hexdec(substr($line_color, 4, 2));
@ -77,6 +78,10 @@ class PMA_GIS_Linestring extends PMA_GIS_Geometry
$temp_point = $point;
}
}
// print label if applicable
if (isset($label) && trim($label) != '') {
imagestring($image, 1, $points_arr[1][0], $points_arr[1][1], trim($label), $black);
}
return $image;
}
@ -112,6 +117,12 @@ class PMA_GIS_Linestring extends PMA_GIS_Geometry
$temp_point = $point;
}
}
// print label
if (isset($label) && trim($label) != '') {
$pdf->SetXY($points_arr[1][0], $points_arr[1][1]);
$pdf->SetFontSize(5);
$pdf->Cell(0, 0, trim($label));
}
return $pdf;
}
@ -196,5 +207,70 @@ class PMA_GIS_Linestring extends PMA_GIS_Geometry
. json_encode($style_options) . '));';
return $result;
}
/**
* Generate the WKT with the set of parameters passed by the GIS editor.
*
* @param array $gis_data GIS data
* @param int $index Index into the parameter object
* @param string $empty Value for empty points
*
* @return WKT with the set of parameters passed by the GIS editor
*/
public function generateWkt($gis_data, $index, $empty = '')
{
$no_of_points = isset($gis_data[$index]['LINESTRING']['no_of_points'])
? $gis_data[$index]['LINESTRING']['no_of_points'] : 2;
if ($no_of_points < 2) {
$no_of_points = 2;
}
$wkt = 'LINESTRING(';
for ($i = 0; $i < $no_of_points; $i++) {
$wkt .= ((isset($gis_data[$index]['LINESTRING'][$i]['x'])
&& trim($gis_data[$index]['LINESTRING'][$i]['x']) != '')
? $gis_data[$index]['LINESTRING'][$i]['x'] : $empty)
. ' ' . ((isset($gis_data[$index]['LINESTRING'][$i]['y'])
&& trim($gis_data[$index]['LINESTRING'][$i]['y']) != '')
? $gis_data[$index]['LINESTRING'][$i]['y'] : $empty) .',';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= ')';
return $wkt;
}
/**
* Generate parameters for the GIS data editor from the value of the GIS column.
*
* @param string $value of the GIS column
* @param index $index of the geometry
*
* @return parameters for the GIS data editor from the value of the GIS column
*/
public function generateParams($value, $index = -1)
{
if ($index == -1) {
$index = 0;
$params = array();
$data = PMA_GIS_Geometry::generateParams($value);
$params['srid'] = $data['srid'];
$wkt = $data['wkt'];
} else {
$params[$index]['gis_type'] = 'LINESTRING';
$wkt = $value;
}
// Trim to remove leading 'LINESTRING(' and trailing ')'
$linestring = substr($wkt, 11, (strlen($wkt) - 12));
$points_arr = $this->extractPoints($linestring, null);
$no_of_points = count($points_arr);
$params[$index]['LINESTRING']['no_of_points'] = $no_of_points;
for ($i = 0; $i < $no_of_points; $i++) {
$params[$index]['LINESTRING'][$i]['x'] = $points_arr[$i][0];
$params[$index]['LINESTRING'][$i]['y'] = $points_arr[$i][1];
}
return $params;
}
}
?>

View File

@ -68,6 +68,7 @@ class PMA_GIS_Multilinestring extends PMA_GIS_Geometry
public function prepareRowAsPng($spatial, $label, $line_color, $scale_data, $image)
{
// allocate colors
$black = imagecolorallocate($image, 0, 0, 0);
$red = hexdec(substr($line_color, 1, 2));
$green = hexdec(substr($line_color, 3, 2));
$blue = hexdec(substr($line_color, 4, 2));
@ -78,6 +79,7 @@ class PMA_GIS_Multilinestring extends PMA_GIS_Geometry
// Seperate each linestring
$linestirngs = explode("),(", $multilinestirng);
$first_line = true;
foreach ($linestirngs as $linestring) {
$points_arr = $this->extractPoints($linestring, $scale_data);
foreach ($points_arr as $point) {
@ -90,6 +92,11 @@ class PMA_GIS_Multilinestring extends PMA_GIS_Geometry
}
}
unset($temp_point);
// print label if applicable
if (isset($label) && trim($label) != '' && $first_line) {
imagestring($image, 1, $points_arr[1][0], $points_arr[1][1], trim($label), $black);
}
$first_line = false;
}
return $image;
}
@ -118,6 +125,7 @@ class PMA_GIS_Multilinestring extends PMA_GIS_Geometry
// Seperate each linestring
$linestirngs = explode("),(", $multilinestirng);
$first_line = true;
foreach ($linestirngs as $linestring) {
$points_arr = $this->extractPoints($linestring, $scale_data);
foreach ($points_arr as $point) {
@ -130,6 +138,13 @@ class PMA_GIS_Multilinestring extends PMA_GIS_Geometry
}
}
unset($temp_point);
// print label
if (isset($label) && trim($label) != '' && $first_line) {
$pdf->SetXY($points_arr[1][0], $points_arr[1][1]);
$pdf->SetFontSize(5);
$pdf->Cell(0, 0, trim($label));
}
$first_line = false;
}
return $pdf;
}
@ -225,5 +240,109 @@ class PMA_GIS_Multilinestring extends PMA_GIS_Geometry
$row .= ')), null, ' . json_encode($style_options) . '));';
return $row;
}
/**
* Generate the WKT with the set of parameters passed by the GIS editor.
*
* @param array $gis_data GIS data
* @param int $index Index into the parameter object
* @param string $empty Value for empty points
*
* @return WKT with the set of parameters passed by the GIS editor
*/
public function generateWkt($gis_data, $index, $empty = '')
{
$no_of_lines = isset($gis_data[$index]['MULTILINESTRING']['no_of_lines'])
? $gis_data[$index]['MULTILINESTRING']['no_of_lines'] : 1;
if ($no_of_lines < 1) {
$no_of_lines = 1;
}
$wkt = 'MULTILINESTRING(';
for ($i = 0; $i < $no_of_lines; $i++) {
$no_of_points = isset($gis_data[$index]['MULTILINESTRING'][$i]['no_of_points'])
? $gis_data[$index]['MULTILINESTRING'][$i]['no_of_points'] : 2;
if ($no_of_points < 2) {
$no_of_points = 2;
}
$wkt .= '(';
for ($j = 0; $j < $no_of_points; $j++) {
$wkt .= ((isset($gis_data[$index]['MULTILINESTRING'][$i][$j]['x'])
&& trim($gis_data[$index]['MULTILINESTRING'][$i][$j]['x']) != '')
? $gis_data[$index]['MULTILINESTRING'][$i][$j]['x'] : $empty)
. ' ' . ((isset($gis_data[$index]['MULTILINESTRING'][$i][$j]['y'])
&& trim($gis_data[$index]['MULTILINESTRING'][$i][$j]['y']) != '')
? $gis_data[$index]['MULTILINESTRING'][$i][$j]['y'] : $empty) . ',';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= '),';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= ')';
return $wkt;
}
/**
* Generate the WKT for the data from ESRI shape files.
*
* @param array $row_data GIS data
*
* @return the WKT for the data from ESRI shape files
*/
public function getShape($row_data)
{
$wkt = 'MULTILINESTRING(';
for ($i = 0; $i < $row_data['numparts']; $i++) {
$wkt .= '(';
foreach ($row_data['parts'][$i]['points'] as $point) {
$wkt .= $point['x'] . ' ' . $point['y'] . ',';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= '),';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= ')';
return $wkt;
}
/**
* Generate parameters for the GIS data editor from the value of the GIS column.
*
* @param string $value of the GIS column
* @param index $index of the geometry
*
* @return parameters for the GIS data editor from the value of the GIS column
*/
public function generateParams($value, $index = -1)
{
if ($index == -1) {
$index = 0;
$params = array();
$data = PMA_GIS_Geometry::generateParams($value);
$params['srid'] = $data['srid'];
$wkt = $data['wkt'];
} else {
$params[$index]['gis_type'] = 'MULTILINESTRING';
$wkt = $value;
}
// Trim to remove leading 'MULTILINESTRING((' and trailing '))'
$multilinestirng = substr($wkt, 17, (strlen($wkt) - 19));
// Seperate each linestring
$linestirngs = explode("),(", $multilinestirng);
$params[$index]['MULTILINESTRING']['no_of_lines'] = count($linestirngs);
$j = 0;
foreach ($linestirngs as $linestring) {
$points_arr = $this->extractPoints($linestring, null);
$no_of_points = count($points_arr);
$params[$index]['MULTILINESTRING'][$j]['no_of_points'] = $no_of_points;
for ($i = 0; $i < $no_of_points; $i++) {
$params[$index]['MULTILINESTRING'][$j][$i]['x'] = $points_arr[$i][0];
$params[$index]['MULTILINESTRING'][$j][$i]['y'] = $points_arr[$i][1];
}
$j++;
}
return $params;
}
}
?>

View File

@ -59,6 +59,7 @@ class PMA_GIS_Multipoint extends PMA_GIS_Geometry
public function prepareRowAsPng($spatial, $label, $point_color, $scale_data, $image)
{
// allocate colors
$black = imagecolorallocate($image, 0, 0, 0);
$red = hexdec(substr($point_color, 1, 2));
$green = hexdec(substr($point_color, 3, 2));
$blue = hexdec(substr($point_color, 4, 2));
@ -70,7 +71,15 @@ class PMA_GIS_Multipoint extends PMA_GIS_Geometry
foreach ($points_arr as $point) {
// draw a small circle to mark the point
imagearc($image, $point[0], $point[1], 7, 7, 0, 360, $color);
if ($point[0] != '' && $point[1] != '') {
imagearc($image, $point[0], $point[1], 7, 7, 0, 360, $color);
}
}
// print label for each point
if ((isset($label) && trim($label) != '')
&& ($points_arr[0][0] != '' && $points_arr[0][1] != '')
) {
imagestring($image, 1, $points_arr[0][0], $points_arr[0][1], trim($label), $black);
}
return $image;
}
@ -100,7 +109,17 @@ class PMA_GIS_Multipoint extends PMA_GIS_Geometry
foreach ($points_arr as $point) {
// draw a small circle to mark the point
$pdf->Circle($point[0], $point[1], 2, 0, 360, 'D', $line);
if ($point[0] != '' && $point[1] != '') {
$pdf->Circle($point[0], $point[1], 2, 0, 360, 'D', $line);
}
}
// print label for each point
if ((isset($label) && trim($label) != '')
&& ($points_arr[0][0] != '' && $points_arr[0][1] != '')
) {
$pdf->SetXY($points_arr[0][0], $points_arr[0][1]);
$pdf->SetFontSize(5);
$pdf->Cell(0, 0, trim($label));
}
return $pdf;
}
@ -131,12 +150,14 @@ class PMA_GIS_Multipoint extends PMA_GIS_Geometry
$row = '';
foreach ($points_arr as $point) {
$row .= '<circle cx="' . $point[0] . '" cy="' . $point[1] . '" r="3"';
$point_options['id'] = $label . rand();
foreach ($point_options as $option => $val) {
$row .= ' ' . $option . '="' . trim($val) . '"';
if ($point[0] != '' && $point[1] != '') {
$row .= '<circle cx="' . $point[0] . '" cy="' . $point[1] . '" r="3"';
$point_options['id'] = $label . rand();
foreach ($point_options as $option => $val) {
$row .= ' ' . $option . '="' . trim($val) . '"';
}
$row .= '/>';
}
$row .= '/>';
}
return $row;
@ -176,11 +197,15 @@ class PMA_GIS_Multipoint extends PMA_GIS_Geometry
$row = 'new Array(';
foreach ($points_arr as $point) {
$row .= '(new OpenLayers.Geometry.Point(' . $point[0] . ', ' . $point[1]
. ')).transform(new OpenLayers.Projection("EPSG:' . $srid
. '"), map.getProjectionObject()), ';
if ($point[0] != '' && $point[1] != '') {
$row .= '(new OpenLayers.Geometry.Point(' . $point[0] . ', ' . $point[1]
. ')).transform(new OpenLayers.Projection("EPSG:' . $srid
. '"), map.getProjectionObject()), ';
}
}
if (substr($row, strlen($row) - 2) == ', ') {
$row = substr($row, 0, strlen($row) - 2);
}
$row = substr($row, 0, strlen($row) - 2);
$row .= ')';
$result .= 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
@ -188,5 +213,88 @@ class PMA_GIS_Multipoint extends PMA_GIS_Geometry
. json_encode($style_options) . '));';
return $result;
}
/**
* Generate the WKT with the set of parameters passed by the GIS editor.
*
* @param array $gis_data GIS data
* @param int $index Index into the parameter object
* @param string $empty Multipoint does not adhere to this
*
* @return WKT with the set of parameters passed by the GIS editor
*/
public function generateWkt($gis_data, $index, $empty = '')
{
$no_of_points = isset($gis_data[$index]['MULTIPOINT']['no_of_points'])
? $gis_data[$index]['MULTIPOINT']['no_of_points'] : 1;
if ($no_of_points < 1) {
$no_of_points = 1;
}
$wkt = 'MULTIPOINT(';
for ($i = 0; $i < $no_of_points; $i++) {
$wkt .= ((isset($gis_data[$index]['MULTIPOINT'][$i]['x'])
&& trim($gis_data[$index]['MULTIPOINT'][$i]['x']) != '')
? $gis_data[$index]['MULTIPOINT'][$i]['x'] : '')
. ' ' . ((isset($gis_data[$index]['MULTIPOINT'][$i]['y'])
&& trim($gis_data[$index]['MULTIPOINT'][$i]['y']) != '')
? $gis_data[$index]['MULTIPOINT'][$i]['y'] : '') . ',';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= ')';
return $wkt;
}
/**
* Generate the WKT for the data from ESRI shape files.
*
* @param array $row_data GIS data
*
* @return the WKT for the data from ESRI shape files
*/
public function getShape($row_data)
{
$wkt = 'MULTIPOINT(';
for ($i = 0; $i < $row_data['numpoints']; $i++) {
$wkt .= $row_data['points'][$i]['x'] . ' ' . $row_data['points'][$i]['y'] . ',';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= ')';
return $wkt;
}
/**
* Generate parameters for the GIS data editor from the value of the GIS column.
*
* @param string $value of the GIS column
* @param index $index of the geometry
*
* @return parameters for the GIS data editor from the value of the GIS column
*/
public function generateParams($value, $index = -1)
{
if ($index == -1) {
$index = 0;
$params = array();
$data = PMA_GIS_Geometry::generateParams($value);
$params['srid'] = $data['srid'];
$wkt = $data['wkt'];
} else {
$params[$index]['gis_type'] = 'MULTIPOINT';
$wkt = $value;
}
// Trim to remove leading 'MULTIPOINT(' and trailing ')'
$points = substr($wkt, 11, (strlen($wkt) - 12));
$points_arr = $this->extractPoints($points, null);
$no_of_points = count($points_arr);
$params[$index]['MULTIPOINT']['no_of_points'] = $no_of_points;
for ($i = 0; $i < $no_of_points; $i++) {
$params[$index]['MULTIPOINT'][$i]['x'] = $points_arr[$i][0];
$params[$index]['MULTIPOINT'][$i]['y'] = $points_arr[$i][1];
}
return $params;
}
}
?>

View File

@ -82,6 +82,7 @@ class PMA_GIS_Multipolygon extends PMA_GIS_Geometry
public function prepareRowAsPng($spatial, $label, $fill_color, $scale_data, $image)
{
// allocate colors
$black = imagecolorallocate($image, 0, 0, 0);
$red = hexdec(substr($fill_color, 1, 2));
$green = hexdec(substr($fill_color, 3, 2));
$blue = hexdec(substr($fill_color, 4, 2));
@ -92,6 +93,7 @@ class PMA_GIS_Multipolygon extends PMA_GIS_Geometry
// Seperate each polygon
$polygons = explode(")),((", $multipolygon);
$first_poly = true;
foreach ($polygons as $polygon) {
// If the polygon doesnt have an inner polygon
if (strpos($polygon, "),(") === false) {
@ -112,6 +114,15 @@ class PMA_GIS_Multipolygon extends PMA_GIS_Geometry
}
// draw polygon
imagefilledpolygon($image, $points_arr, sizeof($points_arr) / 2, $color);
// mark label point if applicable
if (isset($label) && trim($label) != '' && $first_poly) {
$label_point = array($points_arr[2], $points_arr[3]);
}
$first_poly = false;
}
// print label if applicable
if (isset($label_point)) {
imagestring($image, 1, $points_arr[2], $points_arr[3], trim($label), $black);
}
return $image;
}
@ -140,6 +151,7 @@ class PMA_GIS_Multipolygon extends PMA_GIS_Geometry
// Seperate each polygon
$polygons = explode(")),((", $multipolygon);
$first_poly = true;
foreach ($polygons as $polygon) {
// If the polygon doesnt have an inner polygon
if (strpos($polygon, "),(") === false) {
@ -161,6 +173,18 @@ class PMA_GIS_Multipolygon extends PMA_GIS_Geometry
}
// draw polygon
$pdf->Polygon($points_arr, 'F*', array(), $color, true);
// mark label point if applicable
if (isset($label) && trim($label) != '' && $first_poly) {
$label_point = array($points_arr[2], $points_arr[3]);
}
$first_poly = false;
}
// print label if applicable
if (isset($label_point)) {
$pdf->SetXY($label_point[0], $label_point[1]);
$pdf->SetFontSize(5);
$pdf->Cell(0, 0, trim($label));
}
return $pdf;
}
@ -287,5 +311,190 @@ class PMA_GIS_Multipolygon extends PMA_GIS_Geometry
return $row;
}
/**
* Generate the WKT with the set of parameters passed by the GIS editor.
*
* @param array $gis_data GIS data
* @param int $index Index into the parameter object
* @param string $empty Value for empty points
*
* @return WKT with the set of parameters passed by the GIS editor
*/
public function generateWkt($gis_data, $index, $empty = '')
{
$no_of_polygons = isset($gis_data[$index]['MULTIPOLYGON']['no_of_polygons'])
? $gis_data[$index]['MULTIPOLYGON']['no_of_polygons'] : 1;
if ($no_of_polygons < 1) {
$no_of_polygons = 1;
}
$wkt = 'MULTIPOLYGON(';
for ($k = 0; $k < $no_of_polygons; $k++) {
$no_of_lines = isset($gis_data[$index]['MULTIPOLYGON'][$k]['no_of_lines'])
? $gis_data[$index]['MULTIPOLYGON'][$k]['no_of_lines'] : 1;
if ($no_of_lines < 1) {
$no_of_lines = 1;
}
$wkt .= '(';
for ($i = 0; $i < $no_of_lines; $i++) {
$no_of_points = isset($gis_data[$index]['MULTIPOLYGON'][$k][$i]['no_of_points'])
? $gis_data[$index]['MULTIPOLYGON'][$k][$i]['no_of_points'] : 4;
if ($no_of_points < 4) {
$no_of_points = 4;
}
$wkt .= '(';
for ($j = 0; $j < $no_of_points; $j++) {
$wkt .= ((isset($gis_data[$index]['MULTIPOLYGON'][$k][$i][$j]['x'])
&& trim($gis_data[$index]['MULTIPOLYGON'][$k][$i][$j]['x']) != '')
? $gis_data[$index]['MULTIPOLYGON'][$k][$i][$j]['x'] : $empty)
. ' ' . ((isset($gis_data[$index]['MULTIPOLYGON'][$k][$i][$j]['y'])
&& trim($gis_data[$index]['MULTIPOLYGON'][$k][$i][$j]['y']) != '')
? $gis_data[$index]['MULTIPOLYGON'][$k][$i][$j]['y'] : $empty) .',';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= '),';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= '),';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= ')';
return $wkt;
}
/**
* Generate the WKT for the data from ESRI shape files.
*
* @param array $row_data GIS data
*
* @return the WKT for the data from ESRI shape files
*/
public function getShape($row_data)
{
// Determines whether each line ring is an inner ring or an outer ring.
// If it's an inner ring get a point on the surface which can be used to
// correctly classify inner rings to their respective outer rings.
require_once './libraries/gis/pma_gis_polygon.php';
foreach ($row_data['parts'] as $i => $ring) {
$row_data['parts'][$i]['isOuter'] = PMA_GIS_Polygon::isOuterRing($ring['points']);
}
// Find points on surface for inner rings
foreach ($row_data['parts'] as $i => $ring) {
if (! $ring['isOuter']) {
$row_data['parts'][$i]['pointOnSurface'] = PMA_GIS_Polygon::getPointOnSurface($ring['points']);
}
}
// Classify inner rings to their respective outer rings.
foreach ($row_data['parts'] as $j => $ring1) {
if (! $ring1['isOuter']) {
foreach ($row_data['parts'] as $k => $ring2) {
if ($ring2['isOuter']) {
// If the pointOnSurface of the inner ring is also inside the outer ring
if (PMA_GIS_Polygon::isPointInsidePolygon($ring1['pointOnSurface'], $ring2['points'])) {
if (! isset($ring2['inner'])) {
$row_data['parts'][$k]['inner'] = array();
}
$row_data['parts'][$k]['inner'][] = $j;
}
}
}
}
}
$wkt = 'MULTIPOLYGON(';
// for each polygon
foreach ($row_data['parts'] as $ring) {
if ($ring['isOuter']) {
$wkt .= '('; // start of polygon
$wkt .= '('; // start of outer ring
foreach($ring['points'] as $point) {
$wkt .= $point['x'] . ' ' . $point['y'] . ',';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= ')'; // end of outer ring
// inner rings if any
if (isset($ring['inner'])) {
foreach ($ring['inner'] as $j) {
$wkt .= ',('; // start of inner ring
foreach ($row_data['parts'][$j]['points'] as $innerPoint) {
$wkt .= $innerPoint['x'] . ' ' . $innerPoint['y'] . ',';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= ')'; // end of inner ring
}
}
$wkt .= '),'; // end of polygon
}
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= ')'; // end of multipolygon
return $wkt;
}
/**
* Generate parameters for the GIS data editor from the value of the GIS column.
*
* @param string $value of the GIS column
* @param index $index of the geometry
*
* @return parameters for the GIS data editor from the value of the GIS column
*/
public function generateParams($value, $index = -1)
{
if ($index == -1) {
$index = 0;
$params = array();
$data = PMA_GIS_Geometry::generateParams($value);
$params['srid'] = $data['srid'];
$wkt = $data['wkt'];
} else {
$params[$index]['gis_type'] = 'MULTIPOLYGON';
$wkt = $value;
}
// Trim to remove leading 'MULTIPOLYGON(((' and trailing ')))'
$multipolygon = substr($wkt, 15, (strlen($wkt) - 18));
// Seperate each polygon
$polygons = explode(")),((", $multipolygon);
$params[$index]['MULTIPOLYGON']['no_of_polygons'] = count($polygons);
$k = 0;
foreach ($polygons as $polygon) {
// If the polygon doesnt have an inner polygon
if (strpos($polygon, "),(") === false) {
$params[$index]['MULTIPOLYGON'][$k]['no_of_lines'] = 1;
$points_arr = $this->extractPoints($polygon, null);
$no_of_points = count($points_arr);
$params[$index]['MULTIPOLYGON'][$k][0]['no_of_points'] = $no_of_points;
for ($i = 0; $i < $no_of_points; $i++) {
$params[$index]['MULTIPOLYGON'][$k][0][$i]['x'] = $points_arr[$i][0];
$params[$index]['MULTIPOLYGON'][$k][0][$i]['y'] = $points_arr[$i][1];
}
} else {
// Seperate outer and inner polygons
$parts = explode("),(", $polygon);
$params[$index]['MULTIPOLYGON'][$k]['no_of_lines'] = count($parts);
$j = 0;
foreach ($parts as $ring) {
$points_arr = $this->extractPoints($ring, null);
$no_of_points = count($points_arr);
$params[$index]['MULTIPOLYGON'][$k][$j]['no_of_points'] = $no_of_points;
for ($i = 0; $i < $no_of_points; $i++) {
$params[$index]['MULTIPOLYGON'][$k][$j][$i]['x'] = $points_arr[$i][0];
$params[$index]['MULTIPOLYGON'][$k][$j][$i]['y'] = $points_arr[$i][1];
}
$j++;
}
}
$k++;
}
return $params;
}
}
?>

View File

@ -59,6 +59,7 @@ class PMA_GIS_Point extends PMA_GIS_Geometry
public function prepareRowAsPng($spatial, $label, $point_color, $scale_data, $image)
{
// allocate colors
$black = imagecolorallocate($image, 0, 0, 0);
$red = hexdec(substr($point_color, 1, 2));
$green = hexdec(substr($point_color, 3, 2));
$blue = hexdec(substr($point_color, 4, 2));
@ -69,7 +70,13 @@ class PMA_GIS_Point extends PMA_GIS_Geometry
$points_arr = $this->extractPoints($point, $scale_data);
// draw a small circle to mark the point
imagearc($image, $points_arr[0][0], $points_arr[0][1], 7, 7, 0, 360, $color);
if ($points_arr[0][0] != '' && $points_arr[0][1] != '') {
imagearc($image, $points_arr[0][0], $points_arr[0][1], 7, 7, 0, 360, $color);
// print label if applicable
if (isset($label) && trim($label) != '') {
imagestring($image, 1, $points_arr[0][0], $points_arr[0][1], trim($label), $black);
}
}
return $image;
}
@ -97,7 +104,15 @@ class PMA_GIS_Point extends PMA_GIS_Geometry
$points_arr = $this->extractPoints($point, $scale_data);
// draw a small circle to mark the point
$pdf->Circle($points_arr[0][0], $points_arr[0][1], 2, 0, 360, 'D', $line);
if ($points_arr[0][0] != '' && $points_arr[0][1] != '') {
$pdf->Circle($points_arr[0][0], $points_arr[0][1], 2, 0, 360, 'D', $line);
// print label if applicable
if (isset($label) && trim($label) != '') {
$pdf->SetXY($points_arr[0][0], $points_arr[0][1]);
$pdf->SetFontSize(5);
$pdf->Cell(0, 0, trim($label));
}
}
return $pdf;
}
@ -126,11 +141,14 @@ class PMA_GIS_Point extends PMA_GIS_Geometry
$point = substr($spatial, 6, (strlen($spatial) - 7));
$points_arr = $this->extractPoints($point, $scale_data);
$row = '<circle cx="' . $points_arr[0][0] . '" cy="' . $points_arr[0][1] . '" r="3"';
foreach ($point_options as $option => $val) {
$row .= ' ' . $option . '="' . trim($val) . '"';
$row = '';
if ($points_arr[0][0] != '' && $points_arr[0][1] != '') {
$row .= '<circle cx="' . $points_arr[0][0] . '" cy="' . $points_arr[0][1] . '" r="3"';
foreach ($point_options as $option => $val) {
$row .= ' ' . $option . '="' . trim($val) . '"';
}
$row .= '/>';
}
$row .= '/>';
return $row;
}
@ -167,12 +185,76 @@ class PMA_GIS_Point extends PMA_GIS_Geometry
$point = substr($spatial, 6, (strlen($spatial) - 7));
$points_arr = $this->extractPoints($point, null);
$result .= 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector(('
. 'new OpenLayers.Geometry.Point(' . $points_arr[0][0] . ', '
. $points_arr[0][1] . ').transform(new OpenLayers.Projection("EPSG:'
. $srid . '"), map.getProjectionObject())), null, '
. json_encode($style_options) . '));';
if ($points_arr[0][0] != '' && $points_arr[0][1] != '') {
$result .= 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector(('
. 'new OpenLayers.Geometry.Point(' . $points_arr[0][0] . ', '
. $points_arr[0][1] . ').transform(new OpenLayers.Projection("EPSG:'
. $srid . '"), map.getProjectionObject())), null, '
. json_encode($style_options) . '));';
}
return $result;
}
/**
* Generate the WKT with the set of parameters passed by the GIS editor.
*
* @param array $gis_data GIS data
* @param int $index Index into the parameter object
* @param string $empty Point deos not adhere to this parameter
*
* @return WKT with the set of parameters passed by the GIS editor
*/
public function generateWkt($gis_data, $index, $empty = '')
{
return 'POINT('
. ((isset($gis_data[$index]['POINT']['x']) && trim($gis_data[$index]['POINT']['x']) != '')
? $gis_data[$index]['POINT']['x'] : '') . ' '
. ((isset($gis_data[$index]['POINT']['y']) && trim($gis_data[$index]['POINT']['y']) != '')
? $gis_data[$index]['POINT']['y'] : '') . ')';
}
/**
* Generate the WKT for the data from ESRI shape files.
*
* @param array $row_data GIS data
*
* @return the WKT for the data from ESRI shape files
*/
public function getShape($row_data)
{
return 'POINT(' . (isset($row_data['x']) ? $row_data['x'] : '')
. ' ' . (isset($row_data['y']) ? $row_data['y'] : '') . ')';
}
/**
* Generate parameters for the GIS data editor from the value of the GIS column.
*
* @param string $value of the GIS column
* @param index $index of the geometry
*
* @return parameters for the GIS data editor from the value of the GIS column
*/
public function generateParams($value, $index = -1)
{
if ($index == -1) {
$index = 0;
$params = array();
$data = PMA_GIS_Geometry::generateParams($value);
$params['srid'] = $data['srid'];
$wkt = $data['wkt'];
} else {
$params[$index]['gis_type'] = 'POINT';
$wkt = $value;
}
// Trim to remove leading 'POINT(' and trailing ')'
$point = substr($wkt, 6, (strlen($wkt) - 7));
$points_arr = $this->extractPoints($point, null);
$params[$index]['POINT']['x'] = $points_arr[0][0];
$params[$index]['POINT']['y'] = $points_arr[0][1];
return $params;
}
}
?>

View File

@ -77,6 +77,7 @@ class PMA_GIS_Polygon extends PMA_GIS_Geometry
public function prepareRowAsPng($spatial, $label, $fill_color, $scale_data, $image)
{
// allocate colors
$black = imagecolorallocate($image, 0, 0, 0);
$red = hexdec(substr($fill_color, 1, 2));
$green = hexdec(substr($fill_color, 3, 2));
$blue = hexdec(substr($fill_color, 4, 2));
@ -105,6 +106,10 @@ class PMA_GIS_Polygon extends PMA_GIS_Geometry
// draw polygon
imagefilledpolygon($image, $points_arr, sizeof($points_arr) / 2, $color);
// print label if applicable
if (isset($label) && trim($label) != '') {
imagestring($image, 1, $points_arr[2], $points_arr[3], trim($label), $black);
}
return $image;
}
@ -150,6 +155,12 @@ class PMA_GIS_Polygon extends PMA_GIS_Geometry
// draw polygon
$pdf->Polygon($points_arr, 'F*', array(), $color, true);
// print label if applicable
if (isset($label) && trim($label) != '') {
$pdf->SetXY($points_arr[2], $points_arr[3]);
$pdf->SetFontSize(5);
$pdf->Cell(0, 0, trim($label));
}
return $pdf;
}
@ -262,5 +273,248 @@ class PMA_GIS_Polygon extends PMA_GIS_Geometry
return $row;
}
/**
* Generate the WKT with the set of parameters passed by the GIS editor.
*
* @param array $gis_data GIS data
* @param int $index Index into the parameter object
* @param string $empty Value for empty points
*
* @return WKT with the set of parameters passed by the GIS editor
*/
public function generateWkt($gis_data, $index, $empty = '')
{
$no_of_lines = isset($gis_data[$index]['POLYGON']['no_of_lines'])
? $gis_data[$index]['POLYGON']['no_of_lines'] : 1;
if ($no_of_lines < 1) {
$no_of_lines = 1;
}
$wkt = 'POLYGON(';
for ($i = 0; $i < $no_of_lines; $i++) {
$no_of_points = isset($gis_data[$index]['POLYGON'][$i]['no_of_points'])
? $gis_data[$index]['POLYGON'][$i]['no_of_points'] : 4;
if ($no_of_points < 4) {
$no_of_points = 4;
}
$wkt .= '(';
for ($j = 0; $j < $no_of_points; $j++) {
$wkt .= ((isset($gis_data[$index]['POLYGON'][$i][$j]['x'])
&& trim($gis_data[$index]['POLYGON'][$i][$j]['x']) != '')
? $gis_data[$index]['POLYGON'][$i][$j]['x'] : $empty)
. ' ' . ((isset($gis_data[$index]['POLYGON'][$i][$j]['y'])
&& trim($gis_data[$index]['POLYGON'][$i][$j]['y']) != '')
? $gis_data[$index]['POLYGON'][$i][$j]['y'] : $empty) .',';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= '),';
}
$wkt = substr($wkt, 0, strlen($wkt) - 1);
$wkt .= ')';
return $wkt;
}
/**
* Calculates the area of a closed simple polygon.
*
* @param array $ring array of points forming the ring
*
* @return the area of a closed simple polygon.
*/
public static function area($ring)
{
$no_of_points = count($ring);
// If the last point is same as the first point ignore it
$last = count($ring) - 1;
if (($ring[0]['x'] == $ring[$last]['x'])
&& ($ring[0]['y'] == $ring[$last]['y'])
) {
$no_of_points--;
}
// _n-1
// A = _1_ \ (X(i) * Y(i+1)) - (Y(i) * X(i+1))
// 2 /__
// i=0
$area = 0;
for ($i = 0; $i < $no_of_points; $i++) {
$j = ($i + 1) % $no_of_points;
$area += $ring[$i]['x'] * $ring[$j]['y'];
$area -= $ring[$i]['y'] * $ring[$j]['x'];
}
$area /= 2.0;
return $area;
}
/**
* Determines whether a set of points represents an outer ring.
* If points are in clockwise orientation then, they form an outer ring.
*
* @param array $ring array of points forming the ring
*
* @return whether a set of points represents an outer ring.
*/
public static function isOuterRing($ring)
{
// If area is negative then it's in clockwise orientation,
// i.e. it's an outer ring
if (PMA_GIS_Polygon::area($ring) < 0) {
return true;
}
return false;
}
/**
* Determines whether a given point is inside a given polygon.
*
* @param array $point x, y coordinates of the point
* @param array $polygon array of points forming the ring
*
* @return whether a given point is inside a given polygon
*/
public static function isPointInsidePolygon($point, $polygon)
{
// If first point is repeated at the end remove it
$last = count($polygon) - 1;
if (($polygon[0]['x'] == $polygon[$last]['x'])
&& ($polygon[0]['y'] == $polygon[$last]['y'])
) {
$polygon = array_slice($polygon, 0, $last);
}
$no_of_points = count($polygon);
$counter = 0;
// Use ray casting algorithm
$p1 = $polygon[0];
for ($i = 1; $i <= $no_of_points; $i++) {
$p2 = $polygon[$i % $no_of_points];
if ($point['y'] > min(array($p1['y'], $p2['y']))) {
if ($point['y'] <= max(array($p1['y'], $p2['y']))) {
if ($point['x'] <= max(array($p1['x'], $p2['x']))) {
if ($p1['y'] != $p2['y']) {
$xinters = ($point['y'] - $p1['y'])
* ($p2['x'] - $p1['x'])
/ ($p2['y'] - $p1['y']) + $p1['x'];
if ($p1['x'] == $p2['x'] || $point['x'] <= $xinters) {
$counter++;
}
}
}
}
}
$p1 = $p2;
}
if ($counter % 2 == 0) {
return false;
} else {
return true;
}
}
/**
* Returns a point that is guaranteed to be on the surface of the ring.
* (for simple closed rings)
*
* @param array $ring array of points forming the ring
*
* @return a point on the surface of the ring
*/
public static function getPointOnSurface($ring)
{
// Find two consecutive distinct points.
for ($i = 0; $i < count($ring) - 1; $i++) {
if ($ring[$i]['y'] != $ring[$i + 1]['y']) {
$x0 = $ring[$i]['x'];
$x1 = $ring[$i + 1]['x'];
$y0 = $ring[$i]['y'];
$y1 = $ring[$i + 1]['y'];
break;
}
}
if (! isset($x0)) {
return false;
}
// Find the mid point
$x2 = ($x0 + $x1) / 2;
$y2 = ($y0 + $y1) / 2;
// Always keep $epsilon < 1 to go with the reduction logic down here
$epsilon = 0.1;
$denominator = sqrt(pow(($y1 - $y0), 2) + pow(($x0 - $x1), 2));
$pointA = array(); $pointB = array();
while (true) {
// Get the points on either sides of the line
// with a distance of epsilon to the mid point
$pointA['x'] = $x2 + ($epsilon * ($y1 - $y0)) / $denominator;
$pointA['y'] = $y2 + ($pointA['x'] - $x2) * ($x0 - $x1) / ($y1 - $y0);
$pointB['x'] = $x2 + ($epsilon * ($y1 - $y0)) / (0 - $denominator);
$pointB['y'] = $y2 + ($pointB['x'] - $x2) * ($x0 - $x1) / ($y1 - $y0);
// One of the points should be inside the polygon,
// unless epcilon chosen is too large
if (PMA_GIS_Polygon::isPointInsidePolygon($pointA, $ring)) {
return $pointA;
} elseif (PMA_GIS_Polygon::isPointInsidePolygon($pointB, $ring)) {
return $pointB;
} else {
//If both are outside the polygon reduce the epsilon and
//recalculate the points(reduce exponentially for faster convergance)
$epsilon = pow($epsilon, 2);
if ($epsilon == 0) {
return false;
}
}
}
}
/** Generate parameters for the GIS data editor from the value of the GIS column.
*
* @param string $value of the GIS column
* @param index $index of the geometry
*
* @return parameters for the GIS data editor from the value of the GIS column
*/
public function generateParams($value, $index = -1)
{
if ($index == -1) {
$index = 0;
$params = array();
$data = PMA_GIS_Geometry::generateParams($value);
$params['srid'] = $data['srid'];
$wkt = $data['wkt'];
} else {
$params[$index]['gis_type'] = 'POLYGON';
$wkt = $value;
}
// Trim to remove leading 'POLYGON((' and trailing '))'
$polygon = substr($wkt, 9, (strlen($wkt) - 11));
// Seperate each linestring
$linerings = explode("),(", $polygon);
$params[$index]['POLYGON']['no_of_lines'] = count($linerings);
$j = 0;
foreach ($linerings as $linering) {
$points_arr = $this->extractPoints($linering, null);
$no_of_points = count($points_arr);
$params[$index]['POLYGON'][$j]['no_of_points'] = $no_of_points;
for ($i = 0; $i < $no_of_points; $i++) {
$params[$index]['POLYGON'][$j][$i]['x'] = $points_arr[$i][0];
$params[$index]['POLYGON'][$j][$i]['y'] = $points_arr[$i][1];
}
$j++;
}
return $params;
}
}
?>

View File

@ -18,15 +18,14 @@ class PMA_GIS_Visualization
// Array of colors to be used for GIS visualizations.
'colors' => array(
'#BCE02E',
'#B02EE0',
'#E0642E',
'#E0D62E',
'#2E97E0',
'#B02EE0',
'#BCE02E',
'#E02E75',
'#5CE02E',
'#E0B02E',
'#000000',
'#0022E0',
'#726CB1',
'#481A36',
@ -153,7 +152,7 @@ class PMA_GIS_Visualization
$output .= '<g id="groupPanel">';
$scale_data = $this->_scaleDataSet($this->_data);
$output .= $this->_prepareDataSet($this->_data, 0, $scale_data, 'svg', '');
$output .= $this->_prepareDataSet($this->_data, $scale_data, 'svg', '');
$output .= '</g>';
$output .= '</svg>';
@ -206,7 +205,7 @@ class PMA_GIS_Visualization
);
$scale_data = $this->_scaleDataSet($this->_data);
$image = $this->_prepareDataSet($this->_data, 0, $scale_data, 'png', $image);
$image = $this->_prepareDataSet($this->_data, $scale_data, 'png', $image);
return $image;
}
@ -256,7 +255,33 @@ class PMA_GIS_Visualization
{
$this->init();
$scale_data = $this->_scaleDataSet($this->_data);
$output = $this->_prepareDataSet($this->_data, 0, $scale_data, 'ol', '');
$output =
'var options = {'
. 'projection: new OpenLayers.Projection("EPSG:900913"),'
. 'displayProjection: new OpenLayers.Projection("EPSG:4326"),'
. 'units: "m",'
. 'numZoomLevels: 18,'
. 'maxResolution: 156543.0339,'
. 'maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508),'
. 'restrictedExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508)'
. '};'
. 'var map = new OpenLayers.Map("openlayersmap", options);'
. 'var layerNone = new OpenLayers.Layer.Boxes("None", {isBaseLayer: true});'
. 'var layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");'
. 'var layerOsmarender = new OpenLayers.Layer.OSM.Osmarender("Osmarender");'
. 'var layerCycleMap = new OpenLayers.Layer.OSM.CycleMap("CycleMap");'
. 'map.addLayers([layerMapnik, layerOsmarender, layerCycleMap, layerNone]);'
. 'var vectorLayer = new OpenLayers.Layer.Vector("Data");'
. 'var bound;';
$output .= $this->_prepareDataSet($this->_data, $scale_data, 'ol', '');
$output .=
'map.addLayer(vectorLayer);'
. 'map.zoomToExtent(bound);'
. 'if (map.getZoom() < 2) {'
. 'map.zoomTo(2);'
. '}'
. 'map.addControl(new OpenLayers.Control.LayerSwitcher());'
. 'map.addControl(new OpenLayers.Control.MousePosition());';
return $output;
}
@ -274,7 +299,7 @@ class PMA_GIS_Visualization
include_once './libraries/tcpdf/tcpdf.php';
// create pdf
$pdf = new TCPDF('', 'pt', 'A4', true, 'UTF-8', false);
$pdf = new TCPDF('', 'pt', $GLOBALS['cfg']['PDFDefaultPageSize'], true, 'UTF-8', false);
// disable header and footer
$pdf->setPrintHeader(false);
@ -287,7 +312,7 @@ class PMA_GIS_Visualization
$pdf->AddPage();
$scale_data = $this->_scaleDataSet($this->_data);
$pdf = $this->_prepareDataSet($this->_data, 0, $scale_data, 'pdf', $pdf);
$pdf = $this->_prepareDataSet($this->_data, $scale_data, 'pdf', $pdf);
// sanitize file name
$file_name = $this->_sanitizeName($file_name, 'pdf');
@ -319,6 +344,9 @@ class PMA_GIS_Visualization
$type = substr($ref_data, 0, $type_pos);
$gis_obj = PMA_GIS_Factory::factory($type);
if (! $gis_obj) {
continue;
}
$scale_data = $gis_obj->scaleRow($row[$this->_settings['spatialColumn']]);
// Upadate minimum/maximum values for x and y cordinates.
@ -377,19 +405,19 @@ class PMA_GIS_Visualization
/**
* Prepares and return the dataset as needed by the visualization.
*
* @param array $data Raw data
* @param int $color_number Start index to the color array
* @param array $scale_data Data related to scaling
* @param string $format Format of the visulaization
* @param image $results Image object in the case of png
* @param array $data Raw data
* @param array $scale_data Data related to scaling
* @param string $format Format of the visulaization
* @param image $results Image object in the case of png
*
* @return the formatted array of data.
*/
private function _prepareDataSet($data, $color_number, $scale_data, $format, $results)
private function _prepareDataSet($data, $scale_data, $format, $results)
{
$color_number = 0;
// loop through the rows
foreach ($data as $row) {
$index = $color_number % sizeof($this->_settings['colors']);
// Figure out the data type
@ -398,6 +426,9 @@ class PMA_GIS_Visualization
$type = substr($ref_data, 0, $type_pos);
$gis_obj = PMA_GIS_Factory::factory($type);
if (! $gis_obj) {
continue;
}
$label = '';
if (isset($this->_settings['labelColumn'])
&& isset($row[$this->_settings['labelColumn']])
@ -432,4 +463,3 @@ class PMA_GIS_Visualization
}
}
?>

View File

@ -16,7 +16,7 @@
*
* @return the modified sql query.
*/
function PMA_GIS_modify_query($sql_query, $visualizationSettings)
function PMA_GIS_modifyQuery($sql_query, $visualizationSettings)
{
$modified_query = 'SELECT ';
@ -75,7 +75,9 @@ function PMA_GIS_modify_query($sql_query, $visualizationSettings)
// If select cluase is *
} else {
// If label column is chosen add it to the query
if ($visualizationSettings['labelColumn'] != '') {
if (isset($visualizationSettings['labelColumn'])
&& $visualizationSettings['labelColumn'] != ''
) {
$modified_query .= '`' . $visualizationSettings['labelColumn'] .'`, ';
}
@ -84,7 +86,8 @@ function PMA_GIS_modify_query($sql_query, $visualizationSettings)
. '`) AS `' . $visualizationSettings['spatialColumn'] . '`, ';
// Get the SRID
$modified_query .= 'SRID(`' . $visualizationSettings['spatialColumn'] . '`) AS `srid` ';
$modified_query .= 'SRID(`' . $visualizationSettings['spatialColumn']
. '`) AS `srid` ';
}
// Append the rest of the query
@ -98,14 +101,16 @@ function PMA_GIS_modify_query($sql_query, $visualizationSettings)
function sanitize($select)
{
$table_col = $select['table_name'] . "." . $select['column'];
$db_table_col = $select['db'] . "." . $select['table_name'] . "." . $select['column'];
$db_table_col = $select['db'] . "." . $select['table_name']
. "." . $select['column'];
if ($select['expr'] == $select['column']) {
return "`" . $select['column'] . "`";
} elseif ($select['expr'] == $table_col) {
return "`" . $select['table_name'] . "`.`" . $select['column'] . "`";
} elseif ($select['expr'] == $db_table_col) {
return "`" . $select['db'] . "`.`" . $select['table_name'] . "`.`" . $select['column'] . "`";
return "`" . $select['db'] . "`.`" . $select['table_name']
. "`.`" . $select['column'] . "`";
}
return $select['expr'];
}
@ -119,7 +124,7 @@ function sanitize($select)
*
* @return string HTML and JS code for the GIS visualization
*/
function PMA_GIS_visualization_results($data, &$visualizationSettings, $format)
function PMA_GIS_visualizationResults($data, &$visualizationSettings, $format)
{
include_once './libraries/gis/pma_gis_visualization.php';
include_once './libraries/gis/pma_gis_factory.php';
@ -156,7 +161,7 @@ function PMA_GIS_visualization_results($data, &$visualizationSettings, $format)
*
* @return file File containing the visualization
*/
function PMA_GIS_save_to_file($data, $visualizationSettings, $format, $fileName)
function PMA_GIS_saveToFile($data, $visualizationSettings, $format, $fileName)
{
include_once './libraries/gis/pma_gis_visualization.php';
include_once './libraries/gis/pma_gis_factory.php';

View File

@ -425,6 +425,7 @@ define("VARCHAR", 1);
define("INT", 2);
define("DECIMAL", 3);
define("BIGINT", 4);
define("GEOMETRY", 5);
/* Decimal size defs */
define("M", 0);
@ -437,8 +438,9 @@ define("COL_NAMES", 1);
define("ROWS", 2);
/* Analysis array defs */
define("TYPES", 0);
define("SIZES", 1);
define("TYPES", 0);
define("SIZES", 1);
define("FORMATTEDSQL", 2);
/**
* Obtains the precision (total # of digits) from a size of type decimal
@ -916,7 +918,7 @@ function PMA_buildSQL($db_name, &$tables, &$analyses = null, &$additional_sql =
}
if ($analyses != null) {
$type_array = array(NONE => "NULL", VARCHAR => "varchar", INT => "int", DECIMAL => "decimal", BIGINT => "bigint");
$type_array = array(NONE => "NULL", VARCHAR => "varchar", INT => "int", DECIMAL => "decimal", BIGINT => "bigint", GEOMETRY => 'geometry');
/* TODO: Do more checking here to make sure they really are matched */
if (count($tables) != count($analyses)) {
@ -935,7 +937,10 @@ function PMA_buildSQL($db_name, &$tables, &$analyses = null, &$additional_sql =
$size = 10;
}
$tempSQLStr .= PMA_backquote($tables[$i][COL_NAMES][$j]) . " " . $type_array[$analyses[$i][TYPES][$j]] . "(" . $size . ")";
$tempSQLStr .= PMA_backquote($tables[$i][COL_NAMES][$j]) . " " . $type_array[$analyses[$i][TYPES][$j]];
if ($analyses[$i][TYPES][$j] != GEOMETRY) {
$tempSQLStr .= "(" . $size . ")";
}
if ($j != (count($tables[$i][COL_NAMES]) - 1)) {
$tempSQLStr .= ", ";
@ -980,20 +985,28 @@ function PMA_buildSQL($db_name, &$tables, &$analyses = null, &$additional_sql =
$tempSQLStr .= "(";
for ($k = 0; $k < $num_cols; ++$k) {
if ($analyses != null) {
$is_varchar = ($analyses[$i][TYPES][$col_count] === VARCHAR);
// If fully formatted SQL, no need to enclose with aphostrophes, add shalshes etc.
if ($analyses != null
&& isset($analyses[$i][FORMATTEDSQL][$col_count])
&& $analyses[$i][FORMATTEDSQL][$col_count] == true
) {
$tempSQLStr .= (string) $tables[$i][ROWS][$j][$k];
} else {
$is_varchar = !is_numeric($tables[$i][ROWS][$j][$k]);
}
if ($analyses != null) {
$is_varchar = ($analyses[$i][TYPES][$col_count] === VARCHAR);
} else {
$is_varchar = !is_numeric($tables[$i][ROWS][$j][$k]);
}
/* Don't put quotes around NULL fields */
if (! strcmp($tables[$i][ROWS][$j][$k], 'NULL')) {
$is_varchar = false;
}
/* Don't put quotes around NULL fields */
if (! strcmp($tables[$i][ROWS][$j][$k], 'NULL')) {
$is_varchar = false;
}
$tempSQLStr .= (($is_varchar) ? "'" : "");
$tempSQLStr .= PMA_sqlAddSlashes((string)$tables[$i][ROWS][$j][$k]);
$tempSQLStr .= (($is_varchar) ? "'" : "");
$tempSQLStr .= (($is_varchar) ? "'" : "");
$tempSQLStr .= PMA_sqlAddSlashes((string)$tables[$i][ROWS][$j][$k]);
$tempSQLStr .= (($is_varchar) ? "'" : "");
}
if ($k != ($num_cols - 1)) {
$tempSQLStr .= ", ";

399
libraries/import/shp.php Normal file
View File

@ -0,0 +1,399 @@
<?php
/**
* ESRI Shape file import plugin for phpMyAdmin
*
* @package phpMyAdmin-Import
* @subpackage ESRI_Shape
*/
if (! defined('PHPMYADMIN')) {
exit;
}
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/');
require_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 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 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));
$tmp = loadData("N", readFromBuffer(4)); //We read the length of the record
$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',
);
require_once './libraries/gis/pma_gis_geometry.php';
switch ($shp->shapeType) {
// ESRI Null Shape
case 0:
$gis_obj = null;
break;
// ESRI Point
case 1:
require_once './libraries/gis/pma_gis_point.php';
$gis_obj = PMA_GIS_Point::singleton();
break;
// ESRI PolyLine
case 3:
require_once './libraries/gis/pma_gis_multilinestring.php';
$gis_obj = PMA_GIS_Multilinestring::singleton();
break;
// ESRI Polygon
case 5:
require_once './libraries/gis/pma_gis_multipolygon.php';
$gis_obj = PMA_GIS_Multipolygon::singleton();
break;
// ESRI MultiPoint
case 8:
require_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();
}
?>

View File

@ -3,8 +3,8 @@
/**
* Functions for the table-search page and zoom-search page
*
* Funtion PMA_tbl_getFields : Returns the fields of a table
* Funtion PMA_tbl_search_getWhereClause : Returns the where clause for query generation
* Funtion PMA_tbl_getFields : Returns the fields of a table
* Funtion PMA_tbl_search_getWhereClause : Returns the where clause for query generation
*
* @package phpMyAdmin
*/
@ -13,7 +13,7 @@ require_once 'url_generating.lib.php';
/**
* PMA_tbl_setTitle() sets the title for foreign keys display link
*
*
* @param $propertiesIconic Type of icon property
* @param $themeImage Icon Image
* @return string $str Value of the Title
@ -51,20 +51,26 @@ function PMA_tbl_setTitle($propertiesIconic,$pmaThemeImage){
* @param $db Selected database
* @param $table Selected table
*
* @return array($fields_list,$fields_type,$fields_collation,$fields_null) Array containing the field list, field types, collations and null constatint
* @return array($fields_list,$fields_type,$fields_collation,$fields_null) Array containing the field list, field types, collations and null constatint
*
*/
function PMA_tbl_getFields($table,$db) {
// Gets the list and number of fields
$result = PMA_DBI_query('SHOW FULL FIELDS FROM ' . PMA_backquote($table) . ' FROM ' . PMA_backquote($db) . ';', null, PMA_DBI_QUERY_STORE);
$fields_cnt = PMA_DBI_num_rows($result);
$fields_list = $fields_null = $fields_type = $fields_collation = array();
$geom_column_present = false;
$geom_types = PMA_getGISDatatypes();
while ($row = PMA_DBI_fetch_assoc($result)) {
$fields_list[] = $row['Field'];
$type = $row['Type'];
// check whether table contains geometric columns
if (in_array($type, $geom_types)) {
$geom_column_present = true;
}
// reformat mysql query output
if (strncasecmp($type, 'set', 3) == 0
|| strncasecmp($type, 'enum', 4) == 0) {
@ -93,20 +99,26 @@ function PMA_tbl_getFields($table,$db) {
PMA_DBI_free_result($result);
unset($result, $type);
return array($fields_list,$fields_type,$fields_collation,$fields_null);
return array($fields_list,$fields_type,$fields_collation,$fields_null, $geom_column_present);
}
/* PMA_tbl_setTableHeader() sets the table header for displaying a table in query-by-example format
*
* @return HTML content, the tags and content for table header
* @return HTML content, the tags and content for table header
*
*/
function PMA_tbl_setTableHeader(){
function PMA_tbl_setTableHeader($geom_column_present = false){
// Display the Function column only if there is alteast one geomety colum
$func = '';
if ($geom_column_present) {
$func = '<th>' . __('Function') . '</th>';
}
return '<thead>
<tr><th>' . __('Column') . '</th>
<tr>' . $func . '<th>' . __('Column') . '</th>
<th>' . __('Type') . '</th>
<th>' . __('Collation') . '</th>
<th>' . __('Operator') . '</th>
@ -117,9 +129,9 @@ return '<thead>
}
/* PMA_tbl_getSubTabs() returns an array with necessary configrations to create sub-tabs(Table Search and Zoom Search) in the table_select page
/* PMA_tbl_getSubTabs() returns an array with necessary configrations to create sub-tabs(Table Search and Zoom Search) in the table_select page
*
* @return array $subtabs Array containing configuration (icon,text,link,id,args) of sub-tabs for Table Search and Zoom search
* @return array $subtabs Array containing configuration (icon,text,link,id,args) of sub-tabs for Table Search and Zoom search
*
*/
@ -137,7 +149,7 @@ function PMA_tbl_getSubTabs(){
$subtabs['zoom']['link'] = 'tbl_zoom_select.php';
$subtabs['zoom']['text'] = __('Zoom Search');
$subtabs['zoom']['id'] = 'zoom_search_id';
return $subtabs;
}
@ -164,12 +176,13 @@ function PMA_tbl_getSubTabs(){
* @param $titles Selected title
* @param $foreignMaxLimit Max limit of displaying foreign elements
* @param $fields Array of search criteria inputs
* @param $in_fbs In function based search
*
* @return string $str HTML content for viewing foreing data and elements for search criteria input.
* @return string $str HTML content for viewing foreing data and elements for search criteria input.
*
*/
function PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i, $db, $table,$titles,$foreignMaxLimit, $fields){
function PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i, $db, $table, $titles, $foreignMaxLimit, $fields, $in_fbs = false){
$str = '';
@ -185,29 +198,40 @@ function PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fie
$foreignData['foreign_display'],
'', $foreignMaxLimit);
$str .= ' </select>' . "\n";
}
}
elseif ($foreignData['foreign_link'] == true) {
if(isset($fields[$i]) && is_string($fields[$i])){
$str .= '<input type="text" id="fieldID_' . $i .'"name="fields[' . $i . '] " value="' . $fields[$i] . '"';
'id="field_' . md5($field) . '[' . $i .']"
class="textfield"/>' ;
'id="field_' . md5($field) . '[' . $i .']"
class="textfield"/>' ;
}
else{
$str .= '<input type="text" id="fieldID_' . $i .'"name="fields[' . $i . '] "';
'id="field_' . md5($field) . '[' . $i .']"
class="textfield" />' ;
'id="field_' . md5($field) . '[' . $i .']"
class="textfield" />' ;
}
?>
<?php $str .= '<script type="text/javascript">';
// <![CDATA[
$str .= <<<EOT
<a target="_blank" onclick="window.open(this.href, 'foreigners', 'width=640,height=240,scrollbars=yes'); return false" href="browse_foreigners.php?
<a target="_blank" onclick="window.open(this.href, 'foreigners', 'width=640,height=240,scrollbars=yes'); return false" href="browse_foreigners.php?
EOT;
$str .= '' . PMA_generate_common_url($db, $table) . '&amp;field=' . urlencode($field) . '&amp;fieldkey=' . $i . '">' . str_replace("'", "\'", $titles['Browse']) . '</a>';
// ]]
$str .= '</script>';
}
elseif (strncasecmp($tbl_fields_type[$i], 'enum', 4) == 0) {
} elseif (in_array($tbl_fields_type[$i], PMA_getGISDatatypes())) {
// g e o m e t r y
$str .= '<input type="text" name="fields[' . $i . ']"'
.' size="40" class="textfield" id="field_' . $i . '" />' . "\n";
if ($in_fbs) {
$edit_url = 'gis_data_editor.php?' . PMA_generate_common_url();
$edit_str = PMA_getIcon('b_edit.png', __('Edit/Insert'), true);
$str .= '<span class="open_search_gis_editor">';
$str .= PMA_linkOrButton($edit_url, $edit_str, array(), false, false, '_blank');
$str .= '</span>';
}
} elseif (strncasecmp($tbl_fields_type[$i], 'enum', 4) == 0) {
// e n u m s
$enum_value=explode(', ', str_replace("'", '', substr($tbl_fields_type[$i], 5, -1)));
$cnt_enum_value = count($enum_value);
@ -224,7 +248,7 @@ EOT;
}
} // end for
$str .= ' </select>' . "\n";
}
}
else {
// o t h e r c a s e s
$the_class = 'textfield';
@ -267,17 +291,61 @@ EOT;
* @param $func_type Search fucntion/operator
* @param $unaryFlag Whether operator unary or not
*
* @return string $str HTML content for viewing foreing data and elements for search criteria input.
* @return string $str HTML content for viewing foreing data and elements for search criteria input.
*
*/
function PMA_tbl_search_getWhereClause($fields, $names, $types, $collations, $func_type, $unaryFlag){
function PMA_tbl_search_getWhereClause($fields, $names, $types, $collations, $func_type, $unaryFlag, $geom_func = null){
/**
* @todo move this to a more apropriate place
*/
$geom_unary_functions = array(
'IsEmpty' => 1,
'IsSimple' => 1,
'IsRing' => 1,
'IsClosed' => 1,
);
$w = '';
// If geometry function is set apply it to the field name
if ($geom_func != null && trim($geom_func) != '') {
// Get details about the geometry fucntions
$geom_funcs = PMA_getGISFunctions($types, true, false);
// If the function takes a single parameter
if ($geom_funcs[$geom_func]['params'] == 1) {
$backquoted_name = $geom_func . '(' . PMA_backquote($names) . ')';
// If the function takes two parameters
} else {
// create gis data from the string
$gis_data = PMA_createGISData($fields);
$w = $geom_func . '(' . PMA_backquote($names) . ',' . $gis_data . ')';
return $w;
}
// New output type is the output type of the function being applied
$types = $geom_funcs[$geom_func]['type'];
// If the intended where clause is something like 'IsEmpty(`spatial_col_name`)'
if (isset($geom_unary_functions[$geom_func]) && trim($fields) == '') {
$w = $backquoted_name;
return $w;
}
} else {
$backquoted_name = PMA_backquote($names);
}
$w = '';
if($unaryFlag){
$fields = '';
$w = PMA_backquote($names) . ' ' . $func_type;
$w = $backquoted_name . ' ' . $func_type;
} elseif (in_array($types, PMA_getGISDatatypes())) {
// create gis data from the string
$gis_data = PMA_createGISData($fields);
$w = $backquoted_name . ' ' . $func_type . ' ' . $gis_data;
} elseif (strncasecmp($types, 'enum', 4) == 0) {
if (!empty($fields)) {
@ -304,7 +372,7 @@ function PMA_tbl_search_getWhereClause($fields, $names, $types, $collations, $fu
$enum_where .= ', \'' . PMA_sqlAddslashes($fields[$e]) . '\'';
}
$w = PMA_backquote($names) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close;
$w = $backquoted_name . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close;
}
} elseif ($fields != '') {
@ -336,12 +404,12 @@ function PMA_tbl_search_getWhereClause($fields, $names, $types, $collations, $fu
$value = $quot . PMA_sqlAddslashes(trim($value)) . $quot;
if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN')
$w = PMA_backquote($names) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : '');
$w = $backquoted_name . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : '');
else
$w = PMA_backquote($names) . ' ' . $func_type . ' (' . implode(',', $values) . ')';
$w = $backquoted_name . ' ' . $func_type . ' (' . implode(',', $values) . ')';
}
else {
$w = PMA_backquote($names) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddslashes($fields) . $quot;;
$w = $backquoted_name . ' ' . $func_type . ' ' . $quot . PMA_sqlAddslashes($fields) . $quot;;
}
} // end if

View File

@ -9,12 +9,12 @@
/**
* Gets zip file contents
*
* @param string $file
* @param string $specific_entry regular expression to match a file
* @return array ($error_message, $file_data); $error_message
* is empty if no error
*/
function PMA_getZipContents($file)
function PMA_getZipContents($file, $specific_entry = null)
{
$error_message = '';
$file_data = '';
@ -28,11 +28,15 @@ function PMA_getZipContents($file)
$read = zip_entry_read($first_zip_entry);
$ods_mime = 'application/vnd.oasis.opendocument.spreadsheet';
if (!strcmp($ods_mime, $read)) {
$specific_entry = '/^content\.xml$/';
}
if (isset($specific_entry)) {
/* Return the correct contents, not just the first entry */
for ( ; ; ) {
$entry = zip_read($zip_handle);
if (is_resource($entry)) {
if (!strcmp('content.xml', zip_entry_name($entry))) {
if (preg_match($specific_entry, zip_entry_name($entry))) {
zip_entry_open($zip_handle, $entry, 'r');
$file_data = zip_entry_read($entry, zip_entry_filesize($entry));
zip_entry_close($entry);
@ -41,15 +45,15 @@ function PMA_getZipContents($file)
} else {
/**
* Either we have reached the end of the zip and still
* haven't found 'content.xml' or there was a parsing
* haven't found $specific_entry or there was a parsing
* error that we must display
*/
if ($entry === false) {
$error_message = __('Error in ZIP archive:') . ' Could not find "content.xml"';
$error_message = __('Error in ZIP archive:') . ' Could not find "' . $specific_entry . '"';
} else {
$error_message = __('Error in ZIP archive:') . ' ' . PMA_getZipError($zip_handle);
}
break;
}
}
@ -68,6 +72,69 @@ function PMA_getZipContents($file)
return (array('error' => $error_message, 'data' => $file_data));
}
/**
* Returns the file name of the first file that matches the given $file_regexp.
*
* @param string $file_regexp regular expression for the file name to match
* @param string $file zip archive
*/
function PMA_findFileFromZipArchive ($file_regexp, $file)
{
$zip_handle = zip_open($file);
$found = false;
if (is_resource($zip_handle)) {
$entry = zip_read($zip_handle);
while (is_resource($entry)) {
if (preg_match($file_regexp, zip_entry_name($entry))) {
$file_name = zip_entry_name($entry);
zip_close($zip_handle);
return $file_name;
}
$entry = zip_read($zip_handle);
}
}
zip_close($zip_handle);
return false;
}
/**
* Returns the number of files in the zip archive.
*
* @param string $file
*/
function PMA_getNoOfFilesInZip($file)
{
$count = 0;
$zip_handle = zip_open($file);
$found = false;
if (is_resource($zip_handle)) {
$entry = zip_read($zip_handle);
while (is_resource($entry)) {
$count++;
$entry = zip_read($zip_handle);
}
}
zip_close($zip_handle);
return $count;
}
/**
* Extracts a set of files from the given zip archive to a given destinations.
*
* @param string $zip_path
* @param string $destination
* @param array $entries
*/
function PMA_zipExtract($zip_path, $destination, $entries) {
$zip = new ZipArchive;
if ($zip->open($zip_path) === true) {
$zip->extractTo($destination, $entries);
$zip->close();
return true;
}
return false;
}
/**
* Gets zip error message
*

View File

@ -18,6 +18,15 @@ $GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js';
$GLOBALS['js_include'][] = 'jquery/timepicker.js';
$GLOBALS['js_include'][] = 'tbl_change.js';
// required for GIS editor loaded via AJAX
$GLOBALS['js_include'][] = 'gis_data_editor.js';
$GLOBALS['js_include'][] = 'jquery/jquery.svg.js';
$GLOBALS['js_include'][] = 'jquery/jquery.mousewheel.js';
$GLOBALS['js_include'][] = 'jquery/jquery.event.drag-2.0.min.js';
$GLOBALS['js_include'][] = 'tbl_gis_visualization.js';
$GLOBALS['js_include'][] = 'openlayers/OpenLayers.js';
$GLOBALS['js_include'][] = 'OpenStreetMap.js';
if (isset($_SESSION['profiling'])) {
$GLOBALS['js_include'][] = 'highcharts/highcharts.js';
/* Files required for chart exporting */

View File

@ -118,6 +118,16 @@ $GLOBALS['js_include'][] = 'functions.js';
$GLOBALS['js_include'][] = 'tbl_change.js';
$GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js';
$GLOBALS['js_include'][] = 'jquery/timepicker.js';
// required for GIS editor
$GLOBALS['js_include'][] = 'gis_data_editor.js';
$GLOBALS['js_include'][] = 'jquery/jquery.svg.js';
$GLOBALS['js_include'][] = 'jquery/jquery.mousewheel.js';
$GLOBALS['js_include'][] = 'jquery/jquery.event.drag-2.0.min.js';
$GLOBALS['js_include'][] = 'tbl_gis_visualization.js';
$GLOBALS['js_include'][] = 'openlayers/OpenLayers.js';
$GLOBALS['js_include'][] = 'OpenStreetMap.js';
/**
* HTTP and HTML headers
*/
@ -472,6 +482,9 @@ foreach ($rows as $row_id => $vrow) {
<?php } //End if
// Get a list of GIS data types.
$gis_data_types = PMA_getGISDatatypes();
// Prepares the field value
$real_null_value = false;
$special_chars_encoded = '';
@ -484,6 +497,10 @@ foreach ($rows as $row_id => $vrow) {
$data = $vrow[$field['Field']];
} elseif ($field['True_Type'] == 'bit') {
$special_chars = PMA_printable_bit_value($vrow[$field['Field']], $extracted_fieldspec['spec_in_brackets']);
} elseif (in_array($field['True_Type'], $gis_data_types)) {
// Convert gis data to Well Know Text format
$vrow[$field['Field']] = PMA_asWKT($vrow[$field['Field']], true);
$special_chars = htmlspecialchars($vrow[$field['Field']]);
} else {
// special binary "characters"
if ($field['is_binary'] || ($field['is_blob'] && ! $cfg['ProtectBinary'])) {
@ -897,7 +914,6 @@ foreach ($rows as $row_id => $vrow) {
}
} // end if (web-server upload directory)
} // end elseif (binary or blob)
elseif (in_array($field['pma_type'], $no_support_types)) {
// ignore this column to avoid changing it
} else {
@ -965,6 +981,21 @@ foreach ($rows as $row_id => $vrow) {
}
}
}
if (in_array($field['pma_type'], $gis_data_types)) {
$data_val = isset($vrow[$field['Field']]) ? $vrow[$field['Field']] : '';
$_url_params = array(
'field' => $field['Field_title'],
'value' => $data_val,
);
if ($field['pma_type'] != 'geometry') {
$_url_params = $_url_params + array('gis_data[gis_type]' => strtoupper($field['pma_type']));
}
$edit_url = 'gis_data_editor.php' . PMA_generate_common_url($_url_params);
$edit_str = PMA_getIcon('b_edit.png', __('Edit/Insert'), true);
echo('<span class="open_gis_editor">');
echo(PMA_linkOrButton($edit_url, $edit_str, array(), false, false, '_blank'));
echo('</span>');
}
?>
</td>
</tr>
@ -975,8 +1006,8 @@ foreach ($rows as $row_id => $vrow) {
echo ' </tbody></table><br />';
} // end foreach on multi-edit
?>
<div id="gis_editor"></div><div id="popup_background"></div>
<br />
<fieldset id="actions_panel">
<table border="0" cellpadding="5" cellspacing="0">
<tr>

View File

@ -20,6 +20,7 @@ $GLOBALS['js_include'][] = 'jquery/jquery.svg.js';
$GLOBALS['js_include'][] = 'jquery/jquery.mousewheel.js';
$GLOBALS['js_include'][] = 'jquery/jquery.event.drag-2.0.min.js';
$GLOBALS['js_include'][] = 'tbl_gis_visualization.js';
$GLOBALS['js_include'][] = 'OpenStreetMap.js';
// Allows for resending headers even after sending some data
ob_start();
@ -63,7 +64,7 @@ if (! isset($visualizationSettings['spatialColumn'])) {
}
// Convert geometric columns from bytes to text.
$modified_query = PMA_GIS_modify_query($sql_query, $visualizationSettings);
$modified_query = PMA_GIS_modifyQuery($sql_query, $visualizationSettings);
$modified_result = PMA_DBI_try_query($modified_query);
$data = array();
@ -89,7 +90,7 @@ if (isset($_REQUEST['saveToFile'])) {
}
$save_format = $_REQUEST['fileFormat'];
PMA_GIS_save_to_file($data, $visualizationSettings, $save_format, $file_name);
PMA_GIS_saveToFile($data, $visualizationSettings, $save_format, $file_name);
exit();
}
@ -97,7 +98,7 @@ $svg_support = (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER <= 8) ? fal
$format = $svg_support ? 'svg' : 'png';
// get the chart and settings after chart generation
$visualization = PMA_GIS_visualization_results($data, $visualizationSettings, $format);
$visualization = PMA_GIS_visualizationResults($data, $visualizationSettings, $format);
/**
* Displays the page
@ -115,39 +116,9 @@ $visualization = PMA_GIS_visualization_results($data, $visualizationSettings, $f
<div id="openlayersmap"></div>
<input type="hidden" id="pmaThemeImage" value="<?php echo($GLOBALS['pmaThemeImage']); ?>" />
<script type="text/javascript" src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js"></script>
<script language="javascript" type="text/javascript">
function drawOpenLayers() {
var options = {
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
units: "m",
numZoomLevels: 18,
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508),
restrictedExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508)
};
var map = new OpenLayers.Map('openlayersmap', options);
// create OSM layer
var layerNone = new OpenLayers.Layer.Boxes("None", {isBaseLayer: true});
var layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
var layerOsmarender = new OpenLayers.Layer.OSM.Osmarender("Osmarender");
var layerCycleMap = new OpenLayers.Layer.OSM.CycleMap("CycleMap");
map.addLayers([layerMapnik, layerOsmarender, layerCycleMap, layerNone]);
// create a vector layer
var vectorLayer = new OpenLayers.Layer.Vector("Data");
var bound;
<?php echo (PMA_GIS_visualization_results($data, $visualizationSettings, 'ol')); ?>
map.addLayer(vectorLayer);
map.zoomToExtent(bound);
if (map.getZoom() < 2) {
map.zoomTo(2);
}
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition());
<?php echo (PMA_GIS_visualizationResults($data, $visualizationSettings, 'ol')); ?>
}
</script>

View File

@ -153,6 +153,28 @@ $func_optional_param = array(
'UNIX_TIMESTAMP',
);
$gis_from_text_functions = array(
'GeomFromText',
'GeomCollFromText',
'LineFromText',
'MLineFromText',
'PointFromText',
'MPointFromText',
'PolyFromText',
'MPolyFromText',
);
$gis_from_wkb_functions = array(
'GeomFromWKB',
'GeomCollFromWKB',
'LineFromWKB',
'MLineFromWKB',
'PointFromWKB',
'MPointFromWKB',
'PolyFromWKB',
'MPolyFromWKB',
);
foreach ($loop_array as $rownumber => $where_clause) {
// skip fields to be ignored
if (! $using_key && isset($_REQUEST['insert_ignore_' . $where_clause])) {
@ -238,10 +260,19 @@ foreach ($loop_array as $rownumber => $where_clause) {
/* This way user will know what UUID new row has */
$uuid = PMA_DBI_fetch_value('SELECT UUID()');
$cur_value = "'" . $uuid . "'";
} elseif (!in_array($me_funcs[$key], $func_no_param)
} elseif ((in_array($me_funcs[$key], $gis_from_text_functions)
&& substr($val, 0, 3) == "'''")
|| in_array($me_funcs[$key], $gis_from_wkb_functions)
) {
// Remove enclosing apostrophes
$val = substr($val, 1, strlen($val) - 2);
// Remove escaping apostrophes
$val = str_replace("''", "'", $val);
$cur_value = $me_funcs[$key] . '(' . $val . ')';
} elseif (! in_array($me_funcs[$key], $func_no_param)
|| ($val != "''" && in_array($me_funcs[$key], $func_optional_param))) {
$cur_value = $me_funcs[$key] . '(' . $val . ')';
} else {
} else {
$cur_value = $me_funcs[$key] . '()';
}

View File

@ -24,8 +24,18 @@ $GLOBALS['js_include'][] = 'tbl_change.js';
$GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js';
$GLOBALS['js_include'][] = 'jquery/timepicker.js';
// required for GIS editor loaded via AJAX
$GLOBALS['js_include'][] = 'gis_data_editor.js';
$GLOBALS['js_include'][] = 'jquery/jquery.svg.js';
$GLOBALS['js_include'][] = 'jquery/jquery.mousewheel.js';
$GLOBALS['js_include'][] = 'jquery/jquery.event.drag-2.0.min.js';
$GLOBALS['js_include'][] = 'tbl_gis_visualization.js';
$GLOBALS['js_include'][] = 'openlayers/OpenLayers.js';
$GLOBALS['js_include'][] = 'OpenStreetMap.js';
$titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaThemeImage);
$geom_types = PMA_getGISDatatypes();
/**
* Not selection yet required -> displays the selection form
*/
@ -52,8 +62,7 @@ if (! isset($param) || $param[0] == '') {
$err_url = $goto . '?' . PMA_generate_common_url($db, $table);
// Gets the list and number of fields
list($fields_list, $fields_type, $fields_collation, $fields_null) = PMA_tbl_getFields($table,$db);
list($fields_list, $fields_type, $fields_collation, $fields_null, $geom_column_present) = PMA_tbl_getFields($table,$db);
$fields_cnt = count($fields_list);
// retrieve keys into foreign fields, if any
@ -82,7 +91,7 @@ echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params);
<fieldset id="fieldset_table_qbe">
<legend><?php echo __('Do a "query by example" (wildcard: "%")') ?></legend>
<table class="data">
<?php echo PMA_tbl_setTableHeader(); ?>
<?php echo PMA_tbl_setTableHeader($geom_column_present); ?>
<tbody>
<?php
$odd_row = true;
@ -90,6 +99,27 @@ echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params);
for ($i = 0; $i < $fields_cnt; $i++) {
?>
<tr class="noclick <?php echo $odd_row ? 'odd' : 'even'; $odd_row = ! $odd_row; ?>">
<?php
// if 'Function' column is present
if ($geom_column_present) {
echo('<td>');
// if a geometry column
if (in_array($fields_type[$i], $geom_types)) {
echo('<select class="geom_func" name="geom_func['. $i .']">');
// get the relevant list of functions
$funcs = PMA_getGISFunctions($fields_type[$i], true, true);
foreach ($funcs as $func_name => $func) {
$name = isset($func['display']) ? $func['display'] : $func_name;
echo('<option value="' . htmlspecialchars($name) . '">'
. htmlspecialchars($name) . '</option>');
}
echo('</select>');
} else {
echo('&nbsp;');
}
echo('</td>');
}
?>
<th><?php echo htmlspecialchars($fields_list[$i]); ?></th>
<td><?php echo $fields_type[$i]; ?></td>
<td><?php echo $fields_collation[$i]; ?></td>
@ -131,8 +161,8 @@ echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params);
$foreignData = PMA_getForeignData($foreigners, $field, false, '', '');
echo PMA_getForeignFields_Values($foreigners, $foreignData, $field, $fields_type, $i, $db, $table, $titles,$GLOBALS['cfg']['ForeignKeyMaxLimit'], '' );
echo PMA_getForeignFields_Values($foreigners, $foreignData, $field, $fields_type, $i, $db, $table, $titles,$GLOBALS['cfg']['ForeignKeyMaxLimit'], '', true);
?>
<input type="hidden" name="names[<?php echo $i; ?>]"
value="<?php echo htmlspecialchars($fields_list[$i]); ?>" />
@ -147,6 +177,7 @@ echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params);
?>
</tbody>
</table>
<div id="gis_editor"></div><div id="popup_background"></div>
</fieldset>
<?php
PMA_generate_slider_effect('searchoptions', __('Options'));
@ -228,7 +259,6 @@ echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params);
* Selection criteria have been submitted -> do the work
*/
else {
echo "ZZ";
// Builds the query
$sql_query = 'SELECT ' . (isset($distinct) ? 'DISTINCT ' : '');
@ -258,14 +288,16 @@ else {
$cnt_func = count($func);
reset($func);
while (list($i, $func_type) = each($func)) {
list($charsets[$i]) = explode('_', $collations[$i]);
list($charsets[$i]) = explode('_', $collations[$i]);
$unaryFlag = (isset($GLOBALS['cfg']['UnaryOperators'][$func_type]) && $GLOBALS['cfg']['UnaryOperators'][$func_type] == 1) ? true : false;
$whereClause = PMA_tbl_search_getWhereClause($fields[$i],$names[$i], $types[$i], $collations[$i], $func_type, $unaryFlag);
if($whereClause)
$w[] = $whereClause;
} // end for
$tmp_geom_func = isset($geom_func[$i]) ? $geom_func[$i] : null;
$whereClause = PMA_tbl_search_getWhereClause($fields[$i],$names[$i], $types[$i], $collations[$i], $func_type, $unaryFlag, $tmp_geom_func);
if($whereClause)
$w[] = $whereClause;
} // end for
//print_r($w);
if ($w) {
$sql_query .= ' WHERE ' . implode(' AND ', $w);
@ -278,4 +310,4 @@ else {
require './sql.php';
}
?>
?>

View File

@ -0,0 +1,80 @@
<?php
/**
* Test for PMA_GIS_Factory
*
* @package phpMyAdmin-test
*/
require_once 'libraries/gis/pma_gis_geometry.php';
require_once 'libraries/gis/pma_gis_linestring.php';
require_once 'libraries/gis/pma_gis_multilinestring.php';
require_once 'libraries/gis/pma_gis_point.php';
require_once 'libraries/gis/pma_gis_multipoint.php';
require_once 'libraries/gis/pma_gis_polygon.php';
require_once 'libraries/gis/pma_gis_multipolygon.php';
require_once 'libraries/gis/pma_gis_geometrycollection.php';
/*
* Include to test
*/
require_once 'libraries/gis/pma_gis_factory.php';
/**
* Test class for PMA_GIS_Factory
*/
class PMA_GIS_FactoryTest extends PHPUnit_Framework_TestCase
{
/**
* Test factory method
*
* @param string $type geometry type
* @param object $geom geometry object
*
* @dataProvider providerForTestFactory
* @return nothing
*/
public function testFactory($type, $geom)
{
$this->assertInstanceOf($geom, PMA_GIS_Factory::factory($type));
}
/**
* data provider for testFactory
*
* @return data for testFactory
*/
public function providerForTestFactory()
{
return array(
array(
'MULTIPOLYGON',
'PMA_GIS_Multipolygon'
),
array(
'POLYGON',
'PMA_GIS_Polygon'
),
array(
'MULTILINESTRING',
'PMA_GIS_Multilinestring'
),
array(
'LINESTRING',
'PMA_GIS_Linestring'
),
array(
'MULTIPOINT',
'PMA_GIS_Multipoint'
),
array(
'POINT',
'PMA_GIS_Point'
),
array(
'GEOMETRYCOLLECTION',
'PMA_GIS_Geometrycollection'
),
);
}
}
?>

View File

@ -0,0 +1,60 @@
<?php
/**
* Abstract parent class for all PMA_GIS_<Geom_type> test classes
*
* @package phpMyAdmin-test
*/
require_once 'libraries/gis/pma_gis_geometry.php';
/**
* Abstract parent class for all PMA_GIS_<Geom_type> test classes
*/
abstract class PMA_GIS_GeometryTest extends PHPUnit_Framework_TestCase
{
/**
* test generateWkt method
*
* @param array $gis_data array of GIS data
* @param int $index index
* @param string $empty string to be insterted in place of missing values
* @param string $wkt expected WKT
*
* @return nothing
* @dataProvider providerForTestGenerateWkt
*/
public function testGenerateWkt($gis_data, $index, $empty, $wkt)
{
if ($empty == null) {
$this->assertEquals($this->object->generateWkt($gis_data, $index), $wkt);
} else {
$this->assertEquals(
$this->object->generateWkt($gis_data, $index, $empty),
$wkt
);
}
}
/**
* test generateParams method
*
* @param string $wkt point in WKT form
* @param index $index index
* @param array $params expected output array
*
* @dataProvider providerForTestGenerateParams
* @return nothing
*/
public function testGenerateParams($wkt, $index, $params)
{
if ($index == null) {
$this->assertEquals($this->object->generateParams($wkt), $params);
} else {
$this->assertEquals(
$this->object->generateParams($wkt, $index),
$params
);
}
}
}
?>

View File

@ -0,0 +1,142 @@
<?php
/**
* Test for PMA_GIS_Linestring
*
* @package phpMyAdmin-test
*/
require_once 'PMA_GIS_Geometry_test.php';
require_once 'libraries/gis/pma_gis_geometry.php';
require_once 'libraries/gis/pma_gis_linestring.php';
/**
* Tests for PMA_GIS_Linestring class
*/
class PMA_GIS_LinestringTest extends PMA_GIS_GeometryTest
{
/**
* @var PMA_GIS_Linestring
* @access protected
*/
protected $object;
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*
* @access protected
* @return nothing
*/
protected function setUp()
{
$this->object = PMA_GIS_Linestring::singleton();
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*
* @access protected
* @return nothing
*/
protected function tearDown()
{
unset($this->object);
}
/**
* data provider for testGenerateWkt
*
* @return data for testGenerateWkt
*/
public function providerForTestGenerateWkt()
{
$temp1 = array(
0 => array(
'LINESTRING' => array(
'no_of_points' => 2,
0 => array('x' => 5.02, 'y' => 8.45),
1 => array('x' => 6.14, 'y' => 0.15)
)
)
);
$temp2 = $temp1;
$temp2[0]['LINESTRING']['no_of_points'] = 3;
$temp2[0]['LINESTRING'][2] = array('x' => 1.56);
$temp3 = $temp2;
$temp3[0]['LINESTRING']['no_of_points'] = -1;
$temp4 = $temp3;
$temp4[0]['LINESTRING']['no_of_points'] = 3;
unset($temp4[0]['LINESTRING'][2]['x']);
return array(
array(
$temp1,
0,
null,
'LINESTRING(5.02 8.45,6.14 0.15)'
),
// if a coordinate is missing, default is empty string
array(
$temp2,
0,
null,
'LINESTRING(5.02 8.45,6.14 0.15,1.56 )'
),
// if no_of_points is not valid, it is considered as 2
array(
$temp3,
0,
null,
'LINESTRING(5.02 8.45,6.14 0.15)'
),
// missing coordinates are replaced with provided values (3rd parameter)
array(
$temp4,
0,
'0',
'LINESTRING(5.02 8.45,6.14 0.15,0 0)'
)
);
}
/**
* data provider for testGenerateParams
*
* @return data for testGenerateParams
*/
public function providerForTestGenerateParams()
{
$temp = array(
'LINESTRING' => array(
'no_of_points' => 2,
0 => array('x' => '5.02', 'y' => '8.45'),
1 => array('x' => '6.14', 'y' => '0.15')
)
);
$temp1 = $temp;
$temp1['gis_type'] = 'LINESTRING';
return array(
array(
"'LINESTRING(5.02 8.45,6.14 0.15)',124",
null,
array(
'srid' => '124',
0 => $temp
)
),
array(
'LINESTRING(5.02 8.45,6.14 0.15)',
2,
array(
2 => $temp1
)
)
);
}
}
?>

View File

@ -0,0 +1,182 @@
<?php
/**
* Test for PMA_GIS_Multilinestring
*
* @package phpMyAdmin-test
*/
require_once 'PMA_GIS_Geometry_test.php';
require_once 'libraries/gis/pma_gis_geometry.php';
require_once 'libraries/gis/pma_gis_multilinestring.php';
/**
* Tests for PMA_GIS_Multilinestring class
*/
class PMA_GIS_MultilinestringTest extends PMA_GIS_GeometryTest
{
/**
* @var PMA_GIS_Multilinestring
* @access protected
*/
protected $object;
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*
* @access protected
* @return nothing
*/
protected function setUp()
{
$this->object = PMA_GIS_Multilinestring::singleton();
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*
* @access protected
* @return nothing
*/
protected function tearDown()
{
unset($this->object);
}
/**
* data provider for testGenerateWkt
*
* @return data for testGenerateWkt
*/
public function providerForTestGenerateWkt()
{
$temp = array(
0 => array(
'MULTILINESTRING' => array(
'no_of_lines' => 2,
0 => array(
'no_of_points' => 2,
0 => array('x' => 5.02, 'y' => 8.45),
1 => array('x' => 6.14, 'y' => 0.15)
),
1 => array(
'no_of_points' => 2,
0 => array('x' => 1.23, 'y' => 4.25),
1 => array('x' => 9.15, 'y' => 0.47)
)
)
)
);
$temp1 = $temp;
unset($temp1[0]['MULTILINESTRING'][1][1]['y']);
return array(
array(
$temp,
0,
null,
'MULTILINESTRING((5.02 8.45,6.14 0.15),(1.23 4.25,9.15 0.47))'
),
// values at undefined index
array(
$temp,
1,
null,
'MULTILINESTRING(( , ))'
),
// if a coordinate is missing, default is empty string
array(
$temp1,
0,
null,
'MULTILINESTRING((5.02 8.45,6.14 0.15),(1.23 4.25,9.15 ))'
),
// missing coordinates are replaced with provided values (3rd parameter)
array(
$temp1,
0,
'0',
'MULTILINESTRING((5.02 8.45,6.14 0.15),(1.23 4.25,9.15 0))'
)
);
}
/**
* test getShape method
*
* @return nothing
*/
public function testGetShape()
{
$row_data = array(
'numparts' => 2,
'parts' => array(
0 => array(
'points' => array(
0 => array('x' => 5.02, 'y' => 8.45),
1 => array('x' => 6.14, 'y' => 0.15),
),
),
1 => array(
'points' => array(
0 => array('x' => 1.23, 'y' => 4.25),
1 => array('x' => 9.15, 'y' => 0.47),
),
),
),
);
$this->assertEquals(
$this->object->getShape($row_data),
'MULTILINESTRING((5.02 8.45,6.14 0.15),(1.23 4.25,9.15 0.47))'
);
}
/**
* data provider for testGenerateParams
*
* @return data for testGenerateParams
*/
public function providerForTestGenerateParams()
{
$temp = array(
'MULTILINESTRING' => array(
'no_of_lines' => 2,
0 => array(
'no_of_points' => 2,
0 => array('x' => 5.02, 'y' => 8.45),
1 => array('x' => 6.14, 'y' => 0.15),
),
1 => array(
'no_of_points' => 2,
0 => array('x' => 1.23, 'y' => 4.25),
1 => array('x' => 9.15, 'y' => 0.47),
)
)
);
$temp1 = $temp;
$temp1['gis_type'] = 'MULTILINESTRING';
return array(
array(
"'MULTILINESTRING((5.02 8.45,6.14 0.15),(1.23 4.25,9.15 0.47))',124",
null,
array(
'srid' => '124',
0 => $temp
)
),
array(
'MULTILINESTRING((5.02 8.45,6.14 0.15),(1.23 4.25,9.15 0.47))',
2,
array(
2 => $temp1
)
)
);
}
}
?>

View File

@ -0,0 +1,146 @@
<?php
/**
* Test for PMA_GIS_Multipoint
*
* @package phpMyAdmin-test
*/
require_once 'PMA_GIS_Geometry_test.php';
require_once 'libraries/gis/pma_gis_geometry.php';
require_once 'libraries/gis/pma_gis_multipoint.php';
/**
* Tests for PMA_GIS_Multipoint class
*/
class PMA_GIS_MultipointTest extends PMA_GIS_GeometryTest
{
/**
* @var PMA_GIS_Multipoint
* @access protected
*/
protected $object;
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*
* @access protected
* @return nothing
*/
protected function setUp()
{
$this->object = PMA_GIS_Multipoint::singleton();
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*
* @access protected
* @return nothing
*/
protected function tearDown()
{
unset($this->object);
}
/**
* data provider for testGenerateWkt
*
* @return data for testGenerateWkt
*/
public function providerForTestGenerateWkt()
{
$gis_data1 = array(
0 => array(
'MULTIPOINT' => array(
'no_of_points' => 2,
0 => array(
'x' => 5.02,
'y' => 8.45
),
1 => array(
'x' => 1.56,
'y' => 4.36
)
)
)
);
$gis_data2 = $gis_data1;
$gis_data2[0]['MULTIPOINT']['no_of_points'] = -1;
return array(
array(
$gis_data1,
0,
null,
'MULTIPOINT(5.02 8.45,1.56 4.36)'
),
array(
$gis_data2,
0,
null,
'MULTIPOINT(5.02 8.45)'
)
);
}
/**
* test getShape method
*
* @return nothing
*/
public function testGetShape()
{
$gis_data = array(
'numpoints' => 2,
'points' => array(
0 => array('x' => 5.02, 'y' => 8.45),
1 => array('x' => 6.14, 'y' => 0.15)
)
);
$this->assertEquals(
$this->object->getShape($gis_data),
'MULTIPOINT(5.02 8.45,6.14 0.15)'
);
}
/**
* data provider for testGenerateParams
*
* @return data for testGenerateParams
*/
public function providerForTestGenerateParams()
{
$temp1 = array(
'MULTIPOINT' => array(
'no_of_points' => 2,
0 => array('x' => '5.02', 'y' => '8.45'),
1 => array('x' => '6.14', 'y' => '0.15')
)
);
$temp2 = $temp1;
$temp2['gis_type'] = 'MULTIPOINT';
return array(
array(
"'MULTIPOINT(5.02 8.45,6.14 0.15)',124",
null,
array(
'srid' => '124',
0 => $temp1
)
),
array(
'MULTIPOINT(5.02 8.45,6.14 0.15)',
2,
array(
2 => $temp2
)
)
);
}
}
?>

View File

@ -0,0 +1,139 @@
<?php
/**
* Test for PMA_GIS_Multipolygon
*
* @package phpMyAdmin-test
*/
require_once 'PMA_GIS_Geometry_test.php';
require_once 'libraries/gis/pma_gis_geometry.php';
require_once 'libraries/gis/pma_gis_multipolygon.php';
/**
* Tests for PMA_GIS_Multipolygon class
*/
class PMA_GIS_MultipolygonTest extends PMA_GIS_GeometryTest
{
/**
* @var PMA_GIS_Multipolygon
* @access protected
*/
protected $object;
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*
* @access protected
* @return nothing
*/
protected function setUp()
{
$this->object = PMA_GIS_Multipolygon::singleton();
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*
* @access protected
* @return nothing
*/
protected function tearDown()
{
unset($this->object);
}
private function _getData()
{
return array(
'MULTIPOLYGON' => array(
'no_of_polygons' => 2,
0 => array(
'no_of_lines' => 2,
0 => array(
'no_of_points' => 5,
0 => array('x' => 35, 'y' => 10),
1 => array('x' => 10, 'y' => 20),
2 => array('x' => 15, 'y' => 40),
3 => array('x' => 45, 'y' => 45),
4 => array('x' => 35, 'y' => 10),
),
1 => array(
'no_of_points' => 4,
0 => array('x' => 20, 'y' => 30),
1 => array('x' => 35, 'y' => 32),
2 => array('x' => 30, 'y' => 20),
3 => array('x' => 20, 'y' => 30),
)
),
1 => array(
'no_of_lines' => 1,
0 => array(
'no_of_points' => 4,
0 => array('x' => 123, 'y' => 0),
1 => array('x' => 23, 'y' => 30),
2 => array('x' => 17, 'y' => 63),
3 => array('x' => 123, 'y' => 0),
)
)
)
);
}
/**
* data provider for testGenerateWkt
*
* @return data for testGenerateWkt
*/
public function providerForTestGenerateWkt()
{
$temp = array(
0 => $this->_getData()
);
return array(
array(
$temp,
0,
null,
'MULTIPOLYGON(((35 10,10 20,15 40,45 45,35 10)'
. ',(20 30,35 32,30 20,20 30)),((123 0,23 30,17 63,123 0)))'
),
);
}
/**
* data provider for testGenerateParams
*
* @return data for testGenerateParams
*/
public function providerForTestGenerateParams()
{
$temp = $this->_getData();
$temp1 = $this->_getData();
$temp1['gis_type'] = 'MULTIPOLYGON';
return array(
array(
"'MULTIPOLYGON(((35 10,10 20,15 40,45 45,35 10),"
. "(20 30,35 32,30 20,20 30)),((123 0,23 30,17 63,123 0)))',124",
null,
array(
'srid' => '124',
0 => $temp
)
),
array(
'MULTIPOLYGON(((35 10,10 20,15 40,45 45,35 10)'
. ',(20 30,35 32,30 20,20 30)),((123 0,23 30,17 63,123 0)))',
2,
array(
2 => $temp1
)
)
);
}
}
?>

View File

@ -0,0 +1,148 @@
<?php
/**
* Test for PMA_GIS_Point
*
* @package phpMyAdmin-test
*/
require_once 'PMA_GIS_Geometry_test.php';
require_once 'libraries/gis/pma_gis_geometry.php';
require_once 'libraries/gis/pma_gis_point.php';
/**
* Tests for PMA_GIS_Point class.
*/
class PMA_GIS_PointTest extends PMA_GIS_GeometryTest
{
/**
* @var PMA_GIS_Point
* @access protected
*/
protected $object;
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*
* @access protected
* @return nothing
*/
protected function setUp()
{
$this->object = PMA_GIS_Point::singleton();
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*
* @access protected
* @return nothing
*/
protected function tearDown()
{
unset($this->object);
}
/**
* data provider for testGenerateWkt
*
* @return data for testGenerateWkt
*/
public function providerForTestGenerateWkt()
{
return array(
array(
array(0 => array('POINT' => array('x' => 5.02, 'y' => 8.45))),
0,
null,
'POINT(5.02 8.45)'
),
array(
array(0 => array('POINT' => array('x' => 5.02, 'y' => 8.45))),
1,
null,
'POINT( )'
),
array(
array(0 => array('POINT' => array('x' => 5.02))),
0,
null,
'POINT(5.02 )'
),
array(
array(0 => array('POINT' => array('y' => 8.45))),
0,
null,
'POINT( 8.45)'
),
array(
array(0 => array('POINT' => array())),
0,
null,
'POINT( )'
),
);
}
/**
* test getShape method
*
* @param array $row_data array of GIS data
* @param string $shape expected shape in WKT
*
* @dataProvider providerForTestGetShape
* @return nothing
*/
public function testGetShape($row_data, $shape)
{
$this->assertEquals($this->object->getShape($row_data), $shape);
}
/**
* data provider for testGetShape
*
* @return data for testGetShape
*/
public function providerForTestGetShape()
{
return array(
array(
array('x' => 5.02, 'y' => 8.45),
'POINT(5.02 8.45)'
)
);
}
/**
* data provider for testGenerateParams
*
* @return data for testGenerateParams
*/
public function providerForTestGenerateParams()
{
return array(
array(
"'POINT(5.02 8.45)',124",
null,
array(
'srid' => '124',
0 => array(
'POINT' => array('x' => '5.02', 'y' => '8.45')
),
)
),
array(
'POINT(5.02 8.45)',
2,
array(
2 => array(
'gis_type' => 'POINT',
'POINT' => array('x' => '5.02', 'y' => '8.45')
),
)
)
);
}
}
?>

View File

@ -0,0 +1,299 @@
<?php
/**
* Test for PMA_GIS_Polygon
*
* @package phpMyAdmin-test
*/
require_once 'PMA_GIS_Geometry_test.php';
require_once 'libraries/gis/pma_gis_geometry.php';
require_once 'libraries/gis/pma_gis_polygon.php';
/**
* Tests for PMA_GIS_Polygon class
*/
class PMA_GIS_PolygonTest extends PMA_GIS_GeometryTest
{
/**
* @var PMA_GIS_Polygon
* @access protected
*/
protected $object;
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*
* @access protected
* @return nothing
*/
protected function setUp()
{
$this->object = PMA_GIS_Polygon::singleton();
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*
* @access protected
* @return nothing
*/
protected function tearDown()
{
unset($this->object);
}
private function _getData()
{
return array(
'POLYGON' => array(
'no_of_lines' => 2,
0 => array(
'no_of_points' => 5,
0 => array('x' => 35, 'y' => 10),
1 => array('x' => 10, 'y' => 20),
2 => array('x' => 15, 'y' => 40),
3 => array('x' => 45, 'y' => 45),
4 => array('x' => 35, 'y' => 10),
),
1 => array(
'no_of_points' => 4,
0 => array('x' => 20, 'y' => 30),
1 => array('x' => 35, 'y' => 32),
2 => array('x' => 30, 'y' => 20),
3 => array('x' => 20, 'y' => 30),
)
)
);
}
/**
* data provider for testGenerateWkt
*
* @return data for testGenerateWkt
*/
public function providerForTestGenerateWkt()
{
$temp = array(
0 => $this->_getData()
);
$temp1 = $temp;
unset($temp1[0]['POLYGON'][1][3]['y']);
return array(
array(
$temp,
0,
null,
'POLYGON((35 10,10 20,15 40,45 45,35 10),(20 30,35 32,30 20,20 30))'
),
// values at undefined index
array(
$temp,
1,
null,
'POLYGON(( , , , ))'
),
// if a coordinate is missing, default is empty string
array(
$temp1,
0,
null,
'POLYGON((35 10,10 20,15 40,45 45,35 10),(20 30,35 32,30 20,20 ))'
),
// missing coordinates are replaced with provided values (3rd parameter)
array(
$temp1,
0,
'0',
'POLYGON((35 10,10 20,15 40,45 45,35 10),(20 30,35 32,30 20,20 0))'
)
);
}
/**
* data provider for testGenerateParams
*
* @return data for testGenerateParams
*/
public function providerForTestGenerateParams()
{
$temp = $this->_getData();
$temp1 = $temp;
$temp1['gis_type'] = 'POLYGON';
return array(
array(
"'POLYGON((35 10,10 20,15 40,45 45,35 10),(20 30,35 32,30 20,20 30))',124",
null,
array(
'srid' => '124',
0 => $temp
)
),
array(
'POLYGON((35 10,10 20,15 40,45 45,35 10),(20 30,35 32,30 20,20 30))',
2,
array(
2 => $temp1
)
)
);
}
/**
* test for Area
*
* @param array $ring array of points forming the ring
* @param fload $area area of the ring
*
* @dataProvider providerForTestArea
* @return nothing
*/
public function testArea($ring, $area)
{
$this->assertEquals($this->object->area($ring), $area);
}
/**
* data provider for testArea
*
* @return data for testArea
*/
public function providerForTestArea()
{
return array(
array(
array(
0 => array('x' => 35, 'y' => 10),
1 => array('x' => 10, 'y' => 10),
2 => array('x' => 15, 'y' => 40)
),
-375.00
),
// first point of the ring repeated as the last point
array(
array(
0 => array('x' => 35, 'y' => 10),
1 => array('x' => 10, 'y' => 10),
2 => array('x' => 15, 'y' => 40),
3 => array('x' => 35, 'y' => 10)
),
-375.00
),
// anticlockwise gives positive area
array(
array(
0 => array('x' => 15, 'y' => 40),
1 => array('x' => 10, 'y' => 10),
2 => array('x' => 35, 'y' => 10)
),
375.00
)
);
}
/**
* test for isPointInsidePolygon
*
* @param array $point x, y coordinates of the point
* @param array $polygon array of points forming the ring
* @param bool $isInside output
*
* @dataProvider providerForTestIsPointInsidePolygon
* @return nothing
*/
public function testIsPointInsidePolygon($point, $polygon, $isInside)
{
$this->assertEquals(
$this->object->isPointInsidePolygon($point, $polygon),
$isInside
);
}
/**
* data provider for testIsPointInsidePolygon
*
* @return data for testIsPointInsidePolygon
*/
public function providerForTestIsPointInsidePolygon()
{
$ring = array(
0 => array('x' => 35, 'y' => 10),
1 => array('x' => 10, 'y' => 10),
2 => array('x' => 15, 'y' => 40),
3 => array('x' => 35, 'y' => 10)
);
return array(
// point inside the ring
array(
array('x' => 20, 'y' => 15),
$ring,
true
),
// point on an edge of the ring
array(
array('x' => 20, 'y' => 10),
$ring,
false
),
// point on a vertex of the ring
array(
array('x' => 10, 'y' => 10),
$ring,
false
),
// point outside the ring
array(
array('x' => 5, 'y' => 10),
$ring,
false
),
);
}
/**
* test for getPointOnSurface
*
* @param array $ring array of points forming the ring
*
* @dataProvider providerForTestGetPointOnSurface
* @return nothing
*/
public function testGetPointOnSurface($ring)
{
$this->assertEquals(
$this->object->isPointInsidePolygon(
$this->object->getPointOnSurface($ring),
$ring
),
true
);
}
/**
* data provider for testGetPointOnSurface
*
* @return data for testGetPointOnSurface
*/
public function providerForTestGetPointOnSurface()
{
$temp = $this->_getData();
unset($temp['POLYGON'][0]['no_of_points']);
unset($temp['POLYGON'][1]['no_of_points']);
return array(
array(
$temp['POLYGON'][0]
),
array(
$temp['POLYGON'][1]
)
);
}
}
?>

View File

@ -0,0 +1,94 @@
<?php
/**
* Tests for PMA_GIS_modifyQuery method
*
* @package phpMyAdmin-test
*/
require_once 'libraries/sqlparser.lib.php';
require_once 'libraries/common.lib.php';
/*
* Include to test
*/
require_once 'libraries/gis_visualization.lib.php';
class PMA_GIS_modifyQueryTest extends PHPUnit_Framework_TestCase
{
/**
* Test PMA_GIS_modifyQuery method
*
* @param string $sql_query query to modify
* @param array $settings visualization settings
* @param string $modified_query modified query
*
* @dataProvider provider
* @return nothing
*/
public function testModifyQuery($sql_query, $settings, $modified_query)
{
$this->assertEquals(
PMA_GIS_modifyQuery($sql_query, $settings),
$modified_query
);
}
/**
* data provider for testModifyQuery
*
* @return data for testModifyQuery
*/
public function provider()
{
return array(
// select *
array(
'SELECT * FROM `foo` WHERE `bar` = `zoo`',
array('spatialColumn' => 'moo', 'labelColumn' => 'noo'),
'SELECT `noo`, ASTEXT(`moo`) AS `moo`, SRID(`moo`) AS `srid` FROM `foo` WHERE `bar` = `zoo`'
),
// select * with no label column
array(
'SELECT * FROM `foo` WHERE `bar` = `zoo`',
array('spatialColumn' => 'moo'),
'SELECT ASTEXT(`moo`) AS `moo`, SRID(`moo`) AS `srid` FROM `foo` WHERE `bar` = `zoo`'
),
// more columns
array(
'SELECT `aaa`, `moo`, `bbb`, `noo` FROM `foo` WHERE `bar` = `zoo`',
array('spatialColumn' => 'moo', 'labelColumn' => 'noo'),
'SELECT `noo`, ASTEXT(`moo`) AS `moo`, SRID(`moo`) AS `srid` FROM `foo` WHERE `bar` = `zoo`'
),
// no labelColumn defined
array(
'SELECT `moo`, `noo` FROM `foo` WHERE `bar` = `zoo`',
array('spatialColumn' => 'moo'),
'SELECT ASTEXT(`moo`) AS `moo`, SRID(`moo`) AS `srid` FROM `foo` WHERE `bar` = `zoo`'
),
// alias for spatialColumn
array(
'SELECT `aaa` AS `moo`, `noo` FROM `foo` WHERE `bar` = `zoo`',
array('spatialColumn' => 'moo', 'labelColumn' => 'noo'),
'SELECT `noo`, ASTEXT(`aaa`) AS `moo`, SRID(`aaa`) AS `srid` FROM `foo` WHERE `bar` = `zoo`'
),
// alias for labelColumn
array(
'SELECT `moo`, `bbb` AS `noo` FROM `foo` WHERE `bar` = `zoo`',
array('spatialColumn' => 'moo', 'labelColumn' => 'noo'),
'SELECT `bbb` AS `noo`, ASTEXT(`moo`) AS `moo`, SRID(`moo`) AS `srid` FROM `foo` WHERE `bar` = `zoo`'
),
// with database names
array(
'SELECT `db`.`moo`, `db`.`noo` FROM `foo` WHERE `bar` = `zoo`',
array('spatialColumn' => 'moo', 'labelColumn' => 'noo'),
'SELECT `db`.`noo`, ASTEXT(`db`.`moo`) AS `moo`, SRID(`db`.`moo`) AS `srid` FROM `foo` WHERE `bar` = `zoo`'
),
// database names plus alias
array(
'SELECT `db`.`aaa` AS `moo`, `noo` FROM `foo` WHERE `bar` = `zoo`',
array('spatialColumn' => 'moo', 'labelColumn' => 'noo'),
'SELECT `noo`, ASTEXT(`db`.`aaa`) AS `moo`, SRID(`db`.`aaa`) AS `srid` FROM `foo` WHERE `bar` = `zoo`'
),
);
}
}
?>

View File

@ -1739,6 +1739,44 @@ input#input_import_file {
margin: 5px 0px 5px 0px;
}
/**
* GIS data editor styles
*/
a.close_gis_editor {
float: right;
}
#gis_editor {
display: none;
position: fixed;
_position: absolute; /* hack for IE */
z-index: 101;
overflow-y: auto;
overflow-x: hidden;
}
#gis_data {
min-height: 230px;
}
#gis_data_textarea {
height: 6em;
}
#gis_data_editor {
background: #D0DCE0;
padding: 15px;
min-height: 500px;
}
#gis_data_editor .choice {
display: none;
}
#gis_data_editor input[type="text"] {
width: 75px;
}
/**
* ENUM/SET editor styles
*/

View File

@ -2134,6 +2134,44 @@ input#input_import_file {
margin: 5px 0px 5px 0px;
}
/**
* GIS data editor styles
*/
a.close_gis_editor {
float: right;
}
#gis_editor {
display: none;
position: fixed;
_position: absolute; /* hack for IE */
z-index: 101;
overflow-y: auto;
overflow-x: hidden;
}
#gis_data {
min-height: 230px;
}
#gis_data_textarea {
height: 6em;
}
#gis_data_editor {
background: #D0DCE0;
padding: 15px;
min-height: 500px;
}
#gis_data_editor .choice {
display: none;
}
#gis_data_editor input[type="text"] {
width: 75px;
}
/**
* ENUM/SET editor styles
*/