Passed
Push — master ( 3c9843...962ccc )
by Doug
02:47
created

UTMPoint::convert()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 1
b 0
f 0
1
<?php
2
/**
3
 * PHPCoord.
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace PHPCoord;
10
11
use DateTimeInterface;
12
use PHPCoord\CoordinateReferenceSystem\CoordinateReferenceSystem;
13
use PHPCoord\CoordinateReferenceSystem\Geographic;
14
use PHPCoord\CoordinateReferenceSystem\Projected;
15
use PHPCoord\CoordinateSystem\Cartesian;
16
use PHPCoord\Geometry\GeographicPolygon;
17
use PHPCoord\UnitOfMeasure\Angle\Degree;
18
use PHPCoord\UnitOfMeasure\Length\Length;
19
use PHPCoord\UnitOfMeasure\Length\Metre;
20
use PHPCoord\UnitOfMeasure\Scale\Unity;
21
22
class UTMPoint extends ProjectedPoint
23
{
24
    public const HEMISPHERE_NORTH = 'N';
25
26
    public const HEMISPHERE_SOUTH = 'S';
27
28
    /**
29
     * Zone number.
30
     */
31
    protected int $zone;
32
33
    /**
34
     * Hemisphere (N or S).
35
     */
36
    protected string $hemisphere;
37
38
    /**
39
     * Base CRS.
40
     */
41
    protected Geographic $baseCRS;
42
43 8
    public function __construct(Length $easting, Length $northing, int $zone, string $hemisphere, Geographic $crs, ?DateTimeInterface $epoch = null)
44
    {
45 8
        $this->zone = $zone;
46 8
        $this->hemisphere = $hemisphere;
47 8
        $this->baseCRS = $crs;
48
49 8
        $longitudeOrigin = $zone * 6 - 3;
50 8
        if ($hemisphere === self::HEMISPHERE_NORTH) {
51 6
            $boundingBox = GeographicPolygon::createFromArray([[$longitudeOrigin, 0], [$longitudeOrigin, 90], [$longitudeOrigin + 6, 90], [$longitudeOrigin + 6, 0]], false);
52
        } else {
53 2
            $boundingBox = GeographicPolygon::createFromArray([[$longitudeOrigin, -90], [$longitudeOrigin, 0], [$longitudeOrigin + 6, 0], [$longitudeOrigin + 6, -90]], false);
54
        }
55
56 8
        $projectedCRS = new Projected(
57 8
            'UTM/' . $crs->getSRID(),
58 8
            Cartesian::fromSRID(Cartesian::EPSG_2D_AXES_EASTING_NORTHING_E_N_ORIENTATIONS_EAST_NORTH_UOM_M),
59 8
            $crs->getDatum(),
60
            $boundingBox
61
        );
62
63 8
        parent::__construct($easting, $northing, null, null, $projectedCRS, $epoch);
64 8
    }
65
66 6
    public function asGeographicPoint(): GeographicPoint
67
    {
68 6
        $latitudeOfNaturalOrigin = new Degree(0);
69 6
        $initialLongitude = new Degree(-180);
70 6
        $scaleFactorAtNaturalOrigin = new Unity(0.9996);
71 6
        $falseEasting = new Metre(500000);
72 6
        $falseNorthing = $this->hemisphere === self::HEMISPHERE_NORTH ? new Metre(0) : new Metre(10000000);
73 6
        $longitudeOrigin = $initialLongitude->add(new Degree($this->zone * 6 - 3));
74
75 6
        return $this->transverseMercator($this->getBaseCRS(), $latitudeOfNaturalOrigin, $longitudeOrigin, $scaleFactorAtNaturalOrigin, $falseEasting, $falseNorthing);
76
    }
77
78 2
    public function getZone(): int
79
    {
80 2
        return $this->zone;
81
    }
82
83 2
    public function getHemisphere(): string
84
    {
85 2
        return $this->hemisphere;
86
    }
87
88 6
    public function getBaseCRS(): Geographic
89
    {
90 6
        return $this->baseCRS;
91
    }
92
93 4
    public function convert(CoordinateReferenceSystem $to, bool $ignoreBoundaryRestrictions = false): Point
94
    {
95 4
        return $this->asGeographicPoint()->convert($to, $ignoreBoundaryRestrictions);
96
    }
97
98 3
    public function calculateDistance(Point $to): Length
99
    {
100 3
        if ($this->crs == $to->getCRS()) {
101 1
            return parent::calculateDistance($to);
102
        }
103
104 2
        return $this->asGeographicPoint()->calculateDistance($to);
105
    }
106
107 2
    public function __toString(): string
108
    {
109 2
        return $this->getZone() . $this->getHemisphere() . ' ' . (int) $this->easting->getValue() . ' ' . (int) $this->northing->getValue();
110
    }
111
}
112