Fix gis extent calculation
Signed-off-by: Maximilian Krög <maxi_kroeg@web.de>
This commit is contained in:
parent
b91b1c25bc
commit
c5343eeed9
@ -21,11 +21,20 @@ use function sprintf;
|
||||
use function str_replace;
|
||||
use function trim;
|
||||
|
||||
use const INF;
|
||||
|
||||
/**
|
||||
* Base class for all GIS data type classes.
|
||||
*/
|
||||
abstract class GisGeometry
|
||||
{
|
||||
public const EMPTY_EXTENT = [
|
||||
'minX' => +INF,
|
||||
'minY' => +INF,
|
||||
'maxX' => -INF,
|
||||
'maxY' => -INF,
|
||||
];
|
||||
|
||||
/**
|
||||
* Prepares and returns the code related to a row in the GIS dataset as SVG.
|
||||
*
|
||||
@ -143,8 +152,10 @@ abstract class GisGeometry
|
||||
*
|
||||
* @param string $point_set point set
|
||||
* @param array $min_max existing min, max values
|
||||
* @psalm-param array{minX:float,minY:float,maxX:float,maxY:float} $min_max *
|
||||
*
|
||||
* @return array the updated min, max values
|
||||
* @psalm-return array{minX:float,minY:float,maxX:float,maxY:float}
|
||||
*/
|
||||
protected function setMinMax($point_set, array $min_max)
|
||||
{
|
||||
|
||||
@ -54,7 +54,7 @@ class GisGeometryCollection extends GisGeometry
|
||||
*/
|
||||
public function scaleRow($spatial)
|
||||
{
|
||||
$min_max = [];
|
||||
$min_max = GisGeometry::EMPTY_EXTENT;
|
||||
|
||||
// Trim to remove leading 'GEOMETRYCOLLECTION(' and trailing ')'
|
||||
$goem_col = mb_substr($spatial, 19, -1);
|
||||
|
||||
@ -52,13 +52,14 @@ class GisLineString extends GisGeometry
|
||||
* @param string $spatial spatial data of a row
|
||||
*
|
||||
* @return array an array containing the min, max values for x and y coordinates
|
||||
* @psalm-return array{minX:float,minY:float,maxX:float,maxY:float}
|
||||
*/
|
||||
public function scaleRow($spatial)
|
||||
{
|
||||
// Trim to remove leading 'LINESTRING(' and trailing ')'
|
||||
$linestring = mb_substr($spatial, 11, -1);
|
||||
|
||||
return $this->setMinMax($linestring, []);
|
||||
return $this->setMinMax($linestring, GisGeometry::EMPTY_EXTENT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -53,10 +53,11 @@ class GisMultiLineString extends GisGeometry
|
||||
* @param string $spatial spatial data of a row
|
||||
*
|
||||
* @return array an array containing the min, max values for x and y coordinates
|
||||
* @psalm-return array{minX:float,minY:float,maxX:float,maxY:float}
|
||||
*/
|
||||
public function scaleRow($spatial)
|
||||
{
|
||||
$min_max = [];
|
||||
$min_max = GisGeometry::EMPTY_EXTENT;
|
||||
|
||||
// Trim to remove leading 'MULTILINESTRING((' and trailing '))'
|
||||
$multilinestirng = mb_substr($spatial, 17, -2);
|
||||
|
||||
@ -52,13 +52,14 @@ class GisMultiPoint extends GisGeometry
|
||||
* @param string $spatial spatial data of a row
|
||||
*
|
||||
* @return array an array containing the min, max values for x and y coordinates
|
||||
* @psalm-return array{minX:float,minY:float,maxX:float,maxY:float}
|
||||
*/
|
||||
public function scaleRow($spatial)
|
||||
{
|
||||
// Trim to remove leading 'MULTIPOINT(' and trailing ')'
|
||||
$multipoint = mb_substr($spatial, 11, -1);
|
||||
|
||||
return $this->setMinMax($multipoint, []);
|
||||
return $this->setMinMax($multipoint, GisGeometry::EMPTY_EXTENT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -56,10 +56,11 @@ class GisMultiPolygon extends GisGeometry
|
||||
* @param string $spatial spatial data of a row
|
||||
*
|
||||
* @return array an array containing the min, max values for x and y coordinates
|
||||
* @psalm-return array{minX:float,minY:float,maxX:float,maxY:float}
|
||||
*/
|
||||
public function scaleRow($spatial)
|
||||
{
|
||||
$min_max = [];
|
||||
$min_max = GisGeometry::EMPTY_EXTENT;
|
||||
|
||||
// Trim to remove leading 'MULTIPOLYGON(((' and trailing ')))'
|
||||
$multipolygon = mb_substr($spatial, 15, -3);
|
||||
|
||||
@ -51,13 +51,14 @@ class GisPoint extends GisGeometry
|
||||
* @param string $spatial spatial data of a row
|
||||
*
|
||||
* @return array an array containing the min, max values for x and y coordinates
|
||||
* @psalm-return array{minX:float,minY:float,maxX:float,maxY:float}
|
||||
*/
|
||||
public function scaleRow($spatial)
|
||||
{
|
||||
// Trim to remove leading 'POINT(' and trailing ')'
|
||||
$point = mb_substr($spatial, 6, -1);
|
||||
|
||||
return $this->setMinMax($point, []);
|
||||
return $this->setMinMax($point, GisGeometry::EMPTY_EXTENT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -59,6 +59,7 @@ class GisPolygon extends GisGeometry
|
||||
* @param string $spatial spatial data of a row
|
||||
*
|
||||
* @return array an array containing the min, max values for x and y coordinates
|
||||
* @psalm-return array{minX:float,minY:float,maxX:float,maxY:float}
|
||||
*/
|
||||
public function scaleRow($spatial)
|
||||
{
|
||||
@ -74,7 +75,7 @@ class GisPolygon extends GisGeometry
|
||||
$ring = $parts[0];
|
||||
}
|
||||
|
||||
return $this->setMinMax($ring, []);
|
||||
return $this->setMinMax($ring, GisGeometry::EMPTY_EXTENT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -17,6 +17,7 @@ use function array_merge;
|
||||
use function base64_encode;
|
||||
use function count;
|
||||
use function intval;
|
||||
use function is_finite;
|
||||
use function is_numeric;
|
||||
use function is_string;
|
||||
use function mb_strlen;
|
||||
@ -543,12 +544,7 @@ class GisVisualization
|
||||
*/
|
||||
private function scaleDataSet(array $data)
|
||||
{
|
||||
$min_max = [
|
||||
'maxX' => 0.0,
|
||||
'maxY' => 0.0,
|
||||
'minX' => 0.0,
|
||||
'minY' => 0.0,
|
||||
];
|
||||
$min_max = GisGeometry::EMPTY_EXTENT;
|
||||
$border = 15;
|
||||
// effective width and height of the plot
|
||||
$plot_width = $this->settings['width'] - 2 * $border;
|
||||
@ -577,28 +573,35 @@ class GisVisualization
|
||||
|
||||
// Update minimum/maximum values for x and y coordinates.
|
||||
$c_maxX = (float) $scale_data['maxX'];
|
||||
if ($min_max['maxX'] === 0.0 || $c_maxX > $min_max['maxX']) {
|
||||
if ($c_maxX > $min_max['maxX']) {
|
||||
$min_max['maxX'] = $c_maxX;
|
||||
}
|
||||
|
||||
$c_minX = (float) $scale_data['minX'];
|
||||
if ($min_max['minX'] === 0.0 || $c_minX < $min_max['minX']) {
|
||||
if ($c_minX < $min_max['minX']) {
|
||||
$min_max['minX'] = $c_minX;
|
||||
}
|
||||
|
||||
$c_maxY = (float) $scale_data['maxY'];
|
||||
if ($min_max['maxY'] === 0.0 || $c_maxY > $min_max['maxY']) {
|
||||
if ($c_maxY > $min_max['maxY']) {
|
||||
$min_max['maxY'] = $c_maxY;
|
||||
}
|
||||
|
||||
$c_minY = (float) $scale_data['minY'];
|
||||
if ($min_max['minY'] !== 0.0 && $c_minY >= $min_max['minY']) {
|
||||
if ($c_minY >= $min_max['minY']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$min_max['minY'] = $c_minY;
|
||||
}
|
||||
|
||||
if (! is_finite($min_max['minX']) || ! is_finite($min_max['minY'])) {
|
||||
$min_max['maxX'] = 0.0;
|
||||
$min_max['maxY'] = 0.0;
|
||||
$min_max['minX'] = 0.0;
|
||||
$min_max['minY'] = 0.0;
|
||||
}
|
||||
|
||||
// scale the visualization
|
||||
$x_ratio = ($min_max['maxX'] - $min_max['minX']) / $plot_width;
|
||||
$y_ratio = ($min_max['maxY'] - $min_max['minY']) / $plot_height;
|
||||
|
||||
@ -3746,12 +3746,22 @@ parameters:
|
||||
path: libraries/classes/Gis/GisGeometry.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpMyAdmin\\\\Gis\\\\GisGeometry\\:\\:setMinMax\\(\\) has parameter \\$min_max with no value type specified in iterable type array\\.$#"
|
||||
message: "#^Offset 'maxX' on array\\{minX\\: float, minY\\: float, maxX\\: float, maxY\\: float\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisGeometry.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpMyAdmin\\\\Gis\\\\GisGeometry\\:\\:setMinMax\\(\\) return type has no value type specified in iterable type array\\.$#"
|
||||
message: "#^Offset 'maxY' on array\\{minX\\: float, minY\\: float, maxX\\: float, maxY\\: float\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisGeometry.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'minX' on array\\{minX\\: float, minY\\: float, maxX\\: float, maxY\\: float\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisGeometry.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'minY' on array\\{minX\\: float, minY\\: float, maxX\\: float, maxY\\: float\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisGeometry.php
|
||||
|
||||
@ -3805,6 +3815,26 @@ parameters:
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisGeometryCollection.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'maxX' on array\\{minX\\: float, minY\\: float, maxX\\: float, maxY\\: float\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisGeometryCollection.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'maxY' on array\\{minX\\: float, minY\\: float, maxX\\: float, maxY\\: float\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisGeometryCollection.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'minX' on array\\{minX\\: float, minY\\: float, maxX\\: float, maxY\\: float\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisGeometryCollection.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'minY' on array\\{minX\\: float, minY\\: float, maxX\\: float, maxY\\: float\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisGeometryCollection.php
|
||||
|
||||
-
|
||||
message: "#^Static property PhpMyAdmin\\\\Gis\\\\GisGeometryCollection\\:\\:\\$instance \\(PhpMyAdmin\\\\Gis\\\\GisGeometryCollection\\) in isset\\(\\) is not nullable\\.$#"
|
||||
count: 1
|
||||
@ -3845,11 +3875,6 @@ parameters:
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisLineString.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpMyAdmin\\\\Gis\\\\GisLineString\\:\\:scaleRow\\(\\) return type has no value type specified in iterable type array\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisLineString.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#5 \\$color of method PhpMyAdmin\\\\Image\\\\ImageWrapper\\:\\:line\\(\\) expects int, int\\|false given\\.$#"
|
||||
count: 1
|
||||
@ -3905,11 +3930,6 @@ parameters:
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisMultiLineString.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpMyAdmin\\\\Gis\\\\GisMultiLineString\\:\\:scaleRow\\(\\) return type has no value type specified in iterable type array\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisMultiLineString.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#5 \\$color of method PhpMyAdmin\\\\Image\\\\ImageWrapper\\:\\:line\\(\\) expects int, int\\|false given\\.$#"
|
||||
count: 1
|
||||
@ -3970,11 +3990,6 @@ parameters:
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisMultiPoint.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpMyAdmin\\\\Gis\\\\GisMultiPoint\\:\\:scaleRow\\(\\) return type has no value type specified in iterable type array\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisMultiPoint.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#5 \\$color of method PhpMyAdmin\\\\Image\\\\ImageWrapper\\:\\:string\\(\\) expects int, int\\|false given\\.$#"
|
||||
count: 1
|
||||
@ -4035,11 +4050,6 @@ parameters:
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisMultiPolygon.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpMyAdmin\\\\Gis\\\\GisMultiPolygon\\:\\:scaleRow\\(\\) return type has no value type specified in iterable type array\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisMultiPolygon.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$color of method PhpMyAdmin\\\\Image\\\\ImageWrapper\\:\\:filledPolygon\\(\\) expects int, int\\|false given\\.$#"
|
||||
count: 1
|
||||
@ -4095,11 +4105,6 @@ parameters:
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisPoint.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpMyAdmin\\\\Gis\\\\GisPoint\\:\\:scaleRow\\(\\) return type has no value type specified in iterable type array\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisPoint.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#5 \\$color of method PhpMyAdmin\\\\Image\\\\ImageWrapper\\:\\:string\\(\\) expects int, int\\|false given\\.$#"
|
||||
count: 1
|
||||
@ -4185,11 +4190,6 @@ parameters:
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisPolygon.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpMyAdmin\\\\Gis\\\\GisPolygon\\:\\:scaleRow\\(\\) return type has no value type specified in iterable type array\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Gis/GisPolygon.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$color of method PhpMyAdmin\\\\Image\\\\ImageWrapper\\:\\:filledPolygon\\(\\) expects int, int\\|false given\\.$#"
|
||||
count: 1
|
||||
|
||||
@ -15640,7 +15640,8 @@
|
||||
</NonInvariantDocblockPropertyType>
|
||||
</file>
|
||||
<file src="test/classes/Gis/GisVisualizationTest.php">
|
||||
<MixedAssignment occurrences="9">
|
||||
<MixedAssignment occurrences="10">
|
||||
<code>$dataSet</code>
|
||||
<code>$dataSet</code>
|
||||
<code>$queryString</code>
|
||||
<code>$queryString</code>
|
||||
|
||||
@ -71,7 +71,7 @@ class GisGeometryTest extends AbstractTestCase
|
||||
return [
|
||||
[
|
||||
'12 35,48 75,69 23,25 45,14 53,35 78',
|
||||
[],
|
||||
GisGeometry::EMPTY_EXTENT,
|
||||
[
|
||||
'minX' => 12,
|
||||
'maxX' => 69,
|
||||
|
||||
@ -80,6 +80,32 @@ class GisVisualizationTest extends AbstractTestCase
|
||||
],
|
||||
$dataSet
|
||||
);
|
||||
|
||||
// Regression test for bug with 0.0 sentinel values
|
||||
$dataSet = $this->callFunction(
|
||||
$gis,
|
||||
GisVisualization::class,
|
||||
'scaleDataSet',
|
||||
[
|
||||
[
|
||||
['abc' => 'MULTIPOLYGON(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))'],
|
||||
['abc' => 'MULTIPOLYGON(((10 10,10 13,13 13,13 10,10 10),(11 11,11 12,12 12,12 11,11 11)))'],
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->assertSame(
|
||||
[
|
||||
'scale' => 32.30769230769231,
|
||||
'x' => -2.7857142857142865,
|
||||
'y' => -0.4642857142857143,
|
||||
'minX' => 0.0,
|
||||
'maxX' => 13.0,
|
||||
'minY' => 0.0,
|
||||
'maxY' => 13.0,
|
||||
'height' => 450,
|
||||
],
|
||||
$dataSet
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user