Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
38.60% |
22 / 57 |
|
70.00% |
7 / 10 |
CRAP | |
0.00% |
0 / 1 |
Globe | |
38.60% |
22 / 57 |
|
70.00% |
7 / 10 |
75.27 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |||
getData | |
8.33% |
3 / 36 |
|
0.00% |
0 / 1 |
5.08 | |||
getName | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRadius | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getMinLongitude | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getMaxLongitude | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getEastSign | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isKnown | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
equalsTo | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
coordinatesAreValid | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
5.12 |
1 | <?php |
2 | |
3 | namespace GeoData; |
4 | |
5 | /** |
6 | * Immutable representation of a celestial body |
7 | */ |
8 | class Globe { |
9 | /** @var string */ |
10 | private $name; |
11 | |
12 | /** @var float|null */ |
13 | private $radius; |
14 | |
15 | /** @var float */ |
16 | private $minLon = -360; |
17 | |
18 | /** @var float */ |
19 | private $maxLon = 360; |
20 | |
21 | /** @var int either -1 or +1 */ |
22 | private $east = 1; |
23 | |
24 | /** @var bool */ |
25 | private $known = false; |
26 | |
27 | /** |
28 | * @param string $name Internal globe name |
29 | */ |
30 | public function __construct( $name ) { |
31 | global $wgGlobes; |
32 | |
33 | $this->name = $name; |
34 | |
35 | $data = $wgGlobes[$name] ?? self::getData()[$name] ?? null; |
36 | if ( $data !== null ) { |
37 | $this->radius = $data['radius'] ?? null; |
38 | $this->minLon = $data['lon'][0] ?? 0; |
39 | $this->maxLon = $data['lon'][1]; |
40 | $this->east = $data['east'] ?? 1; |
41 | $this->known = true; |
42 | } |
43 | } |
44 | |
45 | /** |
46 | * @return array[] |
47 | */ |
48 | private static function getData() { |
49 | static $data = []; |
50 | if ( $data ) { |
51 | return $data; |
52 | } |
53 | |
54 | $earth = [ 'lon' => [ -180, 180 ], 'east' => +1 ]; |
55 | $east360 = [ 'lon' => [ 0, 360 ], 'east' => +1 ]; |
56 | $west360 = [ 'lon' => [ 0, 360 ], 'east' => -1 ]; |
57 | |
58 | /** |
59 | * Format: |
60 | * 'lon' => array of [minimum value, maximum value] |
61 | * 'east' => sign 1 degree East would have |
62 | * 'radius' => mean radius in meters (optional) |
63 | * Coordinate systems mostly taken from http://planetarynames.wr.usgs.gov/TargetCoordinates |
64 | * Radii taken from Wikipedia. Globes that are too irregular in shape don't have radius set. |
65 | */ |
66 | $data = [ |
67 | 'earth' => $earth + [ 'radius' => Math::EARTH_RADIUS ], |
68 | 'mercury' => $west360 + [ 'radius' => 2439700.0 ], |
69 | 'venus' => $east360 + [ 'radius' => 6051800.0 ], |
70 | 'moon' => $earth + [ 'radius' => 1737100.0 ], |
71 | // Assuming MDIM 2.1 |
72 | 'mars' => $east360 + [ 'radius' => 3389500.0 ], |
73 | 'phobos' => $west360, |
74 | 'deimos' => $west360, |
75 | // 'ceres' => ???, |
76 | // 'vesta' => ???, |
77 | 'ganymede' => $west360 + [ 'radius' => 2634100.0 ], |
78 | 'callisto' => $west360 + [ 'radius' => 2410300.0 ], |
79 | 'io' => $west360 + [ 'radius' => 1821600.0 ], |
80 | 'europa' => $west360 + [ 'radius' => 1560800.0 ], |
81 | 'mimas' => $west360 + [ 'radius' => 198200.0 ], |
82 | 'enceladus' => $west360 + [ 'radius' => 252100.0 ], |
83 | 'tethys' => $west360 + [ 'radius' => 531100.0 ], |
84 | 'dione' => $west360 + [ 'radius' => 561400.0 ], |
85 | 'rhea' => $west360 + [ 'radius' => 763800.0 ], |
86 | 'titan' => $west360 + [ 'radius' => 2575500.0 ], |
87 | 'hyperion' => $west360, |
88 | 'iapetus' => $west360 + [ 'radius' => 734500.0 ], |
89 | 'phoebe' => $west360, |
90 | 'miranda' => $east360 + [ 'radius' => 235800.0 ], |
91 | 'ariel' => $east360 + [ 'radius' => 578900.0 ], |
92 | 'umbriel' => $east360 + [ 'radius' => 584700.0 ], |
93 | 'titania' => $east360 + [ 'radius' => 788400.0 ], |
94 | 'oberon' => $east360 + [ 'radius' => 761400.0 ], |
95 | 'triton' => $east360 + [ 'radius' => 1353400.0 ], |
96 | // ??? |
97 | 'pluto' => $east360 + [ 'radius' => 1187000.0 ], |
98 | ]; |
99 | |
100 | return $data; |
101 | } |
102 | |
103 | /** |
104 | * Globe internal name |
105 | * @return string |
106 | */ |
107 | public function getName() { |
108 | return $this->name; |
109 | } |
110 | |
111 | /** |
112 | * Returns globe radius or null if it's not known |
113 | * @return float|null |
114 | */ |
115 | public function getRadius() { |
116 | return $this->radius; |
117 | } |
118 | |
119 | /** |
120 | * Returns minimum longitude |
121 | * @return float |
122 | */ |
123 | public function getMinLongitude() { |
124 | return $this->minLon; |
125 | } |
126 | |
127 | /** |
128 | * Returns maximum longitude |
129 | * @return float |
130 | */ |
131 | public function getMaxLongitude() { |
132 | return $this->maxLon; |
133 | } |
134 | |
135 | /** |
136 | * Returns the sign of East |
137 | * @return int |
138 | */ |
139 | public function getEastSign() { |
140 | return $this->east; |
141 | } |
142 | |
143 | /** |
144 | * Returns whether this globe is registered (and hence, we know its properties) |
145 | * @return bool |
146 | */ |
147 | public function isKnown() { |
148 | return $this->known; |
149 | } |
150 | |
151 | /** |
152 | * Compares this globe to another |
153 | * @param Globe $other |
154 | * @return bool |
155 | */ |
156 | public function equalsTo( Globe $other ) { |
157 | return $this->name === $other->name; |
158 | } |
159 | |
160 | /** |
161 | * Checks whether given coordinates are valid |
162 | * @param int|float|string $lat |
163 | * @param int|float|string $lon |
164 | * @return bool |
165 | */ |
166 | public function coordinatesAreValid( $lat, $lon ) { |
167 | if ( !is_numeric( $lat ) || !is_numeric( $lon ) ) { |
168 | return false; |
169 | } |
170 | $lat = (float)$lat; |
171 | $lon = (float)$lon; |
172 | |
173 | return $lon >= $this->minLon && $lon <= $this->maxLon |
174 | && abs( $lat ) <= 90; |
175 | } |
176 | } |