* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * */ namespace libgpx; use \DateTimeZone; use \RuntimeException; /** * Constants and miscellaneous functions for the libgpx library. * * @static * @author Andy Street */ final class libGPX { /** * The XML namespace for GPX 1.0. */ const NAMESPACE_GPX_1_0 = 'http://www.topografix.com/GPX/1/0'; /** * The XML namespace for GPX 1.1. */ const NAMESPACE_GPX_1_1 = 'http://www.topografix.com/GPX/1/1'; /** * The XML namespace for XML Schema. */ const NAMESPACE_XMLSCHEMA = 'http://www.w3.org/2001/XMLSchema-instance'; /** * The URL of the schema document for GPX 1.0. */ const SCHEMA_GPX_1_0 = 'http://www.topografix.com/GPX/1/0/gpx.xsd'; /** * The URL of the schema document for GPX 1.1. */ const SCHEMA_GPX_1_1 = 'http://www.topografix.com/GPX/1/1/gpx.xsd'; /** * If libgpx::init() has been completed successfully. * * @var boolean */ private static $initialized = false; /** * Empty constructor - class is static. */ private function __construct() {} /** * Check if the system has the required dependencies. * * @param boolean $throw If true, throw an exception when dependencies are unmet. * @return boolean If all dependencies are met. * @throws RuntimeException */ public static function checkDependencies($throw = false) { // Define dependencies $php_version = '7.0.0'; $modules = ['xmlreader', 'xmlwriter']; // Check for PHP if (version_compare(PHP_VERSION, $php_version) < 0) { if ($throw) throw new RuntimeException( sprintf('PHP version %s required.', $php_version) ); else return false; } // Check for modules foreach ($modules as $module) { if (!extension_loaded($module)) { if ($throw) throw new RuntimeException(sprintf( 'PHP module "%s" required but not installed.', $module )); else return false; } } return true; } /** * Ensure that dependencies are met and an autoloader is registered. * * @return void * @throws RuntimeException If the dependencies are not met. */ public static function init() { if (self::$initialized) return; self::checkDependencies(true); spl_autoload_register( function ($class) { if (strncmp($class, 'libgpx\\', 7) !== 0) return; $class = strtolower(substr($class, 7)); $filename = __DIR__ . DIRECTORY_SEPARATOR . $class . '.php'; if (is_readable($filename)) { include $filename; } } ); self::$initialized = true; } /** * Measure the distance between two points. * * Haversine formula, great circle distance. * * @param float $lat1 The latitude of the first point. * @param float $lon1 The longitude of the first point. * @param float $lat2 The latitude of the second point. * @param float $lon2 The longitude of the second point. * @return float The distance in meters. */ public static function distance( float $lat1, float $lon1, float $lat2, float $lon2 ) { $deg2rad = pi() / 180; $r = 6371000; // Radius of the Earth in meters $dlat = ($lat2 - $lat1) * $deg2rad; $dlon = ($lon2 - $lon1) * $deg2rad; $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1 * $deg2rad) * cos($lat2 * $deg2rad) * sin($dlon / 2) * sin($dlon / 2); $c = 2 * atan2(sqrt($a), sqrt(1-$a)); return $r * $c; } /** * Convert meters in to miles. * * @see https://en.wikipedia.org/wiki/Mile * * @param float $meters A distance in meters. * @return float A distance in miles. */ public static function meters2miles(float $meters) { return $meters / 1609.344; } }