]> git.street.me.uk Git - andy/gpx.git/blame - src/libgpx/route.php
Add length measurement to geographic classes
[andy/gpx.git] / src / libgpx / route.php
CommitLineData
f17d2566
AS
1<?php
2/**
3 * route.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;
28
29/**
30 * The GPX route type.
31 *
32 * @see https://www.topografix.com/GPX/1/1/#type_rteType
33 *
34 * @author Andy Street <andy@street.me.uk>
35 */
09a36623 36class Route extends DataType implements Geographic
f17d2566
AS
37{
38
f17d2566
AS
39 /**
40 * GPS route number.
41 *
42 * @var int
43 */
44 protected $number;
45
f17d2566
AS
46 /**
47 * A list of route points.
48 *
49 * @var DoublyLinkedList (Point)
50 */
51 protected $points;
52
f17d2566
AS
53 /**
54 * Fetch the route number.
55 *
56 * @return int|null The route number or null if not set.
57 */
58 public function getNumber()
59 {
60 return $this->number;
61 }
62
63 /**
64 * Set the number of the route.
65 *
66 * @param int $number The route number or null to delete.
67 * @return void
68 * @throws DomainException If the number is < 0
69 */
70 public function setNumber(int $number = null)
71 {
72 if ($number !== null && $number < 0)
73 throw new DomainException(
74 sprintf('Number must be >= 0 but got "%s"', $number)
75 );
76 $this->number = $number;
77 }
78
f17d2566
AS
79 /**
80 * Fetch an ordered list of route points.
81 *
82 * @param boolean $create Create the list if it does not already exist.
83 * @return TypedDoublyLinkedList|null A list of route points.
84 */
85 public function getPoints(bool $create = true)
86 {
87 if ($create && $this->points === null)
88 $this->points = new TypedDoublyLinkedList('libgpx\Point');
89 return $this->points;
90 }
91
92 /**
93 * Fetch a bounding box that covers the feature.
94 *
95 * @return Bounds|null A bounding box covering the extent of the feature or
96 * null if not applicable.
97 */
98 public function getBounds()
99 {
100 $result = null;
101 if ($this->points !== null) {
102 foreach ($this->points as $point) {
103 $bounds = $point->getBounds();
104 $result = ($result === null ? $bounds : $result->extend($bounds));
105 }
106 }
107 return $result;
108 }
109
d23d8f6f
AS
110 /**
111 * Fetch the length of a route.
112 *
113 * @return float The length in meters.
114 */
115 public function getLength()
116 {
117 $length = 0;
118 $points = $this->getPoints(false);
119 if ($points !== null && !$points->isEmpty()) {
120 $last_point = null;
121 foreach ($points as $current_point) {
122 if ($last_point !== null)
123 $length += libgpx::distance(
124 $last_point->getLatitude(),
125 $last_point->getLongitude(),
126 $current_point->getLatitude(),
127 $current_point->getLongitude()
128 );
129 $last_point = $current_point;
130 }
131 }
132 return $length;
133 }
134
f17d2566 135}