]> git.street.me.uk Git - andy/gpx.git/blame - src/libgpx/point.php
Rewrite GPXReader class
[andy/gpx.git] / src / libgpx / point.php
CommitLineData
f528d248
AS
1<?php
2/**
3 * point.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 \DomainException;
28use \DateTimeInterface;
29
30/**
31 * A geographic point.
32 *
33 * @see https://www.topografix.com/GPX/1/1/#type_wptType
34 *
35 * @author Andy Street <andy@street.me.uk>
36 */
09a36623 37class Point extends DataType implements Geographic
f528d248
AS
38{
39
40 /**
41 * The latitude of the point.
42 *
43 * @var float
44 */
45 protected $lat;
46
47 /**
48 * The longitude of the point.
49 *
50 * @var float
51 */
52 protected $lon;
53
54 /**
55 * Elevation (in meters) of the point.
56 *
57 * @var float
58 */
59 protected $ele;
60
61 /**
62 * Creation/modification timestamp for element.
63 *
64 * Date and time in are in Univeral Coordinated Time (UTC), not local time!
65 * Conforms to ISO 8601 specification for date/time representation.
66 * Fractional seconds are allowed for millisecond timing in tracklogs.
67 *
68 * @var DateTimeInterface
69 */
70 protected $time;
71
72 /**
73 * Magnetic variation (in degrees) at the point.
74 *
75 * @var float
76 */
77 protected $magvar;
78
79 /**
80 * Height (in meters) of geoid (mean sea level) above WGS84 earth ellipsoid.
81 * As defined in NMEA GGA message.
82 *
83 * @var float
84 */
85 protected $geoidheight;
86
f528d248
AS
87 /**
88 * Text of GPS symbol name.
89 *
90 * For interchange with other programs, use the exact spelling of the symbol
91 * as displayed on the GPS. If the GPS abbreviates words, spell them out.
92 *
93 * @var string
94 */
95 protected $symbol;
96
f528d248
AS
97 /**
98 * Type of GPS fix.
99 *
100 * "none", "2d", "3d", "dgps" or "pps".
101 *
102 * None means GPS had no fix. To signify "the fix info is unknown, leave out
103 * fixType entirely. pps = military signal used.
104 *
105 * @var string
106 */
107 protected $fix;
108
109 /**
110 * Number of satellites used to calculate the GPX fix.
111 *
112 * @var int
113 */
114 protected $satellites;
115
116 /**
117 * Horizontal dilution of precision.
118 *
119 * @var float
120 */
121 protected $hdop;
122
123 /**
124 * Vertical dilution of precision.
125 *
126 * @var float
127 */
128 protected $vdop;
129
130 /**
131 * Position dilution of precision.
132 *
133 * @var float
134 */
135 protected $pdop;
136
137 /**
138 * Number of seconds since last DGPS update.
139 *
140 * @var float
141 */
142 protected $ageofdgpsdata;
143
144 /**
145 * ID of DGPS station used in differential correction.
146 *
147 * @var int
148 */
149 protected $dgpsid;
150
f528d248
AS
151 /**
152 * Create a new point.
153 *
154 * @param float $lat Latitude
155 * @param float $lon Longitude
156 * @throws DomainException If not a valid latitude or longitude.
157 */
158 public function __construct(float $lat, float $lon)
159 {
160 $this->setLatitude($lat);
161 $this->setLongitude($lon);
162 }
163
164 /**
165 * Fetch the latitude of the point.
166 *
167 * @return float
168 */
169 public function getLatitude()
170 {
171 return $this->lat;
172 }
173
174 /**
175 * Set the latitude of the point.
176 *
177 * @param float $lat Latitude
178 * @return void
179 * @throws DomainException If not a valid latitude.
180 */
181 public function setLatitude(float $lat)
182 {
183 if ($lat < -90 || $lat > 90)
184 throw new DomainException(
185 sprintf('Value %s is not in the range -90-+90.', $lat)
186 );
187 $this->lat = $lat;
188 }
189
190 /**
191 * Fetch the longitude of the point.
192 *
193 * @return float
194 */
195 public function getLongitude()
196 {
197 return $this->lon;
198 }
199
200 /**
201 * Set the longitude of the point.
202 *
203 * @param float $lon Longitude
204 * @return void
205 * @throws DomainException If not a valid longitude.
206 */
207 public function setLongitude(float $lon)
208 {
209 if ($lon < -180 || $lon > 180)
210 throw new DomainException(
211 sprintf('Value %s is not in the range -180-+180.', $lon)
212 );
213 $this->lon = $lon;
214 }
215
216 /**
217 * Fetch the elevation of the point.
218 *
219 * @return float|null The elevation in meters or null if not set.
220 */
221 public function getEle()
222 {
223 return $this->ele;
224 }
225
226 /**
227 * Set the elevation of the point.
228 *
229 * @param float $ele The elevation in meters or null to delete.
230 * @return void
231 */
232 public function setEle(float $ele = null)
233 {
234 $this->ele = $ele;
235 }
236
237 /**
238 * Fetch the creation time of the point.
239 *
240 * @return DateTimeInterface|null The time or null if not set.
241 */
242 public function getTime()
243 {
244 return $this->time;
245 }
246
247 /**
248 * Set the creation time of the point.
249 *
250 * @param DateTimeInterface $time The creation time or null to delete.
251 * @return void
252 */
253 public function setTime(DateTimeInterface $time = null)
254 {
255 $this->time = $time;
256 }
257
258 /**
259 * Fetch the magnetic variation.
260 *
261 * @return float|null The magnetic variation in degrees or null if not set.
262 */
263 public function getMagvar()
264 {
265 return $this->magvar;
266 }
267
268 /**
269 * Set the magnetic variation.
270 *
271 * @param float $magvar The magnetic variation in degrees or null to delete.
272 * @return void
273 * @throws DomainException if not in range 0 <= value < 360
274 */
275 public function setMagvar(float $magvar = null)
276 {
277 if (
278 $magvar !== null
279 && ($magvar < 0 || $magvar >= 360)
280 ) {
281 throw new DomainException(
282 sprintf('Value %s is not in the range 0 <= value < 360.', $lon)
283 );
284 }
285 $this->magvar = $magvar;
286 }
287
288 /**
289 * Fetch the geoid height at the point.
290 *
291 * @return float The geoid height in meters.
292 */
293 public function getGeoidHeight()
294 {
295 return $this->geoidheight;
296 }
297
298 /**
299 * Set the geoid height at the point.
300 *
301 * @param float $geoidheight The geoid height in meters.
302 * @return void
303 */
304 public function setGeoidHeight(float $geoidheight = null)
305 {
306 $this->geoidheight = $geoidheight;
307 }
308
f528d248
AS
309 /**
310 * Fetch the waypoint symbol.
311 *
312 * @return string|null The symbol or null if not set.
313 */
314 public function getSymbol()
315 {
316 return $this->symbol;
317 }
318
319 /**
320 * Set the symbol representing this point.
321 *
322 * @param string $symbol The name of the symbol or null to delete.
323 * @return void
324 */
325 public function setSymbol(string $symbol = null)
326 {
327 $this->symbol = $symbol;
328 }
329
f528d248
AS
330 /**
331 * Fetch the fix type for this point.
332 *
333 * @return string|null The fix type or null if not set.
334 */
335 public function getFix()
336 {
337 return $this->fix;
338 }
339
340 /**
341 * Set the fix type.
342 *
343 * @param string $fix "none", "2d", "3d", "dgps", "pps" or null to delete.
344 * @return void
345 * @throws DomainException If an invalid fix type is passed.
346 */
347 public function setFix(string $fix = null)
348 {
349 if ($fix !== null && !in_array($fix, ['none', '2d', '3d', 'dgps', 'pps']))
350 throw new DomainException(sprintf('Unknown fix type "%s"', $fix));
351 $this->fix = $fix;
352 }
353
354 /**
355 * Fetch the number of satellites used to calculate the fix.
356 *
357 * @return int The number of satellites or null if not set.
358 */
359 public function getSatellites()
360 {
361 return $this->satellites;
362 }
363
364 /**
365 * Set the number of satellites used to calculate the fix.
366 *
367 * @param int $satellites The number if satellites or null to delete.
368 * @return void
369 * @throws DomainException If $satellites < 0
370 */
371 public function setSatellites(int $satellites = null)
372 {
373 if ($satellites !== null && $satellites < 0)
374 throw new DomainException(
375 sprintf('Satellites must be >= 0 but got %s', $satellites)
376 );
377 $this->satellites = $satellites;
378 }
379
380 /**
381 * Fetch the hdop of the point.
382 *
383 * @return float|null The hdop or null if not set.
384 */
385 public function getHdop()
386 {
387 return $this->hdop;
388 }
389
390 /**
391 * Set the hdop of the point.
392 *
393 * @param float $hdop The hdop or null to delete.
394 * @return void
395 */
396 public function setHdop(float $hdop = null)
397 {
398 $this->hdop = $hdop;
399 }
400
401 /**
402 * Fetch the vdop of the point.
403 *
404 * @return float|null The vdop or null if not set.
405 */
406 public function getVdop()
407 {
408 return $this->vdop;
409 }
410
411 /**
412 * Set the vdop of the point.
413 *
414 * @param float $vdop The vdop or null to delete.
415 * @return void
416 */
417 public function setVdop(float $vdop = null)
418 {
419 $this->vdop = $vdop;
420 }
421
422 /**
423 * Fetch the pdop of the point.
424 *
425 * @return float|null The pdop or null if not set.
426 */
427 public function getPdop()
428 {
429 return $this->pdop;
430 }
431
432 /**
433 * Set the pdop of the point.
434 *
435 * @param float $pdop The pdop or null to delete.
436 * @return void
437 */
438 public function setPdop(float $pdop = null)
439 {
440 $this->pdop = $pdop;
441 }
442
443 /**
444 * Fetch the age of the DGPS data.
445 *
446 * @return float The age of DGPS data in seconds or null if not set.
447 */
448 public function getAgeOfDGPSData()
449 {
450 return $this->ageofdgpsdata;
451 }
452
453 /**
454 * Set the age of the DGPS data.
455 *
456 * @param float $ageofdgpsdata The age in seconds or null to delete.
457 * @return void
458 */
459 public function setAgeOfDGPSData(float $ageofdgpsdata = null)
460 {
461 $this->ageofdgpsdata = $ageofdgpsdata;
462 }
463
464 /**
465 * Fetch the id of the DGPS station.
466 *
467 * @return int The DGPS id or null if not set.
468 */
469 public function getDGPSId()
470 {
471 return $this->dgpsid;
472 }
473
474 /**
475 * Set the id of the DGPS station.
476 *
477 * @param int $dgpsid The station id.
478 * @return void
479 * @throws DomainException If the station id < 0 or > 1023.
480 */
481 public function setDGPSId(int $dgpsid = null)
482 {
483 if ($dgpsid !== null && ($dgpsid < 0 || $dgpsid > 1023))
484 throw new DomainException(
485 sprintf('DGPS id must be >= 0 and <= 1023 but got %s', $dgpsid)
486 );
487 return $this->dgpsid = $dgpsid;
488 }
489
f528d248
AS
490 /**
491 * Fetch a bounding box that covers the feature.
492 *
493 * @return Bounds|null A bounding box covering the extent of the feature or
494 * null if not applicable.
495 */
496 public function getBounds()
497 {
498 return new Bounds($this->lat, $this->lon, $this->lat, $this->lon);
499 }
d23d8f6f
AS
500
501 /**
502 * Fetch the length of a point.
503 *
504 * Note: Length is the distance between two points so calling this function
505 * on a single point makes little sense. It is implemented to complete
506 * the `Geographic` interface and will always return a value of 0.
507 *
508 * @return float The length in meters.
509 */
510 public function getLength()
511 {
512 return 0.0;
513 }
514
515 /**
516 * Find the distance to another point.
517 *
518 * @param Point $point The point to find the distance to.
519 * @return float The distance in meters.
520 */
521 public function distanceTo(Point $point)
522 {
523 return libgpx::distance(
524 $this->lat,
525 $this->lon,
526 $point->getLatitude(),
527 $point->getLongitude()
528 );
529 }
530
f528d248 531}