Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
70.00% covered (warning)
70.00%
7 / 10
CRAP
67.65% covered (warning)
67.65%
23 / 34
Globe
0.00% covered (danger)
0.00%
0 / 1
70.00% covered (warning)
70.00%
7 / 10
24.67
67.65% covered (warning)
67.65%
23 / 34
 __construct
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
9 / 9
 getData
0.00% covered (danger)
0.00%
0 / 1
3.69
25.00% covered (danger)
25.00%
3 / 12
 getName
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getRadius
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getMinLongitude
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getMaxLongitude
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getEastSign
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 isKnown
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 equalsTo
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 coordinatesAreValid
0.00% covered (danger)
0.00%
0 / 1
5.12
83.33% covered (warning)
83.33%
5 / 6
<?php
namespace GeoData;
/**
 * Immutable representation of a celestial body
 */
class Globe {
    /** @var string */
    private $name;
    /** @var float|null */
    private $radius;
    /** @var float */
    private $minLon = -360;
    /** @var float */
    private $maxLon = 360;
    /** @var int either -1 or +1 */
    private $east = 1;
    /** @var bool */
    private $known = false;
    /**
     * @param string $name Internal globe name
     */
    public function __construct( $name ) {
        global $wgGlobes;
        $this->name = $name;
        $data = $wgGlobes[$name] ?? self::getData()[$name] ?? null;
        if ( $data !== null ) {
            $this->radius = $data['radius'] ?? null;
            $this->minLon = $data['lon'][0] ?? 0;
            $this->maxLon = $data['lon'][1];
            $this->east = $data['east'] ?? 1;
            $this->known = true;
        }
    }
    /**
     * @return array[]
     */
    private static function getData() {
        static $data = [];
        if ( $data ) {
            return $data;
        }
        $earth   = [ 'lon' => [ -180, 180 ], 'east' => +1 ];
        $east360 = [ 'lon' => [ 0, 360 ],    'east' => +1 ];
        $west360 = [ 'lon' => [ 0, 360 ],    'east' => -1 ];
        /**
         * Format:
         * 'lon' => array of [minimum value, maximum value]
         * 'east' => sign 1 degree East would have
         * 'radius' => mean radius in meters (optional)
         * Coordinate systems mostly taken from http://planetarynames.wr.usgs.gov/TargetCoordinates
         * Radii taken from Wikipedia. Globes that are too irregular in shape don't have radius set.
         */
        $data = [
            'earth'     => $earth + [ 'radius' => Math::EARTH_RADIUS ],
            'mercury'   => $west360 + [ 'radius' => 2439700.0 ],
            'venus'     => $east360 + [ 'radius' => 6051800.0 ],
            'moon'      => $earth + [ 'radius' => 1737100.0 ],
            // Assuming MDIM 2.1
            'mars'      => $east360 + [ 'radius' => 3389500.0 ],
            'phobos'    => $west360,
            'deimos'    => $west360,
            // 'ceres' => ???,
            // 'vesta' => ???,
            'ganymede'  => $west360 + [ 'radius' => 2634100.0 ],
            'callisto'  => $west360 + [ 'radius' => 2410300.0 ],
            'io'        => $west360 + [ 'radius' => 1821600.0 ],
            'europa'    => $west360 + [ 'radius' => 1560800.0 ],
            'mimas'     => $west360 + [ 'radius' => 198200.0 ],
            'enceladus' => $west360 + [ 'radius' => 252100.0 ],
            'tethys'    => $west360 + [ 'radius' => 531100.0 ],
            'dione'     => $west360 + [ 'radius' => 561400.0 ],
            'rhea'      => $west360 + [ 'radius' => 763800.0 ],
            'titan'     => $west360 + [ 'radius' => 2575500.0 ],
            'hyperion'  => $west360,
            'iapetus'   => $west360 + [ 'radius' => 734500.0 ],
            'phoebe'    => $west360,
            'miranda'   => $east360 + [ 'radius' => 235800.0 ],
            'ariel'     => $east360 + [ 'radius' => 578900.0 ],
            'umbriel'   => $east360 + [ 'radius' => 584700.0 ],
            'titania'   => $east360 + [ 'radius' => 788400.0 ],
            'oberon'    => $east360 + [ 'radius' => 761400.0 ],
            'triton'    => $east360 + [ 'radius' => 1353400.0 ],
            // ???
            'pluto'     => $east360 + [ 'radius' => 1187000.0 ],
        ];
        return $data;
    }
    /**
     * Globe internal name
     * @return string
     */
    public function getName() {
        return $this->name;
    }
    /**
     * Returns globe radius or null if it's not known
     * @return float|null
     */
    public function getRadius() {
        return $this->radius;
    }
    /**
     * Returns minimum longitude
     * @return float
     */
    public function getMinLongitude() {
        return $this->minLon;
    }
    /**
     * Returns maximum longitude
     * @return float
     */
    public function getMaxLongitude() {
        return $this->maxLon;
    }
    /**
     * Returns the sign of East
     * @return int
     */
    public function getEastSign() {
        return $this->east;
    }
    /**
     * Returns whether this globe is registered (and hence, we know its properties)
     * @return bool
     */
    public function isKnown() {
        return $this->known;
    }
    /**
     * Compares this globe to another
     * @param Globe $other
     * @return bool
     */
    public function equalsTo( Globe $other ) {
        return $this->name === $other->name;
    }
    /**
     * Checks whether given coordinates are valid
     * @param int|float|string $lat
     * @param int|float|string $lon
     * @return bool
     */
    public function coordinatesAreValid( $lat, $lon ) {
        if ( !is_numeric( $lat ) || !is_numeric( $lon ) ) {
            return false;
        }
        $lat = (float)$lat;
        $lon = (float)$lon;
        return $lon >= $this->minLon && $lon <= $this->maxLon
            && abs( $lat ) <= 90;
    }
}