Skip to content

Commit 25938ac

Browse files
committed
#66 Add "reverse" for general polynomial method
1 parent e6085eb commit 25938ac

File tree

10 files changed

+168
-12
lines changed

10 files changed

+168
-12
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
## [Unreleased]
44

5+
## [5.9.1] - 2024-08-15
6+
### Changed
57
- Updates to data for USA and WGS84
8+
- Support for Irish polynomial transformation in the ETRS89 to TM75 direction (TM75 to ETRS89 was already supported)
69

710
## [5.9.0] - 2024-08-04
811
### Changed

docs/reflection/coordinateoperation/geographic2d.txt

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18975,6 +18975,53 @@ to TM75 (Geographic2D)
1897518975
:header: "EPSG", "PHPCoord"
1897618976
:widths: 40, 60
1897718977

18978+
"| Name: TM75 to ETRS89 (1)
18979+
| Code: ``urn:ogc:def:coordinateOperation:EPSG::1041``
18980+
| Extent: Europe - Ireland (Republic and Ulster) - onshore",".. code-block:: php
18981+
18982+
$point->generalPolynomial(
18983+
to: Geographic2D::fromSRID(Geographic2D::EPSG_TM75),
18984+
ordinate1OfEvaluationPointInSourceCRS: new Degree(53.5),
18985+
ordinate2OfEvaluationPointInSourceCRS: new Degree(-7.7),
18986+
ordinate1OfEvaluationPointInTargetCRS: new Degree(53.5),
18987+
ordinate2OfEvaluationPointInTargetCRS: new Degree(-7.7),
18988+
scalingFactorForSourceCRSCoordDifferences: new Unity(0.1),
18989+
scalingFactorForTargetCRSCoordDifferences: new Unity(3600),
18990+
A0: new Coefficient(0.763),
18991+
Au1v0: new Coefficient(-4.487),
18992+
Au0v1: new Coefficient(0.123),
18993+
Au2v0: new Coefficient(0.215),
18994+
Au1v1: new Coefficient(-0.515),
18995+
Au0v2: new Coefficient(0.183),
18996+
Au3v0: new Coefficient(-0.265),
18997+
Au2v1: new Coefficient(-0.57),
18998+
Au1v2: new Coefficient(0.414),
18999+
Au0v3: new Coefficient(-0.374),
19000+
Au3v1: new Coefficient(2.852),
19001+
Au2v2: new Coefficient(5.703),
19002+
Au1v3: new Coefficient(13.11),
19003+
Au3v2: new Coefficient(-61.678),
19004+
Au2v3: new Coefficient(113.743),
19005+
Au3v3: new Coefficient(-265.898),
19006+
B0: new Coefficient(-2.81),
19007+
Bu1v0: new Coefficient(-0.341),
19008+
Bu0v1: new Coefficient(-4.68),
19009+
Bu2v0: new Coefficient(1.196),
19010+
Bu1v1: new Coefficient(-0.119),
19011+
Bu0v2: new Coefficient(0.17),
19012+
Bu3v0: new Coefficient(-0.887),
19013+
Bu2v1: new Coefficient(4.877),
19014+
Bu1v2: new Coefficient(3.913),
19015+
Bu0v3: new Coefficient(2.163),
19016+
Bu3v1: new Coefficient(-46.666),
19017+
Bu2v2: new Coefficient(-27.795),
19018+
Bu1v3: new Coefficient(18.867),
19019+
Bu3v2: new Coefficient(-95.377),
19020+
Bu2v3: new Coefficient(-284.294),
19021+
Bu3v3: new Coefficient(-853.95)
19022+
)
19023+
19024+
"
1897819025
"| Name: TM75 to ETRS89 (2)
1897919026
| Code: ``urn:ogc:def:coordinateOperation:EPSG::1953``
1898019027
| Extent: Europe - Ireland (Republic and Ulster) - onshore",".. code-block:: php

resources/papers/irish-grid.pdf

563 KB
Binary file not shown.

src/CoordinateOperation/CoordinateOperationMethods.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3018,7 +3018,7 @@ class CoordinateOperationMethods
30183018
],
30193019
'urn:ogc:def:method:EPSG::9648' => [
30203020
'name' => 'General polynomial of degree 6',
3021-
'reversible' => false,
3021+
'reversible' => true,
30223022
'paramData' => [
30233023
'ordinate1OfEvaluationPointInSourceCRS' => [
30243024
'reverses' => false,

src/EPSG/Import/EPSGImporter.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ public function dataFromSQLFiles(): void
148148
*/
149149
$sqlite->exec('UPDATE epsg_usage SET extent_code = 1262 WHERE extent_code IN (1263, 2346, 2830, 4393, 4520, 4523)');
150150

151+
/*
152+
* Ireland TM75 Polynomial is not "reversible" but can be reversed via iteration
153+
*/
154+
$sqlite->exec('UPDATE epsg_coordoperationmethod SET reverse_op = 1 WHERE coord_op_method_code = 9648');
155+
151156
$sqlite->close();
152157
}
153158

src/Point/GeographicPoint.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,7 +2041,8 @@ public function generalPolynomial(
20412041
Scale $scalingFactorForTargetCRSCoordDifferences,
20422042
Scale $A0,
20432043
Scale $B0,
2044-
array $powerCoefficients
2044+
array $powerCoefficients,
2045+
bool $inReverse
20452046
): self {
20462047
$xs = $this->latitude->getValue();
20472048
$ys = $this->longitude->getValue();
@@ -2057,7 +2058,8 @@ public function generalPolynomial(
20572058
$scalingFactorForTargetCRSCoordDifferences,
20582059
$A0,
20592060
$B0,
2060-
$powerCoefficients
2061+
$powerCoefficients,
2062+
$inReverse
20612063
);
20622064

20632065
$xtUnit = $to->getCoordinateSystem()->getAxes()[0]->getUnitOfMeasureId();

src/Point/Point.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ abstract class Point implements Stringable
6363
CoordinateOperationMethods::EPSG_VERTICAL_OFFSET_BY_GRID_INTERPOLATION_PL_TXT => CoordinateOperationMethods::EPSG_VERTICAL_OFFSET_BY_GRID_INTERPOLATION_PL_TXT,
6464
CoordinateOperationMethods::EPSG_VERTICAL_OFFSET_BY_GRID_INTERPOLATION_BEV_AT => CoordinateOperationMethods::EPSG_VERTICAL_OFFSET_BY_GRID_INTERPOLATION_BEV_AT,
6565
CoordinateOperationMethods::EPSG_VERTICAL_CHANGE_BY_GEOID_GRID_DIFFERENCE_NRCAN => CoordinateOperationMethods::EPSG_VERTICAL_CHANGE_BY_GEOID_GRID_DIFFERENCE_NRCAN,
66+
CoordinateOperationMethods::EPSG_GENERAL_POLYNOMIAL_OF_DEGREE_2 => CoordinateOperationMethods::EPSG_GENERAL_POLYNOMIAL_OF_DEGREE_2,
67+
CoordinateOperationMethods::EPSG_GENERAL_POLYNOMIAL_OF_DEGREE_6 => CoordinateOperationMethods::EPSG_GENERAL_POLYNOMIAL_OF_DEGREE_6,
6668
];
6769

6870
/**
@@ -147,6 +149,51 @@ protected static function sign(float $number): int
147149
* @return array{xt: float, yt: float}
148150
*/
149151
protected function generalPolynomialUnitless(
152+
float $xs,
153+
float $ys,
154+
UnitOfMeasure $ordinate1OfEvaluationPointInSourceCRS,
155+
UnitOfMeasure $ordinate2OfEvaluationPointInSourceCRS,
156+
UnitOfMeasure $ordinate1OfEvaluationPointInTargetCRS,
157+
UnitOfMeasure $ordinate2OfEvaluationPointInTargetCRS,
158+
Scale $scalingFactorForSourceCRSCoordDifferences,
159+
Scale $scalingFactorForTargetCRSCoordDifferences,
160+
Scale $A0,
161+
Scale $B0,
162+
array $powerCoefficients,
163+
bool $inReverse
164+
): array {
165+
if (!$inReverse) {
166+
return $this->generalPolynomialUnitlessForward(
167+
$xs,
168+
$ys,
169+
$ordinate1OfEvaluationPointInSourceCRS,
170+
$ordinate2OfEvaluationPointInSourceCRS,
171+
$ordinate1OfEvaluationPointInTargetCRS,
172+
$ordinate2OfEvaluationPointInTargetCRS,
173+
$scalingFactorForSourceCRSCoordDifferences,
174+
$scalingFactorForTargetCRSCoordDifferences,
175+
$A0,
176+
$B0,
177+
$powerCoefficients,
178+
);
179+
} else {
180+
return $this->generalPolynomialUnitlessReverse(
181+
$xs,
182+
$ys,
183+
$ordinate1OfEvaluationPointInSourceCRS,
184+
$ordinate2OfEvaluationPointInSourceCRS,
185+
$ordinate1OfEvaluationPointInTargetCRS,
186+
$ordinate2OfEvaluationPointInTargetCRS,
187+
$scalingFactorForSourceCRSCoordDifferences,
188+
$scalingFactorForTargetCRSCoordDifferences,
189+
$A0,
190+
$B0,
191+
$powerCoefficients,
192+
);
193+
}
194+
}
195+
196+
protected function generalPolynomialUnitlessForward(
150197
float $xs,
151198
float $ys,
152199
UnitOfMeasure $ordinate1OfEvaluationPointInSourceCRS,
@@ -189,6 +236,45 @@ protected function generalPolynomialUnitless(
189236
return ['xt' => $xt, 'yt' => $yt];
190237
}
191238

239+
protected function generalPolynomialUnitlessReverse(
240+
float $xs,
241+
float $ys,
242+
UnitOfMeasure $ordinate1OfEvaluationPointInSourceCRS,
243+
UnitOfMeasure $ordinate2OfEvaluationPointInSourceCRS,
244+
UnitOfMeasure $ordinate1OfEvaluationPointInTargetCRS,
245+
UnitOfMeasure $ordinate2OfEvaluationPointInTargetCRS,
246+
Scale $scalingFactorForSourceCRSCoordDifferences,
247+
Scale $scalingFactorForTargetCRSCoordDifferences,
248+
Scale $A0,
249+
Scale $B0,
250+
array $powerCoefficients
251+
): array {
252+
$result = ['xt' => $xs, 'yt' => $ys];
253+
for ($i = 0; $i <= 15; ++$i) {
254+
$forwardShiftedCoordinates = $this->generalPolynomialUnitlessForward(
255+
$result['xt'],
256+
$result['yt'],
257+
$ordinate1OfEvaluationPointInSourceCRS,
258+
$ordinate2OfEvaluationPointInSourceCRS,
259+
$ordinate1OfEvaluationPointInTargetCRS,
260+
$ordinate2OfEvaluationPointInTargetCRS,
261+
$scalingFactorForSourceCRSCoordDifferences,
262+
$scalingFactorForTargetCRSCoordDifferences,
263+
$A0,
264+
$B0,
265+
$powerCoefficients
266+
);
267+
$deltaError = [
268+
'xt' => $forwardShiftedCoordinates['xt'] - $xs,
269+
'yt' => $forwardShiftedCoordinates['yt'] - $ys,
270+
];
271+
$result['xt'] -= $deltaError['xt'];
272+
$result['yt'] -= $deltaError['yt'];
273+
}
274+
275+
return $result;
276+
}
277+
192278
/**
193279
* Reversible polynomial.
194280
* @param array<string, Coefficient> $powerCoefficients

src/Point/ProjectedPoint.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,7 +2043,8 @@ public function generalPolynomial(
20432043
Scale $scalingFactorForTargetCRSCoordDifferences,
20442044
Scale $A0,
20452045
Scale $B0,
2046-
array $powerCoefficients
2046+
array $powerCoefficients,
2047+
bool $inReverse
20472048
): self {
20482049
$xs = $this->easting->getValue();
20492050
$ys = $this->northing->getValue();
@@ -2059,7 +2060,8 @@ public function generalPolynomial(
20592060
$scalingFactorForTargetCRSCoordDifferences,
20602061
$A0,
20612062
$B0,
2062-
$powerCoefficients
2063+
$powerCoefficients,
2064+
$inReverse
20632065
);
20642066

20652067
$xtUnit = $to->getCoordinateSystem()->getAxes()[0]->getUnitOfMeasureId();

tests/CoordinateOperation/AutoConversionTest.php

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ public function testWGS84ToIrishTM(): void
7171
$toCRS = Projected::fromSRID(Projected::EPSG_TM75_IRISH_GRID);
7272
$to = $from->convert($toCRS);
7373

74-
self::assertEqualsWithDelta(318977.585, $to->getEasting()->asMetres()->getValue(), 0.01);
75-
self::assertEqualsWithDelta(311611.131, $to->getNorthing()->asMetres()->getValue(), 0.01);
74+
self::assertEqualsWithDelta(318977.534, $to->getEasting()->asMetres()->getValue(), 0.01);
75+
self::assertEqualsWithDelta(311611.219, $to->getNorthing()->asMetres()->getValue(), 0.01);
7676

77-
self::assertEquals('J 18978 11611', $to->asGridReferenceWithSpaces(12));
77+
self::assertEquals('J 18977 11611', $to->asGridReferenceWithSpaces(12));
7878
}
7979

8080
public function testETRS89ToIrishTM(): void
@@ -85,10 +85,10 @@ public function testETRS89ToIrishTM(): void
8585
/** @var IrishGridPoint $to */
8686
$to = $from->convert($toCRS);
8787

88-
self::assertEqualsWithDelta(318977.528, $to->getEasting()->asMetres()->getValue(), 0.01);
89-
self::assertEqualsWithDelta(311611.188, $to->getNorthing()->asMetres()->getValue(), 0.01);
88+
self::assertEqualsWithDelta(318977.475, $to->getEasting()->asMetres()->getValue(), 0.01);
89+
self::assertEqualsWithDelta(311611.277, $to->getNorthing()->asMetres()->getValue(), 0.01);
9090

91-
self::assertEquals('J 18978 11611', $to->asGridReferenceWithSpaces(12));
91+
self::assertEquals('J 18977 11611', $to->asGridReferenceWithSpaces(12));
9292
}
9393

9494
public function testNoop(): void
@@ -540,6 +540,16 @@ public function testLambert93RGF2BCorsica(): void
540540
self::assertEqualsWithDelta(9.274852923, $to->getLongitude()->asDegrees()->getValue(), 0.0000001);
541541
}
542542

543+
public function testIRENET95TM75(): void
544+
{
545+
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_IRENET95), new Degree(53.349803), new Degree(-6.2628240));
546+
$toCRS = Projected::fromSRID(Projected::EPSG_TM75_IRISH_GRID);
547+
$to = $from->convert($toCRS);
548+
549+
self::assertEqualsWithDelta(315732.8042, $to->getEasting()->getValue(), 0.001);
550+
self::assertEqualsWithDelta(234667.6783, $to->getNorthing()->getValue(), 0.001);
551+
}
552+
543553
public function testRDNAPToITRF2014(): void
544554
{
545555
if (!class_exists(GTXETRS89NAPProvider::class)) {

tests/Point/GeographicPointTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,8 @@ public function testGeneralPolynomial(): void
958958
'Bu3v2' => new Coefficient(-95.377),
959959
'Bu2v3' => new Coefficient(-284.294),
960960
'Bu3v3' => new Coefficient(-853.95),
961-
]
961+
],
962+
false,
962963
);
963964

964965
self::assertEqualsWithDelta(55.00002972, $to->getLatitude()->getValue(), 0.00000001);

0 commit comments

Comments
 (0)