1<?php 2/* vim: set expandtab sw=4 ts=4 sts=4: */ 3/** 4 * Editor for Geometry data types. 5 * 6 * @package PhpMyAdmin 7 */ 8 9use PhpMyAdmin\Core; 10use PhpMyAdmin\Gis\GisFactory; 11use PhpMyAdmin\Gis\GisVisualization; 12use PhpMyAdmin\Response; 13use PhpMyAdmin\Url; 14 15/** 16 * Escapes special characters if the variable is set. 17 * Returns an empty string otherwise. 18 * 19 * @param string $variable variable to be escaped 20 * 21 * @return string escaped variable 22 */ 23function escape($variable) 24{ 25 return isset($variable) ? htmlspecialchars($variable) : ''; 26} 27 28require_once 'libraries/common.inc.php'; 29 30if (! isset($_POST['field'])) { 31 PhpMyAdmin\Util::checkParameters(array('field')); 32} 33 34// Get data if any posted 35$gis_data = array(); 36if (Core::isValid($_POST['gis_data'], 'array')) { 37 $gis_data = $_POST['gis_data']; 38} 39 40$gis_types = array( 41 'POINT', 42 'MULTIPOINT', 43 'LINESTRING', 44 'MULTILINESTRING', 45 'POLYGON', 46 'MULTIPOLYGON', 47 'GEOMETRYCOLLECTION' 48); 49 50// Extract type from the initial call and make sure that it's a valid one. 51// Extract from field's values if available, if not use the column type passed. 52if (! isset($gis_data['gis_type'])) { 53 if (isset($_POST['type']) && $_POST['type'] != '') { 54 $gis_data['gis_type'] = mb_strtoupper($_POST['type']); 55 } 56 if (isset($_POST['value']) && trim($_POST['value']) != '') { 57 $start = (substr($_POST['value'], 0, 1) == "'") ? 1 : 0; 58 $gis_data['gis_type'] = mb_substr( 59 $_POST['value'], 60 $start, 61 mb_strpos($_POST['value'], "(") - $start 62 ); 63 } 64 if ((! isset($gis_data['gis_type'])) 65 || (! in_array($gis_data['gis_type'], $gis_types)) 66 ) { 67 $gis_data['gis_type'] = $gis_types[0]; 68 } 69} 70$geom_type = htmlspecialchars($gis_data['gis_type']); 71 72// Generate parameters from value passed. 73$gis_obj = GisFactory::factory($geom_type); 74if (isset($_POST['value'])) { 75 $gis_data = array_merge( 76 $gis_data, $gis_obj->generateParams($_POST['value']) 77 ); 78} 79 80// Generate Well Known Text 81$srid = (isset($gis_data['srid']) && $gis_data['srid'] != '') 82 ? htmlspecialchars($gis_data['srid']) : 0; 83$wkt = $gis_obj->generateWkt($gis_data, 0); 84$wkt_with_zero = $gis_obj->generateWkt($gis_data, 0, '0'); 85$result = "'" . $wkt . "'," . $srid; 86 87// Generate SVG based visualization 88$visualizationSettings = array( 89 'width' => 450, 90 'height' => 300, 91 'spatialColumn' => 'wkt', 92 'mysqlVersion' => $GLOBALS['dbi']->getVersion() 93); 94$data = array(array('wkt' => $wkt_with_zero, 'srid' => $srid)); 95$visualization = GisVisualization::getByData($data, $visualizationSettings) 96 ->toImage('svg'); 97 98$open_layers = GisVisualization::getByData($data, $visualizationSettings) 99 ->asOl(); 100 101// If the call is to update the WKT and visualization make an AJAX response 102if (isset($_POST['generate']) && $_POST['generate'] == true) { 103 $extra_data = array( 104 'result' => $result, 105 'visualization' => $visualization, 106 'openLayers' => $open_layers, 107 ); 108 $response = Response::getInstance(); 109 $response->addJSON($extra_data); 110 exit; 111} 112 113ob_start(); 114 115echo '<form id="gis_data_editor_form" action="gis_data_editor.php" method="post">'; 116echo '<input type="hidden" id="pmaThemeImage"' 117 , ' value="' , $GLOBALS['pmaThemeImage'] , '" />'; 118echo '<div id="gis_data_editor">'; 119 120echo '<h3>'; 121printf( 122 __('Value for the column "%s"'), 123 htmlspecialchars($_POST['field']) 124); 125echo '</h3>'; 126 127echo '<input type="hidden" name="field" value="' 128 , htmlspecialchars($_POST['field']) , '" />'; 129// The input field to which the final result should be added 130// and corresponding null checkbox 131if (isset($_POST['input_name'])) { 132 echo '<input type="hidden" name="input_name" value="' 133 , htmlspecialchars($_POST['input_name']) , '" />'; 134} 135echo Url::getHiddenInputs(); 136 137echo '<!-- Visualization section -->'; 138echo '<div id="placeholder"' 139 , ($srid != 0 ? 'class="hide"' : '') , '>'; 140echo $visualization; 141echo '</div>'; 142 143// No not remove inline style or it will cause "Cannot read property 'w' of null" on GIS editor map init 144echo '<div id="openlayersmap" style="width: ' . $visualizationSettings['width'] . 'px; height: ' . $visualizationSettings['height'] . 'px;" ' 145 , ($srid == 0 ? 'class="hide"' : '') , '>'; 146echo '</div>'; 147 148echo '<div class="choice floatright">'; 149echo '<input type="checkbox" id="choice" value="useBaseLayer"' 150 , ($srid != 0 ? ' checked="checked"' : '') , '/>'; 151echo '<label for="choice">' , __("Use OpenStreetMaps as Base Layer") , '</label>'; 152echo '</div>'; 153 154echo '<script language="javascript" type="text/javascript">'; 155echo $open_layers; 156echo '</script>'; 157echo '<!-- End of visualization section -->'; 158 159 160echo '<!-- Header section - Inclueds GIS type selector and input field for SRID -->'; 161echo '<div id="gis_data_header">'; 162echo '<select name="gis_data[gis_type]" class="gis_type">'; 163foreach ($gis_types as $gis_type) { 164 echo '<option value="' , $gis_type , '"'; 165 if ($geom_type == $gis_type) { 166 echo ' selected="selected"'; 167 } 168 echo '>' , $gis_type , '</option>'; 169} 170echo '</select>'; 171echo ' '; 172/* l10n: Spatial Reference System Identifier */ 173echo '<label for="srid">' , __('SRID:') , '</label>'; 174echo '<input name="gis_data[srid]" type="text" value="' , $srid , '" />'; 175echo '</div>'; 176echo '<!-- End of header section -->'; 177 178echo '<!-- Data section -->'; 179echo '<div id="gis_data">'; 180 181$geom_count = 1; 182if ($geom_type == 'GEOMETRYCOLLECTION') { 183 $geom_count = (isset($gis_data[$geom_type]['geom_count'])) 184 ? intval($gis_data[$geom_type]['geom_count']) : 1; 185 if (isset($gis_data[$geom_type]['add_geom'])) { 186 $geom_count++; 187 } 188 echo '<input type="hidden" name="gis_data[GEOMETRYCOLLECTION][geom_count]"' 189 , ' value="' , $geom_count , '" />'; 190} 191 192for ($a = 0; $a < $geom_count; $a++) { 193 if (! isset($gis_data[$a])) { 194 continue; 195 } 196 197 if ($geom_type == 'GEOMETRYCOLLECTION') { 198 echo '<br/><br/>'; 199 printf(__('Geometry %d:'), $a + 1); 200 echo '<br/>'; 201 if (isset($gis_data[$a]['gis_type'])) { 202 $type = htmlspecialchars($gis_data[$a]['gis_type']); 203 } else { 204 $type = $gis_types[0]; 205 } 206 echo '<select name="gis_data[' , $a , '][gis_type]" class="gis_type">'; 207 foreach (array_slice($gis_types, 0, 6) as $gis_type) { 208 echo '<option value="' , $gis_type , '"'; 209 if ($type == $gis_type) { 210 echo ' selected="selected"'; 211 } 212 echo '>' , $gis_type , '</option>'; 213 } 214 echo '</select>'; 215 } else { 216 $type = $geom_type; 217 } 218 219 if ($type == 'POINT') { 220 echo '<br/>'; 221 echo __('Point:'); 222 echo '<label for="x">' , __("X") , '</label>'; 223 echo '<input name="gis_data[' , $a , '][POINT][x]" type="text"' 224 , ' value="' , escape($gis_data[$a]['POINT']['x']) , '" />'; 225 echo '<label for="y">' , __("Y") , '</label>'; 226 echo '<input name="gis_data[' , $a , '][POINT][y]" type="text"' 227 , ' value="' , escape($gis_data[$a]['POINT']['y']) , '" />'; 228 229 } elseif ($type == 'MULTIPOINT' || $type == 'LINESTRING') { 230 $no_of_points = isset($gis_data[$a][$type]['no_of_points']) 231 ? intval($gis_data[$a][$type]['no_of_points']) : 1; 232 if ($type == 'LINESTRING' && $no_of_points < 2) { 233 $no_of_points = 2; 234 } 235 if ($type == 'MULTIPOINT' && $no_of_points < 1) { 236 $no_of_points = 1; 237 } 238 239 if (isset($gis_data[$a][$type]['add_point'])) { 240 $no_of_points++; 241 } 242 echo '<input type="hidden" value="' , $no_of_points , '"' 243 , ' name="gis_data[' , $a , '][' , $type , '][no_of_points]" />'; 244 245 for ($i = 0; $i < $no_of_points; $i++) { 246 echo '<br/>'; 247 printf(__('Point %d'), $i + 1); 248 echo ': '; 249 echo '<label for="x">' , __("X") , '</label>'; 250 echo '<input type="text"' 251 , ' name="gis_data[' , $a , '][' , $type , '][' , $i , '][x]"' 252 , ' value="' , escape($gis_data[$a][$type][$i]['x']) , '" />'; 253 echo '<label for="y">' , __("Y") , '</label>'; 254 echo '<input type="text"' 255 , ' name="gis_data[' , $a , '][' , $type , '][' , $i , '][y]"' 256 , ' value="' , escape($gis_data[$a][$type][$i]['y']) , '" />'; 257 } 258 echo '<input type="submit"' 259 , ' name="gis_data[' , $a , '][' , $type , '][add_point]"' 260 , ' class="add addPoint" value="' , __("Add a point") , '" />'; 261 262 } elseif ($type == 'MULTILINESTRING' || $type == 'POLYGON') { 263 $no_of_lines = isset($gis_data[$a][$type]['no_of_lines']) 264 ? intval($gis_data[$a][$type]['no_of_lines']) : 1; 265 if ($no_of_lines < 1) { 266 $no_of_lines = 1; 267 } 268 if (isset($gis_data[$a][$type]['add_line'])) { 269 $no_of_lines++; 270 } 271 echo '<input type="hidden" value="' , $no_of_lines , '"' 272 , ' name="gis_data[' , $a , '][' , $type , '][no_of_lines]" />'; 273 274 for ($i = 0; $i < $no_of_lines; $i++) { 275 echo '<br/>'; 276 if ($type == 'MULTILINESTRING') { 277 printf(__('Linestring %d:'), $i + 1); 278 } else { 279 if ($i == 0) { 280 echo __('Outer ring:'); 281 } else { 282 printf(__('Inner ring %d:'), $i); 283 } 284 } 285 286 $no_of_points = isset($gis_data[$a][$type][$i]['no_of_points']) 287 ? intval($gis_data[$a][$type][$i]['no_of_points']) : 2; 288 if ($type == 'MULTILINESTRING' && $no_of_points < 2) { 289 $no_of_points = 2; 290 } 291 if ($type == 'POLYGON' && $no_of_points < 4) { 292 $no_of_points = 4; 293 } 294 if (isset($gis_data[$a][$type][$i]['add_point'])) { 295 $no_of_points++; 296 } 297 echo '<input type="hidden" value="' , $no_of_points , '"' 298 , ' name="gis_data[' , $a , '][' , $type , '][' , $i 299 , '][no_of_points]" />'; 300 301 for ($j = 0; $j < $no_of_points; $j++) { 302 echo('<br/>'); 303 printf(__('Point %d'), $j + 1); 304 echo ': '; 305 echo '<label for="x">' , __("X") , '</label>'; 306 echo '<input type="text" name="gis_data[' , $a , '][' , $type . '][' 307 , $i , '][' , $j , '][x]" value="' 308 , escape($gis_data[$a][$type][$i][$j]['x']) , '" />'; 309 echo '<label for="y">' , __("Y") , '</label>'; 310 echo '<input type="text" name="gis_data[' , $a , '][' , $type , '][' 311 , $i , '][' , $j , '][y]"' , ' value="' 312 , escape($gis_data[$a][$type][$i][$j]['y']) , '" />'; 313 } 314 echo '<input type="submit" name="gis_data[' , $a , '][' , $type , '][' 315 , $i , '][add_point]"' 316 , ' class="add addPoint" value="' , __("Add a point") , '" />'; 317 } 318 $caption = ($type == 'MULTILINESTRING') 319 ? __('Add a linestring') 320 : __('Add an inner ring'); 321 echo '<br/>'; 322 echo '<input type="submit"' 323 , ' name="gis_data[' , $a , '][' , $type , '][add_line]"' 324 , ' class="add addLine" value="' , $caption , '" />'; 325 326 } elseif ($type == 'MULTIPOLYGON') { 327 $no_of_polygons = isset($gis_data[$a][$type]['no_of_polygons']) 328 ? intval($gis_data[$a][$type]['no_of_polygons']) : 1; 329 if ($no_of_polygons < 1) { 330 $no_of_polygons = 1; 331 } 332 if (isset($gis_data[$a][$type]['add_polygon'])) { 333 $no_of_polygons++; 334 } 335 echo '<input type="hidden"' 336 , ' name="gis_data[' , $a , '][' , $type , '][no_of_polygons]"' 337 , ' value="' , $no_of_polygons , '" />'; 338 339 for ($k = 0; $k < $no_of_polygons; $k++) { 340 echo '<br/>'; 341 printf(__('Polygon %d:'), $k + 1); 342 $no_of_lines = isset($gis_data[$a][$type][$k]['no_of_lines']) 343 ? intval($gis_data[$a][$type][$k]['no_of_lines']) : 1; 344 if ($no_of_lines < 1) { 345 $no_of_lines = 1; 346 } 347 if (isset($gis_data[$a][$type][$k]['add_line'])) { 348 $no_of_lines++; 349 } 350 echo '<input type="hidden"' 351 , ' name="gis_data[' , $a , '][' , $type , '][' , $k 352 , '][no_of_lines]"' , ' value="' , $no_of_lines , '" />'; 353 354 for ($i = 0; $i < $no_of_lines; $i++) { 355 echo '<br/><br/>'; 356 if ($i == 0) { 357 echo __('Outer ring:'); 358 } else { 359 printf(__('Inner ring %d:'), $i); 360 } 361 362 $no_of_points = isset($gis_data[$a][$type][$k][$i]['no_of_points']) 363 ? intval($gis_data[$a][$type][$k][$i]['no_of_points']) : 4; 364 if ($no_of_points < 4) { 365 $no_of_points = 4; 366 } 367 if (isset($gis_data[$a][$type][$k][$i]['add_point'])) { 368 $no_of_points++; 369 } 370 echo '<input type="hidden"' 371 , ' name="gis_data[' , $a , '][' , $type , '][' , $k , '][' , $i 372 , '][no_of_points]"' , ' value="' , $no_of_points , '" />'; 373 374 for ($j = 0; $j < $no_of_points; $j++) { 375 echo '<br/>'; 376 printf(__('Point %d'), $j + 1); 377 echo ': '; 378 echo '<label for="x">' , __("X") , '</label>'; 379 echo '<input type="text"' 380 , ' name="gis_data[' , $a , '][' , $type , '][' , $k , '][' 381 , $i , '][' , $j , '][x]"' 382 , ' value="' , escape($gis_data[$a][$type][$k][$i][$j]['x']) 383 , '" />'; 384 echo '<label for="y">' , __("Y") , '</label>'; 385 echo '<input type="text"' 386 , ' name="gis_data[' , $a , '][' , $type , '][' , $k , '][' 387 , $i , '][' , $j , '][y]"' 388 , ' value="' , escape($gis_data[$a][$type][$k][$i][$j]['y']) 389 , '" />'; 390 } 391 echo '<input type="submit"' 392 , ' name="gis_data[' , $a , '][' , $type , '][' , $k , '][' , $i 393 , '][add_point]"' 394 , ' class="add addPoint" value="' , __("Add a point") , '" />'; 395 } 396 echo '<br/>'; 397 echo '<input type="submit"' 398 , ' name="gis_data[' , $a , '][' , $type , '][' , $k , '][add_line]"' 399 , ' class="add addLine" value="' , __('Add an inner ring') , '" />'; 400 echo '<br/>'; 401 } 402 echo '<br/>'; 403 echo '<input type="submit"' 404 , ' name="gis_data[' , $a , '][' , $type , '][add_polygon]"' 405 , ' class="add addPolygon" value="' , __('Add a polygon') , '" />'; 406 } 407} 408if ($geom_type == 'GEOMETRYCOLLECTION') { 409 echo '<br/><br/>'; 410 echo '<input type="submit" name="gis_data[GEOMETRYCOLLECTION][add_geom]"' 411 , 'class="add addGeom" value="' , __("Add geometry") , '" />'; 412} 413echo '</div>'; 414echo '<!-- End of data section -->'; 415 416echo '<br/>'; 417echo '<input type="submit" name="gis_data[save]" value="' , __('Go') , '" />'; 418 419echo '<div id="gis_data_output">'; 420echo '<h3>' , __('Output') , '</h3>'; 421echo '<p>'; 422echo __( 423 'Choose "ST_GeomFromText" from the "Function" column and paste the' 424 . ' string below into the "Value" field.' 425); 426echo '</p>'; 427echo '<textarea id="gis_data_textarea" cols="95" rows="5">'; 428echo htmlspecialchars($result); 429echo '</textarea>'; 430echo '</div>'; 431 432echo '</div>'; 433echo '</form>'; 434 435Response::getInstance()->addJSON('gis_editor', ob_get_contents()); 436ob_end_clean(); 437