Skip to content

Commit a7dd3bd

Browse files
Merge pull request #18118 from MoonE/gis-generate-params
Proper method inheritance for gis generateParams
2 parents 5d17681 + 818c2d9 commit a7dd3bd

19 files changed

Lines changed: 467 additions & 486 deletions

libraries/classes/Gis/GisGeometry.php

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use function random_int;
2121
use function sprintf;
2222
use function str_replace;
23+
use function strtoupper;
2324
use function trim;
2425

2526
/**
@@ -166,15 +167,14 @@ protected function setMinMax(string $point_set, ScaleData|null $scaleData = null
166167
}
167168

168169
/**
169-
* Generates parameters for the GIS data editor from the value of the GIS column.
170-
* This method performs common work.
171-
* More specific work is performed by each of the geom classes.
170+
* Parses the wkt and optional srid from a combined string for the GIS data editor
172171
*
173172
* @param string $value value of the GIS column
174173
*
175-
* @return array parameters for the GIS editor from the value of the GIS column
174+
* @return array<string,int|string> parameters for the GIS editor from the value of the GIS column
175+
* @psalm-return array{'srid':int,'wkt':string}
176176
*/
177-
public function generateParams($value): array
177+
protected function parseWktAndSrid(string $value): array
178178
{
179179
$geom_types = '(POINT|MULTIPOINT|LINESTRING|MULTILINESTRING|POLYGON|MULTIPOLYGON|GEOMETRYCOLLECTION)';
180180
$srid = 0;
@@ -194,6 +194,38 @@ public function generateParams($value): array
194194
];
195195
}
196196

197+
/**
198+
* Generate coordinate parameters for the GIS data editor from the value of the GIS column.
199+
*
200+
* @param string $wkt Value of the GIS column
201+
*
202+
* @return array Coordinate params for the GIS data editor from the value of the GIS column
203+
*/
204+
abstract protected function getCoordinateParams(string $wkt): array;
205+
206+
/**
207+
* Generate parameters for the GIS data editor from the value of the GIS column.
208+
*
209+
* @param string $value Value of the GIS column
210+
*
211+
* @return array params for the GIS data editor from the value of the GIS column
212+
*/
213+
public function generateParams(string $value): array
214+
{
215+
$data = $this->parseWktAndSrid($value);
216+
$index = 0;
217+
$wkt = $data['wkt'];
218+
preg_match('/^\w+/', $wkt, $matches);
219+
$wkt_type = strtoupper($matches[0]);
220+
221+
return [
222+
'srid' => $data['srid'],
223+
$index => [
224+
$wkt_type => $this->getCoordinateParams($wkt),
225+
],
226+
];
227+
}
228+
197229
/**
198230
* Extracts points, scales and returns them as an array.
199231
*

libraries/classes/Gis/GisGeometryCollection.php

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77

88
namespace PhpMyAdmin\Gis;
99

10+
use ErrorException;
1011
use PhpMyAdmin\Image\ImageWrapper;
1112
use TCPDF;
1213

13-
use function array_merge;
1414
use function count;
1515
use function mb_strpos;
1616
use function mb_substr;
1717
use function str_split;
18+
use function strtoupper;
1819

1920
/**
2021
* Handles actions related to GIS GEOMETRYCOLLECTION objects
@@ -299,44 +300,55 @@ public function generateWkt(array $gis_data, $index, $empty = ''): string
299300
return $wkt . ')';
300301
}
301302

303+
/**
304+
* GeometryCollection does not have coordinates of its own
305+
*
306+
* @param string $wkt Value of the GIS column
307+
*/
308+
protected function getCoordinateParams(string $wkt): array
309+
{
310+
throw new ErrorException('Has no own coordinates');
311+
}
312+
302313
/**
303314
* Generates parameters for the GIS data editor from the value of the GIS column.
304315
*
305316
* @param string $value of the GIS column
306317
*
307318
* @return array parameters for the GIS editor from the value of the GIS column
308319
*/
309-
public function generateParams($value): array
320+
public function generateParams(string $value): array
310321
{
311-
$params = [];
312-
$data = GisGeometry::generateParams($value);
313-
$params['srid'] = $data['srid'];
322+
$data = $this->parseWktAndSrid($value);
314323
$wkt = $data['wkt'];
315324

316325
// Trim to remove leading 'GEOMETRYCOLLECTION(' and trailing ')'
317326
$goem_col = mb_substr($wkt, 19, -1);
318-
// Split the geometry collection object to get its constituents.
319-
$sub_parts = $this->explodeGeomCol($goem_col);
320-
$params['GEOMETRYCOLLECTION']['geom_count'] = count($sub_parts);
327+
$wkt_geometries = $this->explodeGeomCol($goem_col);
328+
$params = [
329+
'srid' => $data['srid'],
330+
'GEOMETRYCOLLECTION' => [
331+
'geom_count' => count($wkt_geometries),
332+
],
333+
];
321334

322335
$i = 0;
323-
foreach ($sub_parts as $sub_part) {
324-
$type_pos = mb_strpos($sub_part, '(');
336+
foreach ($wkt_geometries as $wkt_geometry) {
337+
$type_pos = mb_strpos($wkt_geometry, '(');
325338
if ($type_pos === false) {
326339
continue;
327340
}
328341

329-
$type = mb_substr($sub_part, 0, $type_pos);
330-
/**
331-
* @var GisMultiPolygon|GisPolygon|GisMultiPoint|GisPoint|GisMultiLineString|GisLineString $gis_obj
332-
*/
333-
$gis_obj = GisFactory::factory($type);
342+
$wkt_type = strtoupper(mb_substr($wkt_geometry, 0, $type_pos));
343+
$gis_obj = GisFactory::factory($wkt_type);
334344
if (! $gis_obj) {
335345
continue;
336346
}
337347

338-
$params = array_merge($params, $gis_obj->generateParams($sub_part, $i));
339-
$i++;
348+
$params[$i++] = [
349+
'gis_type' => $wkt_type,
350+
$wkt_type => $gis_obj->getCoordinateParams($wkt_geometry),
351+
];
340352
}
341353

342354
return $params;

libraries/classes/Gis/GisLineString.php

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -270,37 +270,27 @@ public function generateWkt(array $gis_data, $index, $empty = ''): string
270270
}
271271

272272
/**
273-
* Generate parameters for the GIS data editor from the value of the GIS column.
273+
* Generate coordinate parameters for the GIS data editor from the value of the GIS column.
274274
*
275-
* @param string $value of the GIS column
276-
* @param int $index of the geometry
275+
* @param string $wkt Value of the GIS column
277276
*
278-
* @return array params for the GIS data editor from the value of the GIS column
277+
* @return array Coordinate params for the GIS data editor from the value of the GIS column
279278
*/
280-
public function generateParams($value, $index = -1): array
279+
protected function getCoordinateParams(string $wkt): array
281280
{
282-
$params = [];
283-
if ($index == -1) {
284-
$index = 0;
285-
$data = GisGeometry::generateParams($value);
286-
$params['srid'] = $data['srid'];
287-
$wkt = $data['wkt'];
288-
} else {
289-
$params[$index]['gis_type'] = 'LINESTRING';
290-
$wkt = $value;
291-
}
292-
293281
// Trim to remove leading 'LINESTRING(' and trailing ')'
294282
$linestring = mb_substr($wkt, 11, -1);
295283
$points_arr = $this->extractPoints($linestring, null);
296284

297285
$no_of_points = count($points_arr);
298-
$params[$index]['LINESTRING']['no_of_points'] = $no_of_points;
286+
$coords = ['no_of_points' => $no_of_points];
299287
for ($i = 0; $i < $no_of_points; $i++) {
300-
$params[$index]['LINESTRING'][$i]['x'] = $points_arr[$i][0];
301-
$params[$index]['LINESTRING'][$i]['y'] = $points_arr[$i][1];
288+
$coords[$i] = [
289+
'x' => $points_arr[$i][0],
290+
'y' => $points_arr[$i][1],
291+
];
302292
}
303293

304-
return $params;
294+
return $coords;
305295
}
306296
}

libraries/classes/Gis/GisMultiLineString.php

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -341,45 +341,31 @@ public function getShape(array $row_data): string
341341
}
342342

343343
/**
344-
* Generate parameters for the GIS data editor from the value of the GIS column.
344+
* Generate coordinate parameters for the GIS data editor from the value of the GIS column.
345345
*
346-
* @param string $value Value of the GIS column
347-
* @param int $index Index of the geometry
346+
* @param string $wkt Value of the GIS column
348347
*
349-
* @return array params for the GIS data editor from the value of the GIS column
348+
* @return array Coordinate params for the GIS data editor from the value of the GIS column
350349
*/
351-
public function generateParams($value, $index = -1): array
350+
protected function getCoordinateParams(string $wkt): array
352351
{
353-
$params = [];
354-
if ($index == -1) {
355-
$index = 0;
356-
$data = GisGeometry::generateParams($value);
357-
$params['srid'] = $data['srid'];
358-
$wkt = $data['wkt'];
359-
} else {
360-
$params[$index]['gis_type'] = 'MULTILINESTRING';
361-
$wkt = $value;
362-
}
363-
364352
// Trim to remove leading 'MULTILINESTRING((' and trailing '))'
365-
$multilinestirng = mb_substr($wkt, 17, -2);
366-
// Separate each linestring
367-
$linestirngs = explode('),(', $multilinestirng);
368-
$params[$index]['MULTILINESTRING']['no_of_lines'] = count($linestirngs);
369-
370-
$j = 0;
371-
foreach ($linestirngs as $linestring) {
372-
$points_arr = $this->extractPoints($linestring, null);
373-
$no_of_points = count($points_arr);
374-
$params[$index]['MULTILINESTRING'][$j]['no_of_points'] = $no_of_points;
353+
$wkt_multilinestring = mb_substr($wkt, 17, -2);
354+
$wkt_linestrings = explode('),(', $wkt_multilinestring);
355+
$coords = ['no_of_lines' => count($wkt_linestrings)];
356+
357+
foreach ($wkt_linestrings as $j => $wkt_linestring) {
358+
$points = $this->extractPoints($wkt_linestring, null);
359+
$no_of_points = count($points);
360+
$coords[$j] = ['no_of_points' => $no_of_points];
375361
for ($i = 0; $i < $no_of_points; $i++) {
376-
$params[$index]['MULTILINESTRING'][$j][$i]['x'] = $points_arr[$i][0];
377-
$params[$index]['MULTILINESTRING'][$j][$i]['y'] = $points_arr[$i][1];
362+
$coords[$j][$i] = [
363+
'x' => $points[$i][0],
364+
'y' => $points[$i][1],
365+
];
378366
}
379-
380-
$j++;
381367
}
382368

383-
return $params;
369+
return $coords;
384370
}
385371
}

libraries/classes/Gis/GisMultiPoint.php

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -317,38 +317,28 @@ public function getShape(array $row_data): string
317317
}
318318

319319
/**
320-
* Generate parameters for the GIS data editor from the value of the GIS column.
320+
* Generate coordinate parameters for the GIS data editor from the value of the GIS column.
321321
*
322-
* @param string $value Value of the GIS column
323-
* @param int $index Index of the geometry
322+
* @param string $wkt Value of the GIS column
324323
*
325-
* @return array params for the GIS data editor from the value of the GIS column
324+
* @return array Coordinate params for the GIS data editor from the value of the GIS column
326325
*/
327-
public function generateParams($value, $index = -1): array
326+
protected function getCoordinateParams(string $wkt): array
328327
{
329-
$params = [];
330-
if ($index == -1) {
331-
$index = 0;
332-
$data = GisGeometry::generateParams($value);
333-
$params['srid'] = $data['srid'];
334-
$wkt = $data['wkt'];
335-
} else {
336-
$params[$index]['gis_type'] = 'MULTIPOINT';
337-
$wkt = $value;
338-
}
339-
340328
// Trim to remove leading 'MULTIPOINT(' and trailing ')'
341-
$points = mb_substr($wkt, 11, -1);
342-
$points_arr = $this->extractPoints($points, null);
329+
$wkt_points = mb_substr($wkt, 11, -1);
330+
$points = $this->extractPoints($wkt_points, null);
343331

344-
$no_of_points = count($points_arr);
345-
$params[$index]['MULTIPOINT']['no_of_points'] = $no_of_points;
332+
$no_of_points = count($points);
333+
$coords = ['no_of_points' => $no_of_points];
346334
for ($i = 0; $i < $no_of_points; $i++) {
347-
$params[$index]['MULTIPOINT'][$i]['x'] = $points_arr[$i][0];
348-
$params[$index]['MULTIPOINT'][$i]['y'] = $points_arr[$i][1];
335+
$coords[$i] = [
336+
'x' => $points[$i][0],
337+
'y' => $points[$i][1],
338+
];
349339
}
350340

351-
return $params;
341+
return $coords;
352342
}
353343

354344
/**

libraries/classes/Gis/GisMultiPolygon.php

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -448,54 +448,35 @@ public function getShape(array $row_data): string
448448
}
449449

450450
/**
451-
* Generate parameters for the GIS data editor from the value of the GIS column.
451+
* Generate coordinate parameters for the GIS data editor from the value of the GIS column.
452452
*
453-
* @param string $value Value of the GIS column
454-
* @param int $index Index of the geometry
453+
* @param string $wkt Value of the GIS column
455454
*
456-
* @return array params for the GIS data editor from the value of the GIS column
455+
* @return array Coordinate params for the GIS data editor from the value of the GIS column
457456
*/
458-
public function generateParams($value, $index = -1): array
457+
protected function getCoordinateParams(string $wkt): array
459458
{
460-
$params = [];
461-
if ($index == -1) {
462-
$index = 0;
463-
$data = GisGeometry::generateParams($value);
464-
$params['srid'] = $data['srid'];
465-
$wkt = $data['wkt'];
466-
} else {
467-
$params[$index]['gis_type'] = 'MULTIPOLYGON';
468-
$wkt = $value;
469-
}
470-
471459
// Trim to remove leading 'MULTIPOLYGON(((' and trailing ')))'
472-
$multipolygon = mb_substr($wkt, 15, -3);
473-
// Separate each polygon
474-
$wkt_polygons = explode(')),((', $multipolygon);
475-
476-
$param_row =& $params[$index]['MULTIPOLYGON'];
477-
$param_row['no_of_polygons'] = count($wkt_polygons);
460+
$wkt_multipolygon = mb_substr($wkt, 15, -3);
461+
$wkt_polygons = explode(')),((', $wkt_multipolygon);
462+
$coords = ['no_of_polygons' => count($wkt_polygons)];
478463

479-
$k = 0;
480-
foreach ($wkt_polygons as $wkt_polygon) {
464+
foreach ($wkt_polygons as $k => $wkt_polygon) {
481465
$wkt_rings = explode('),(', $wkt_polygon);
482-
$param_row[$k]['no_of_lines'] = count($wkt_rings);
483-
$j = 0;
484-
foreach ($wkt_rings as $wkt_ring) {
485-
$points_arr = $this->extractPoints($wkt_ring, null);
486-
$no_of_points = count($points_arr);
487-
$param_row[$k][$j]['no_of_points'] = $no_of_points;
466+
$coords[$k] = ['no_of_lines' => count($wkt_rings)];
467+
foreach ($wkt_rings as $j => $wkt_ring) {
468+
$points = $this->extractPoints($wkt_ring, null);
469+
$no_of_points = count($points);
470+
$coords[$k][$j] = ['no_of_points' => $no_of_points];
488471
for ($i = 0; $i < $no_of_points; $i++) {
489-
$param_row[$k][$j][$i]['x'] = $points_arr[$i][0];
490-
$param_row[$k][$j][$i]['y'] = $points_arr[$i][1];
472+
$coords[$k][$j][$i] = [
473+
'x' => $points[$i][0],
474+
'y' => $points[$i][1],
475+
];
491476
}
492-
493-
$j++;
494477
}
495-
496-
$k++;
497478
}
498479

499-
return $params;
480+
return $coords;
500481
}
501482
}

0 commit comments

Comments
 (0)