Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
51.72% covered (warning)
51.72%
15 / 29
87.50% covered (warning)
87.50%
7 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
BoundingBox
51.72% covered (warning)
51.72%
15 / 29
87.50% covered (warning)
87.50%
7 / 8
28.20
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 newFromNumbers
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 newFromPoints
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 newFromRadius
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
 topLeft
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 bottomRight
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 area
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 center
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace GeoData;
4
5/**
6 * Class that represents a bounding box
7 */
8class BoundingBox {
9
10    private Coord $coord1;
11    private Coord $coord2;
12
13    private function __construct( Coord $topLeft, Coord $bottomRight ) {
14        $this->coord1 = $topLeft;
15        $this->coord2 = $bottomRight;
16    }
17
18    /**
19     * @param float $lat1
20     * @param float $lon1
21     * @param float $lat2
22     * @param float $lon2
23     * @param Globe|string $globe
24     */
25    public static function newFromNumbers( $lat1, $lon1, $lat2, $lon2, $globe ): self {
26        return new self( new Coord( $lat1, $lon1, $globe ), new Coord( $lat2, $lon2, $globe ) );
27    }
28
29    /**
30     * Constructs a bounding box from 2 corner coordinates
31     */
32    public static function newFromPoints( Coord $topLeft, Coord $bottomRight ): self {
33        return new self( $topLeft, $bottomRight );
34    }
35
36    /**
37     * Returns a bounding rectangle around this coordinate
38     */
39    public static function newFromRadius( Coord $coord, int $radius ): self {
40        if ( $radius <= 0 ) {
41            return self::newFromPoints( $coord, $coord );
42        }
43
44        $globe = $coord->getGlobeObj();
45        $r2lat = rad2deg( $radius / $globe->getRadius() );
46        // @todo: doesn't work around poles, should we care?
47        if ( abs( $coord->lat ) < 89.9 ) {
48            $r2lon = rad2deg( $radius / cos( deg2rad( $coord->lat ) ) / $globe->getRadius() );
49        } else {
50            $r2lon = 0.1;
51        }
52        $lat1 = $coord->lat - $r2lat;
53        $lon1 = $coord->lon - $r2lon;
54        $lat2 = $coord->lat + $r2lat;
55        $lon2 = $coord->lon + $r2lon;
56        Math::wrapAround( $lat1, $lat2, -90, 90 );
57        Math::wrapAround( $lon1, $lon2, $globe->getMinLongitude(), $globe->getMaxLongitude() );
58        return self::newFromNumbers( $lat1, $lon1, $lat2, $lon2, $globe );
59    }
60
61    /**
62     * @return Coord Top left corner of this bounding box
63     */
64    public function topLeft(): Coord {
65        return $this->coord1;
66    }
67
68    /**
69     * @return Coord Bottom right corner of this bounding box
70     */
71    public function bottomRight(): Coord {
72        return $this->coord2;
73    }
74
75    /**
76     * Computes a (very approximate) area of this bounding box
77     *
78     * @return float
79     */
80    public function area() {
81        $midLat = ( $this->coord2->lat + $this->coord1->lat ) / 2;
82        $radius = $this->coord1->getGlobeObj()->getRadius();
83        $vert = Math::distance( $this->coord1->lat, 0, $this->coord2->lat, 0, $radius );
84        $horz = Math::distance( $midLat, $this->coord1->lon, $midLat, $this->coord2->lon, $radius );
85
86        return $horz * $vert;
87    }
88
89    /**
90     * Returns center of this bounding box
91     */
92    public function center(): Coord {
93        $lon = ( $this->coord2->lon + $this->coord1->lon ) / 2.0;
94        if ( $this->coord1->lon > $this->coord2->lon ) {
95            // Wrap around
96            $lon += ( $lon < 0 ) ? 180 : -180;
97        }
98
99        return new Coord( ( $this->coord1->lat + $this->coord2->lat ) / 2.0, $lon, $this->coord1->globe );
100    }
101}