| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  |  * PHPCoord. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  |  * @author Doug Wright | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | declare(strict_types=1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | namespace PHPCoord; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | use function cos; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | use DateTime; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | use DateTimeImmutable; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | use DateTimeInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | use PHPCoord\CoordinateOperation\AutoConversion; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | use PHPCoord\CoordinateOperation\ConvertiblePoint; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | use PHPCoord\CoordinateReferenceSystem\Compound; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  | use PHPCoord\CoordinateReferenceSystem\CoordinateReferenceSystem; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | use PHPCoord\CoordinateReferenceSystem\Geographic2D; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  | use PHPCoord\CoordinateReferenceSystem\Geographic3D; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | use PHPCoord\CoordinateReferenceSystem\Projected; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | use PHPCoord\CoordinateReferenceSystem\Vertical; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  | use PHPCoord\Exception\InvalidCoordinateReferenceSystemException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  | use PHPCoord\Exception\UnknownConversionException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | use PHPCoord\UnitOfMeasure\Angle\Angle; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  | use PHPCoord\UnitOfMeasure\Length\Length; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  | use PHPCoord\UnitOfMeasure\Length\Metre; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  | use function sin; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  | use function sqrt; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |  * Coordinate representing a point expressed in 2 different CRSs (2D horizontal + 1D Vertical). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  | class CompoundPoint extends Point implements ConvertiblePoint | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |     use AutoConversion { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |         convert as protected autoConvert; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |      * Horizontal point. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |      * @var GeographicPoint|ProjectedPoint | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |     protected Point $horizontalPoint; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |      * Vertical point. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |     protected VerticalPoint $verticalPoint; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |      * Coordinate reference system. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |     protected Compound $crs; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |      * Coordinate epoch (date for which the specified coordinates represented this point). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |     protected ?DateTimeImmutable $epoch; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |      * Constructor. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |      * @param GeographicPoint|ProjectedPoint $horizontalPoint | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 | 8 |  |     protected function __construct(Point $horizontalPoint, VerticalPoint $verticalPoint, Compound $crs, ?DateTimeInterface $epoch = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 | 8 |  |         $this->horizontalPoint = $horizontalPoint; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 | 8 |  |         $this->verticalPoint = $verticalPoint; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 | 8 |  |         $this->crs = $crs; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 | 8 |  |         if ($epoch instanceof DateTime) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 | 1 |  |             $epoch = DateTimeImmutable::createFromMutable($epoch); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 | 8 |  |         $this->epoch = $epoch; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 | 8 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |      * @param GeographicPoint|ProjectedPoint $horizontalPoint | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 | 8 |  |     public static function create(Point $horizontalPoint, VerticalPoint $verticalPoint, Compound $crs, ?DateTimeInterface $epoch = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 | 8 |  |         return new static($horizontalPoint, $verticalPoint, $crs, $epoch); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 | 7 |  |     public function getHorizontalPoint(): Point | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 | 7 |  |         return $this->horizontalPoint; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 | 6 |  |     public function getVerticalPoint(): VerticalPoint | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 | 6 |  |         return $this->verticalPoint; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 | 7 |  |     public function getCRS(): Compound | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 | 7 |  |         return $this->crs; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 99 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 100 | 5 |  |     public function getCoordinateEpoch(): ?DateTimeImmutable | 
            
                                                                        
                            
            
                                    
            
            
                | 101 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 102 | 5 |  |         return $this->epoch; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |      * Calculate distance between two points. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 | 2 |  |     public function calculateDistance(Point $to): Length | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |         try { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 | 2 |  |             if ($to instanceof ConvertiblePoint) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 | 2 |  |                 $to = $to->convert($this->crs); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |         } finally { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 | 2 |  |             if ($to->getCRS()->getSRID() !== $this->crs->getSRID()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 | 1 |  |                 throw new InvalidCoordinateReferenceSystemException('Can only calculate distances between two points in the same CRS'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |             /* @var CompoundPoint $to */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 | 1 |  |             return $this->horizontalPoint->calculateDistance($to->horizontalPoint); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 | 4 |  |     public function convert(CoordinateReferenceSystem $to, bool $ignoreBoundaryRestrictions = false): Point | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |         try { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 | 4 |  |             return $this->autoConvert($to, $ignoreBoundaryRestrictions); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 | 1 |  |         } catch (UnknownConversionException $e) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 | 1 |  |             if (($to instanceof Geographic2D || $to instanceof Projected) && $this->getHorizontalPoint() instanceof ConvertiblePoint) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |                 return $this->getHorizontalPoint()->convert($to, $ignoreBoundaryRestrictions); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 | 1 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 | 3 |  |     public function __toString(): string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 | 3 |  |         return "({$this->horizontalPoint}, {$this->verticalPoint})"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |      * Geographic2D with Height Offsets. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |      * This transformation allows calculation of coordinates in the target system by adding the parameter value to the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |      * coordinate values of the point in the source system. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 | 2 |  |     public function geographic2DWithHeightOffsets( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |         Geographic3D $to, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |         Angle $latitudeOffset, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |         Angle $longitudeOffset, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |         Length $geoidUndulation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |     ): GeographicPoint { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 | 2 |  |         $toLatitude = $this->getHorizontalPoint()->getLatitude()->add($latitudeOffset); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 | 2 |  |         $toLongitude = $this->getHorizontalPoint()->getLongitude()->add($longitudeOffset); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 | 2 |  |         $toHeight = $this->getVerticalPoint()->getHeight()->add($geoidUndulation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 | 2 |  |         return GeographicPoint::create($toLatitude, $toLongitude, $toHeight, $to, $this->epoch); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |      * Vertical Offset and Slope | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |      * This transformation allows calculation of height in the target system by applying the parameter values to the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |      * height value of the point in the source system. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 | 1 |  |     public function verticalOffsetAndSlope( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |         Compound $to, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |         Angle $ordinate1OfEvaluationPoint, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |         Angle $ordinate2OfEvaluationPoint, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |         Length $verticalOffset, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |         Angle $inclinationInLatitude, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |         Angle $inclinationInLongitude | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |     ): self { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 | 1 |  |         $latitude = $this->horizontalPoint->getLatitude()->asRadians()->getValue(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 | 1 |  |         $longitude = $this->horizontalPoint->getLongitude()->asRadians()->getValue(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 | 1 |  |         $latitudeOrigin = $ordinate1OfEvaluationPoint->asRadians()->getValue(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 | 1 |  |         $longitudeOrigin = $ordinate2OfEvaluationPoint->asRadians()->getValue(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 | 1 |  |         $a = $this->horizontalPoint->getCRS()->getDatum()->getEllipsoid()->getSemiMajorAxis()->asMetres()->getValue(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 | 1 |  |         $e2 = $this->horizontalPoint->getCRS()->getDatum()->getEllipsoid()->getEccentricitySquared(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 | 1 |  |         $rhoOrigin = $a * (1 - $e2) / (1 - $e2 * sin($latitudeOrigin) ** 2) ** 1.5; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 | 1 |  |         $nuOrigin = $a / sqrt(1 - $e2 * (sin($latitudeOrigin) ** 2)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 | 1 |  |         $latitudeTerm = new Metre($inclinationInLatitude->asRadians()->getValue() * $rhoOrigin * ($latitude - $latitudeOrigin)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 | 1 |  |         $longitudeTerm = new Metre($inclinationInLongitude->asRadians()->getValue() * $nuOrigin * ($longitude - $longitudeOrigin) * cos($latitude)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 | 1 |  |         $newVerticalHeight = $this->verticalPoint->getHeight()->add($verticalOffset)->add($latitudeTerm)->add($longitudeTerm); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 | 1 |  |         $newVerticalPoint = VerticalPoint::create($newVerticalHeight, $to->getVertical()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 | 1 |  |         return static::create($this->horizontalPoint, $newVerticalPoint, $to); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 189 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 190 |  |  |  | 
            
                        
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.
Either this assignment is in error or an instanceof check should be added for that assignment.