Skip to content

Commit 9a57ad4

Browse files
committed
Gis ScaleData offsets in target coordinate system
Signed-off-by: Maximilian Krög <maxi_kroeg@web.de>
1 parent 3b2cae6 commit 9a57ad4

6 files changed

Lines changed: 59 additions & 50 deletions

File tree

psalm-baseline.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9872,11 +9872,6 @@
98729872
<code><![CDATA[$temp1[0]['POLYGON'][1][3]['y']]]></code>
98739873
</MixedArrayAccess>
98749874
</file>
9875-
<file src="tests/unit/Gis/GisVisualizationTest.php">
9876-
<MixedAssignment>
9877-
<code><![CDATA[$dataSet]]></code>
9878-
</MixedAssignment>
9879-
</file>
98809875
<file src="tests/unit/GitTest.php">
98819876
<RedundantConditionGivenDocblockType>
98829877
<code><![CDATA[assertIsArray]]></code>

src/Gis/Ds/ScaleData.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ public function __construct(
1010
public float $scale,
1111
public float $offsetX,
1212
public float $offsetY,
13-
public int $height,
1413
) {
1514
}
1615
}

src/Gis/GisGeometry.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,8 @@ private function extractPointsInternal(string $pointSet, ScaleData|null $scaleDa
250250
$x = (float) $coordinates[0];
251251
$y = (float) $coordinates[1];
252252
if ($scaleData !== null) {
253-
$x = ($x - $scaleData->offsetX) * $scaleData->scale;
254-
$y = $scaleData->height - ($y - $scaleData->offsetY) * $scaleData->scale;
253+
$x = $x * $scaleData->scale + $scaleData->offsetX;
254+
$y = -$y * $scaleData->scale - $scaleData->offsetY;
255255
}
256256
} else {
257257
$x = 0.0;

src/Gis/GisVisualization.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -414,14 +414,17 @@ private function scaleDataSet(array $data): ScaleData|null
414414
$scale = $ratio === 0.0 ? 1.0 : 1.0 / $ratio;
415415

416416
// Center plot
417-
$x = $ratio === 0.0 || $xRatio < $yRatio
418-
? ($extent->maxX + $extent->minX - $this->width / $scale) / 2
419-
: $extent->minX - ($border / $scale);
420-
$y = $ratio === 0.0 || $xRatio >= $yRatio
421-
? ($extent->maxY + $extent->minY - $this->height / $scale) / 2
422-
: $extent->minY - ($border / $scale);
423-
424-
return new ScaleData(scale: $scale, offsetX: $x, offsetY: $y, height: $this->height);
417+
$offsetX = -$extent->minX * $scale + $border;
418+
if ($ratio === 0.0 || $xRatio < $yRatio) {
419+
$offsetX += ($plotWidth - ($extent->maxX - $extent->minX) * $scale) / 2;
420+
}
421+
422+
$offsetY = -$extent->minY * $scale + $border - $this->height;
423+
if ($ratio === 0.0 || $xRatio > $yRatio) {
424+
$offsetY += ($plotHeight - ($extent->maxY - $extent->minY) * $scale) / 2;
425+
}
426+
427+
return new ScaleData(scale: $scale, offsetX: $offsetX, offsetY: $offsetY);
425428
}
426429

427430
/**

tests/unit/Gis/GisGeometryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public static function providerForTestExtractPointsInternal(): array
142142
// with scale data
143143
[
144144
'12 35,48 75,69 23',
145-
new ScaleData(offsetX: 5, offsetY: 5, scale: 2, height: 200),
145+
new ScaleData(scale: 2.0, offsetX: -10.0, offsetY: -210.0),
146146
false,
147147
[[14, 140], [86, 60], [128, 164]],
148148
],

tests/unit/Gis/GisVisualizationTest.php

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -78,56 +78,68 @@ private function getArch(): string
7878
return $arch;
7979
}
8080

81-
/**
82-
* Scale the data set
83-
*
84-
* @param list<array{abc: string|int|null}> $data
85-
*/
81+
/** @param list<array{wkt:string|null}> $data */
8682
#[DataProvider('providerForTestScaleDataSet')]
8783
public function testScaleDataSet(ScaleData|null $expected, array $data): void
8884
{
89-
$gis = GisVisualization::getByData(
85+
$vis = GisVisualization::getByData(
9086
$data,
91-
new GisVisualizationSettings(width: 600, height: 450, spatialColumn: 'abc'),
87+
new GisVisualizationSettings(width: 200, height: 150, spatialColumn: 'wkt'),
9288
);
93-
$dataSet = (new ReflectionMethod(GisVisualization::class, 'scaleDataSet'))
94-
->invoke($gis, $data);
89+
/** @var ScaleData|null $scaleData */
90+
$scaleData = (new ReflectionMethod(GisVisualization::class, 'scaleDataSet'))
91+
->invoke($vis, $data);
9592

96-
self::assertEquals($expected, $dataSet);
93+
self::assertEquals($expected, $scaleData);
9794
}
9895

99-
/** @return array<string, list{ScaleData|null, list<array{abc: string|int|null}>}> */
96+
/** @return array<string,list{ScaleData|null,list<array{wkt:string|null}>}> */
10097
public static function providerForTestScaleDataSet(): array
10198
{
10299
return [
103-
'no valid data' => [
104-
null,
100+
'empty' => [null, []],
101+
'null' => [null, [['wkt' => null]]],
102+
'invalid and valid' => [
103+
new ScaleData(scale: 1.0, offsetX: 100.0, offsetY: -75.0),
105104
[
106-
['abc' => null], // The column is nullable
107-
['abc' => 2], // Some impossible test case
105+
['wkt' => 'asdf'],
106+
['wkt' => 'POINT(0 0)'],
108107
],
109108
],
110-
'partially valid data' => [
111-
new ScaleData(offsetX: -45.35714285714286, offsetY: 42.85714285714286, scale: 2.1, height: 450),
109+
'Point - multiple' => [
110+
new ScaleData(scale: 120.0, offsetX: 40.0, offsetY: -135.0),
112111
[
113-
['abc' => null], // The column is nullable
114-
['abc' => 2], // Some impossible test case
115-
['abc' => 'MULTILINESTRING((36 140,47 233,62 75),(36 100,17 233,178 93))'],
116-
['abc' => 'POINT(100 250)'],
117-
['abc' => 'MULTIPOINT(125 50,156 250,178 143,175 80)'],
112+
['wkt' => 'POINT(0 0)'],
113+
['wkt' => 'POINT(1 1)'],
118114
],
119115
],
120-
'Regression test for bug with 0.0 sentinel values' => [
121-
new ScaleData(
122-
scale: 32.30769230769231,
123-
offsetX: -2.7857142857142865,
124-
offsetY: -0.4642857142857143,
125-
height: 450,
126-
),
127-
[
128-
['abc' => 'MULTIPOLYGON(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))'],
129-
['abc' => 'MULTIPOLYGON(((10 10,10 13,13 13,13 10,10 10),(11 11,11 12,12 12,12 11,11 11)))'],
130-
],
116+
'Point - centered' => [
117+
new ScaleData(scale: 1.0, offsetX: 100.0, offsetY: -75.0),
118+
[['wkt' => 'POINT(0 0)']],
119+
],
120+
'Linestring - vertically centered' => [
121+
new ScaleData(scale: 0.1, offsetX: 0.0, offsetY: -76.0),
122+
[['wkt' => 'LINESTRING(150 10,1850 10)']],
123+
],
124+
'Polygon - empty space at the top and bottom' => [
125+
new ScaleData(scale: 17.0, offsetX: -155.0, offsetY: -75.0),
126+
[['wkt' => 'POLYGON((10 -1,20 -1,20 1,10 1,10 -1))']],
127+
],
128+
'MultiPoint - horizontally centered' => [
129+
new ScaleData(scale: 10.0, offsetX: -99900.0, offsetY: -135.0),
130+
[['wkt' => 'MULTIPOINT(10000 0,10000 12)']],
131+
],
132+
'MultiLineString - fitting exactly' => [
133+
new ScaleData(scale: 1.0, offsetX: 0.0, offsetY: -150.0),
134+
[['wkt' => 'MULTILINESTRING((15 15,100 100),(185 135,100 50))']],
135+
],
136+
'MultiPolygon - fitting exactly' => [
137+
new ScaleData(scale: 60.0, offsetX: 40.0, offsetY: -75.0),
138+
[['wkt' => 'MULTIPOLYGON(((0 0,1 1,0 1,0 0)),((1 -1,2 -1,2 0,1 -1)))']],
139+
],
140+
'GeometryCollection - empty space at either side' => [
141+
new ScaleData(scale: 6.0, offsetX: 1000.0, offsetY: -1335.0),
142+
[['wkt' => 'GEOMETRYCOLLECTION(MULTIPOINT(-149 201,-151 219),LINESTRING(-150 200,-150 220))']],
131143
],
132144
];
133145
}

0 commit comments

Comments
 (0)