Index: tbl_change.php =================================================================== --- tbl_change.php (revision 12493) +++ tbl_change.php (working copy) @@ -433,6 +433,14 @@ $vrow[$field['Field']] = ''; $special_chars = ''; $data = $vrow[$field['Field']]; + } elseif ($cfg['RestrictColumnTypes'][strtoupper($field['True_Type'])] == 'FUNC_SPATIAL') { + // mikenz: convert geospacial fields to editable text + require_once './libraries/opengiswkb.class.php'; + $WKB = new WKB(substr($vrow[$field['Field']], 4)); + $special_chars = $WKB->decodeWKBGeometry(); + $field['len'] = 40; + + } elseif ($field['True_Type'] == 'bit') { $special_chars = PMA_printable_bit_value($vrow[$field['Field']], $extracted_fieldspec['spec_in_brackets']); } else { Index: libraries/display_tbl.lib.php =================================================================== --- libraries/display_tbl.lib.php (revision 12493) +++ libraries/display_tbl.lib.php (working copy) @@ -1236,8 +1236,14 @@ $vertical_display['data'][$row_no][$i] = '  ' . "\n"; } + // g e o m e t r y + + } elseif (stristr($meta->type, 'GEOMETRY')) { + require_once './libraries/opengiswkb.class.php'; + $WKB = new WKB(substr($row[$i], 4)); + $vertical_display['data'][$row_no][$i] = ' ' . $WKB->decodeWKBGeometry() . '' . "\n"; + // b l o b - } elseif (stristr($meta->type, 'BLOB')) { // loic1 : PMA_mysql_fetch_fields returns BLOB in place of // TEXT fields type so we have to ensure it's really a BLOB Index: libraries/opengiswkb.class.php =================================================================== --- libraries/opengiswkb.class.php (revision 0) +++ libraries/opengiswkb.class.php (revision 0) @@ -0,0 +1,270 @@ + + */ +class WKB { + private $data = ''; + private $pos = 0; + + function __construct($data) { + $this->data = $data; + } + + private function decodePoint() { + if ($this->pos + 16 > strlen($this->data)) { + /* Not enough data */ + $this->pos = strlen($this->data); + return ''; + } + + /* Lat */ + list($nothing, $lat) = unpack("d", substr($this->data, $this->pos, 8)); + $this->pos += 8; + + /* Lon */ + list($nothing, $lon) = unpack("d", substr($this->data, $this->pos, 8)); + $this->pos += 8; + return $lat . ' ' . $lon; + } + + private function decodeLinearRing($UnPackMethord){ + if ($this->pos + 5 > strlen($this->data)) { + /* Not enough data */ + return ''; + } + + /* How many points in the ring? */ + list($nothing, $numPoints) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + /* Get all the points */ + $points = array(); + for ($i = 0; $i < $numPoints; $i++) { + $point = trim($this->decodePoint()); + if ($point) { + $points[] = $point; + } + } + + /* Format for return */ + $ret = "(" . implode($points, ', ') . ((count($points) < $numPoints) ? ', ...)' : ')'); + return $ret; + } + + private function decodeWKBPoint(){ + if ($this->pos + 21 > strlen($this->data)) { + /* Not enough data */ + $this->pos = strlen($this->data); + return ''; + } + + /* Byte order */ + list($nothing, $byteOrder) = unpack("C", $this->data[$this->pos]); + $UnPackMethord = ($byteOrder == 0) ? 'N' : 'V'; + $this->pos++; + + /* Type - ignored */ + list($nothing, $wkbType) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + return $this->decodePoint($UnPackMethord); + } + + private function decodeWKBLineString(){ + if ($this->pos + 10 > strlen($this->data)) { + /* Not enough data */ + $this->pos = strlen($this->data); + return ''; + } + + /* Byte order */ + list($nothing, $byteOrder) = unpack("C", $this->data[$this->pos]); + $UnPackMethord = ($byteOrder == 0) ? 'N' : 'V'; + $this->pos++; + + /* Type - ignored */ + list($nothing, $wkbType) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + /* Number of points */ + list($nothing, $numPoints) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + /* Get all the points */ + $points = array(); + for ($i = 0; $i < $numPoints; $i++) { + $point = trim($this->decodePoint($UnPackMethord)); + if ($point) { + $points[] = $point; + } + } + + /* Format for return */ + return "(" . implode($points, ', ') . ((count($points) < $numPoints) ? ', ...)' : ')'); + } + + private function decodeWKBPolygon(){ + if ($this->pos + 10 > strlen($this->data)) { + /* Not enough data */ + $this->pos = strlen($this->data); + return ''; + } + + /* Byte order */ + list($nothing, $byteOrder) = unpack("C", $this->data[$this->pos]); + $UnPackMethord = ($byteOrder == 0) ? 'N' : 'V'; + $this->pos++; + + /* Type - ignored */ + list($nothing, $wkbType) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + /* Number of rings */ + list($nothing, $numRings) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + /* Get the rings */ + $rings = array(); + for ($i = 0; $i < $numRings && $this->pos < strlen($this->data); $i++) { + $ring = trim($this->decodeLinearRing($UnPackMethord)); + if ($ring) { + $rings[] = $ring; + } + } + + /* Format for return */ + return "(" . implode($rings, ', ') . ((count($rings) < $numRings) ? ', ...)' : ')'); + } + + public function decodeWKBGeometry(){ + /* Byte order */ + list($nothing, $byteOrder) = unpack("C", $this->data[$this->pos]); + $UnPackMethord = ($byteOrder == 0) ? 'N' : 'V'; + $this->pos++; + + /* Type */ + list($nothing, $wkbType) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + switch ($wkbType){ + case 1: + /* Point */ + $ret = "POINT(" . $this->decodePoint() . ")"; + break; + + case 2: + /* Line String */ + list($nothing, $numPoints) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + /* Get all the points */ + $points = array(); + for ($i = 0; $i < $numPoints && $this->pos < strlen($this->data); $i++) { + $point = trim($this->decodePoint()); + if ($point) { + $points[] = $point; + } + } + + /* Format for return */ + $ret = "LINESTRING(" . implode($points, ', ') . ((count($points) < $numPoints) ? ', ...)' : ')'); + break; + + case 3: + /* Polygon */ + list($nothing, $numRings) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + /* Get the rings */ + $rings = array(); + for ($i = 0; $i < $numRings && $this->pos < strlen($this->data); $i++) { + $ring = trim($this->decodeLinearRing($UnPackMethord)); + if ($ring) { + $rings[] = $ring; + } + } + + /* Format for return */ + $ret = "POLYGON(" . implode($rings, ', ') . ((count($rings) < $numRings) ? ', ...)' : ')'); + break; + + case 4: + /* Multi point */ + list($nothing, $numPoints) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + /* Get all the points */ + $points = array(); + for ($i = 0; $i < $numPoints && $this->pos < strlen($this->data); $i++) { + $point = trim($this->decodeWKBPoint()); + if ($point) { + $points[] = $point; + } + } + + /* Format for display */ + $ret = "MULTIPOINT(" . implode($points, ', ') . ((count($points) < $numPoints) ? ', ...)' : ')'); + break; + + case 5: + /* Multi Line String */ + list($nothing, $numLines) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + /* Get the Line Strings */ + $lines = array(); + for ($i = 0; $i < $numLines && $this->pos < strlen($this->data); $i++) { + $line = trim($this->decodeWKBLineString()); + if ($line) { + $lines[] = $line; + } + } + + /* Format for display */ + $ret = "MULTILINESTRING(" . implode($lines, ', ') . ((count($lines) < $numLines) ? ', ...)' : ')'); + break; + + case 6: + /* Multi Polygon */ + list($nothing, $numPolygons) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + /* Get the polygons */ + $polygons = array(); + for ($i = 0; $i < $numPolygons && $this->pos < strlen($this->data); $i++) { + $polygon = trim($this->decodeWKBPolygon()); + if ($polygon) { + $polygons[] = $polygon; + } + } + + /* Format for display */ + $ret = "MULTIPOLYGON(" . implode($polygons, ', ') . ((count($polygons) < $numPolygons) ? ', ...)' : ')'); + break; + case 7: + /* Geometry Collection */ + list($nothing, $numGeometries) = unpack($UnPackMethord, substr($this->data, $this->pos, 4)); + $this->pos += 4; + + /* Get the geometries */ + $geometries = array(); + for ($i = 0; $i < $numGeometries && $this->pos < strlen($this->data); $i++) { + $geom = trim($this->decodeWKBGeometry()); + if ($geom) { + $geometries[] = $geom; + } + } + + /* Format for display */ + $ret = "GEOMETRYCOLLECTION(" . implode($geometries, ', ') . ((count($geometries) < $numGeometries) ? ', ...)' : ')'); + break; + default: + $ret = "Ummm.. something's broken"; + break; + } + return $ret; + } + +} Index: libraries/config.default.php =================================================================== --- libraries/config.default.php (revision 12493) +++ libraries/config.default.php (working copy) @@ -2774,6 +2774,7 @@ 'FUNC_NUMBER' => '', 'first_timestamp' => 'NOW', 'pk_char36' => 'UUID', + 'FUNC_SPATIAL' => 'GeomFromText', );