Passed
Push — master ( 344e29...cbaf3e )
by Doug
38:02
created

NADCON5Grid   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 57
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 30
dl 0
loc 57
ccs 34
cts 34
cp 1
rs 10
c 2
b 0
f 0
wmc 6

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getValues() 0 7 2
A getRecord() 0 14 2
A getHeader() 0 7 1
A __construct() 0 15 1
1
<?php
2
/**
3
 * PHPCoord.
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace PHPCoord\CoordinateOperation;
10
11
use SplFileObject;
12
use UnexpectedValueException;
13
14
use function unpack;
15
16
class NADCON5Grid extends Grid
17
{
18
    use BiquadraticInterpolation;
19
20
    private string $gridDataType;
21
22 8
    public function __construct($filename)
23
    {
24 8
        $this->gridFile = new SplFileObject($filename);
25
26 8
        $header = $this->getHeader();
27 8
        $this->startX = $header['xlonsw'];
28 8
        $this->startY = $header['xlatsw'];
29 8
        $this->columnGridInterval = $header['dlon'];
30 8
        $this->rowGridInterval = $header['dlat'];
31 8
        $this->numberOfColumns = $header['nlon'];
32 8
        $this->numberOfRows = $header['nlat'];
33
34 8
        $this->gridDataType = match ($header['ikind']) {
35 8
            1 => 'G',
36 8
            default => throw new UnexpectedValueException("Unknown ikind: {$header['ikind']}"),
37 8
        };
38
    }
39
40 8
    protected function getRecord(int $longitudeIndex, int $latitudeIndex): GridValues
41
    {
42 8
        $startBytes = 52;
43 8
        $dataTypeBytes = $this->gridDataType === 'n' ? 2 : 4;
44 8
        $recordLength = 4 + $this->numberOfColumns * $dataTypeBytes + 4;
45
46 8
        $this->gridFile->fseek($startBytes + $recordLength * $latitudeIndex);
47 8
        $rawRow = $this->gridFile->fread($recordLength);
48 8
        $row = unpack("Gstartbuffer/{$this->gridDataType}{$this->numberOfColumns}lon/Gendbuffer", $rawRow);
49
50 8
        return new GridValues(
51 8
            $longitudeIndex * $this->columnGridInterval + $this->startX,
52 8
            $latitudeIndex * $this->rowGridInterval + $this->startY,
53 8
            [$row['lon' . ($longitudeIndex + 1)]]
54 8
        );
55
    }
56
57 8
    private function getHeader(): array
58
    {
59 8
        $this->gridFile->fseek(0);
60 8
        $rawData = $this->gridFile->fread(52);
61 8
        $data = unpack('Gstartbuffer/Exlatsw/Exlonsw/Edlat/Edlon/Nnlat/Nnlon/Nikind/Gendbuffer/', $rawData);
62
63 8
        return $data;
64
    }
65
66 8
    public function getValues(float $x, float $y): array
67
    {
68 8
        if ($x < 0) {
69 8
            $x += 360; // NADCON5 uses 0 = 360 = Greenwich
70
        }
71
72 8
        return $this->interpolate($x, $y);
73
    }
74
}
75