]> git.street.me.uk Git - andy/gpx.git/blame - src/libgpx/libgpx.php
Fix: PeakStream fails to function correctly after the first file
[andy/gpx.git] / src / libgpx / libgpx.php
CommitLineData
88564339
AS
1<?php
2/**
3 * libgpx.php
4 *
5 * Copyright 2018 Andy Street <andy@street.me.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * MA 02110-1301, USA.
21 *
22 *
23 */
24
25namespace libgpx;
26
27use \DateTimeZone;
28use \RuntimeException;
29
30/**
31 * Constants and miscellaneous functions for the libgpx library.
32 *
33 * @static
34 * @author Andy Street <andy@street.me.uk>
35 */
36final class libGPX
37{
38
39 /**
40 * The XML namespace for GPX 1.0.
41 */
42 const NAMESPACE_GPX_1_0 = 'http://www.topografix.com/GPX/1/0';
43
44 /**
45 * The XML namespace for GPX 1.1.
46 */
47 const NAMESPACE_GPX_1_1 = 'http://www.topografix.com/GPX/1/1';
48
49 /**
50 * The XML namespace for XML Schema.
51 */
52 const NAMESPACE_XMLSCHEMA = 'http://www.w3.org/2001/XMLSchema-instance';
53
54 /**
55 * The URL of the schema document for GPX 1.0.
56 */
57 const SCHEMA_GPX_1_0 = 'http://www.topografix.com/GPX/1/0/gpx.xsd';
58
59 /**
60 * The URL of the schema document for GPX 1.1.
61 */
62 const SCHEMA_GPX_1_1 = 'http://www.topografix.com/GPX/1/1/gpx.xsd';
63
64 /**
65 * If libgpx::init() has been completed successfully.
66 *
67 * @var boolean
68 */
69 private static $initialized = false;
70
71 /**
72 * Empty constructor - class is static.
73 */
74 private function __construct() {}
75
76 /**
77 * Check if the system has the required dependencies.
78 *
79 * @param boolean $throw If true, throw an exception when dependencies are unmet.
80 * @return boolean If all dependencies are met.
81 * @throws RuntimeException
82 */
83 public static function checkDependencies($throw = false)
84 {
85 // Define dependencies
86 $php_version = '7.0.0';
87 $modules = ['xmlreader', 'xmlwriter'];
88
89 // Check for PHP
90 if (version_compare(PHP_VERSION, $php_version) < 0) {
91 if ($throw)
92 throw new RuntimeException(
93 sprintf('PHP version %s required.', $php_version)
94 );
95 else
96 return false;
97 }
98
99 // Check for modules
100 foreach ($modules as $module) {
101 if (!extension_loaded($module)) {
102 if ($throw)
103 throw new RuntimeException(sprintf(
104 'PHP module "%s" required but not installed.',
105 $module
106 ));
107 else
108 return false;
109 }
110 }
111
112 return true;
113 }
114
115 /**
116 * Ensure that dependencies are met and an autoloader is registered.
117 *
118 * @return void
119 * @throws RuntimeException If the dependencies are not met.
120 */
121 public static function init()
122 {
123 if (self::$initialized) return;
124 self::checkDependencies(true);
125 spl_autoload_register(
126 function ($class) {
127 if (strncmp($class, 'libgpx\\', 7) !== 0) return;
128 $class = strtolower(substr($class, 7));
129 $filename = __DIR__ . DIRECTORY_SEPARATOR . $class . '.php';
130 if (is_readable($filename)) {
131 include $filename;
132 }
133 }
134 );
135 self::$initialized = true;
136 }
137
d23d8f6f
AS
138 /**
139 * Measure the distance between two points.
140 *
141 * Haversine formula, great circle distance.
142 *
143 * @param float $lat1 The latitude of the first point.
144 * @param float $lon1 The longitude of the first point.
145 * @param float $lat2 The latitude of the second point.
146 * @param float $lon2 The longitude of the second point.
147 * @return float The distance in meters.
148 */
149 public static function distance(
150 float $lat1,
151 float $lon1,
152 float $lat2,
153 float $lon2
154 ) {
155 $deg2rad = pi() / 180;
156 $r = 6371000; // Radius of the Earth in meters
157 $dlat = ($lat2 - $lat1) * $deg2rad;
158 $dlon = ($lon2 - $lon1) * $deg2rad;
159 $a =
160 sin($dlat / 2) * sin($dlat / 2) +
161 cos($lat1 * $deg2rad) * cos($lat2 * $deg2rad) *
162 sin($dlon / 2) * sin($dlon / 2);
163 $c = 2 * atan2(sqrt($a), sqrt(1-$a));
164 return $r * $c;
165 }
166
167 /**
168 * Convert meters in to miles.
169 *
170 * @see https://en.wikipedia.org/wiki/Mile
171 *
172 * @param float $meters A distance in meters.
173 * @return float A distance in miles.
174 */
175 public static function meters2miles(float $meters)
176 {
177 return $meters / 1609.344;
178 }
179
88564339 180}