Passed
Push — master ( aca0dd...3e5121 )
by Doug
22:36
created

IGNGeocentricTranslationGrid::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
/**
3
 * PHPCoord.
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace PHPCoord\CoordinateOperation;
10
11
use function abs;
12
use function assert;
13
use function explode;
14
use const PHP_MAJOR_VERSION;
15
use PHPCoord\CoordinateReferenceSystem\Geographic;
16
use PHPCoord\GeographicPoint;
17
use PHPCoord\UnitOfMeasure\Angle\Degree;
18
use PHPCoord\UnitOfMeasure\Length\Metre;
19
use function preg_replace;
20
use SplFileObject;
21
use function str_replace;
22
use function trim;
23
24
class IGNGeocentricTranslationGrid extends SplFileObject
25
{
26
    use BilinearInterpolation;
27
28
    private const ITERATION_CONVERGENCE = 0.0001;
29
30 3
    public function __construct($filename)
31
    {
32 3
        parent::__construct($filename);
33
34 3
        $this->readHeader();
35 3
    }
36
37 2
    public function applyForwardAdjustment(GeographicPoint $point, Geographic $to): GeographicPoint
38
    {
39 2
        [$tx, $ty, $tz] = $this->getAdjustment($point->getLatitude()->asDegrees(), $point->getLongitude()->asDegrees());
40
41 2
        return $point->geocentricTranslation(
42 2
            $to,
43
            $tx,
44
            $ty,
45
            $tz,
46
        );
47
    }
48
49 1
    public function applyReverseAdjustment(GeographicPoint $point, Geographic $to): GeographicPoint
50
    {
51 1
        $adjustment = [new Metre(0), new Metre(0), new Metre(0)];
52 1
        $latitude = $point->getLatitude();
53 1
        $longitude = $point->getLongitude();
54
55
        do {
56 1
            $prevAdjustment = $adjustment;
57 1
            $adjustment = $this->getAdjustment($latitude->asDegrees(), $longitude->asDegrees());
58 1
            $newPoint = $point->geocentricTranslation(
59 1
                $to,
60 1
                $adjustment[0]->multiply(-1),
61 1
                $adjustment[1]->multiply(-1),
62 1
                $adjustment[2]->multiply(-1),
63
            );
64
65 1
            $latitude = $newPoint->getLatitude();
66 1
            $longitude = $newPoint->getLongitude();
67 1
        } while (abs($adjustment[0]->subtract($prevAdjustment[0])->getValue()) > self::ITERATION_CONVERGENCE && abs($adjustment[1]->subtract($prevAdjustment[1])->getValue()) > self::ITERATION_CONVERGENCE && abs($adjustment[2]->subtract($prevAdjustment[2])->getValue()) > self::ITERATION_CONVERGENCE);
68
69 1
        return $newPoint;
70
    }
71
72
    /**
73
     * @return Metre[]
74
     */
75 3
    private function getAdjustment(Degree $latitude, Degree $longitude): array
76
    {
77 3
        $offsets = $this->interpolateBilinear($longitude->getValue(), $latitude->getValue());
78
79 3
        return [new Metre($offsets[0]), new Metre($offsets[1]), new Metre($offsets[2])];
80
    }
81
82 3
    private function getRecord(int $longitudeIndex, int $latitudeIndex): GridValues
0 ignored issues
show
Unused Code introduced by
The method getRecord() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
83
    {
84 3
        $record = ($longitudeIndex * ($this->numberOfRows + 1) + $latitudeIndex + 4);
85
86
        // https://bugs.php.net/bug.php?id=62004
87 3
        if (PHP_MAJOR_VERSION < 8) {
88
            --$record;
89
        }
90
91 3
        $this->seek($record);
92 3
        $rawData = explode(' ', trim(preg_replace('/ +/', ' ', $this->fgets())));
93
94 3
        return new GridValues((float) $rawData[1], (float) $rawData[2], [(float) $rawData[3], (float) $rawData[4], (float) $rawData[5]]);
95
    }
96
97 3
    private function readHeader(): void
98
    {
99 3
        $header0 = $this->fgets();
0 ignored issues
show
Unused Code introduced by
The assignment to $header0 is dead and can be removed.
Loading history...
100 3
        $header1 = $this->fgets();
101 3
        $header2 = $this->fgets();
102 3
        $header3 = $this->fgets();
0 ignored issues
show
Unused Code introduced by
The assignment to $header3 is dead and can be removed.
Loading history...
103
104 3
        $interpolationMethod = trim(str_replace('GR3D2', '', $header2));
105 3
        assert($interpolationMethod === 'INTERPOLATION BILINEAIRE');
106
107 3
        $gridDimensions = explode(' ', trim(preg_replace('/ +/', ' ', str_replace('GR3D1', '', $header1))));
108 3
        $this->startX = (float) $gridDimensions[0];
109 3
        $this->endX = (float) $gridDimensions[1];
110 3
        $this->startY = (float) $gridDimensions[2];
111 3
        $this->endY = (float) $gridDimensions[3];
112 3
        $this->columnGridInterval = (float) $gridDimensions[4];
113 3
        $this->rowGridInterval = (float) $gridDimensions[5];
114 3
        $this->numberOfColumns = (int) (string) (($this->endX - $this->startX) / $this->columnGridInterval);
115 3
        $this->numberOfRows = (int) (string) (($this->endY - $this->startY) / $this->rowGridInterval);
116 3
    }
117
}
118