5 * Copyright 2018 Andy Street <andy@street.me.uk>
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.
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.
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,
30 use \IteratorAggregate;
35 * @see https://www.topografix.com/GPX/1/1/#type_rteType
37 * @author Andy Street <andy@street.me.uk>
39 class Route extends DataType
40 implements Geographic, ArrayAccess, Countable, IteratorAggregate
51 * A list of route points.
53 * @var DoublyLinkedList (Point)
58 * Fetch the route number.
60 * @return int|null The route number or null if not set.
62 public function getNumber()
68 * Set the number of the route.
70 * @param int $number The route number or null to delete.
72 * @throws DomainException If the number is < 0
74 public function setNumber(int $number = null)
76 if ($number !== null && $number < 0)
77 throw new DomainException(
78 sprintf('Number must be >= 0 but got "%s"', $number)
80 $this->number = $number;
84 * Fetch an ordered list of route points.
86 * @param boolean $create Create the list if it does not already exist.
87 * @return TypedDoublyLinkedList|null A list of route points.
89 public function getPoints(bool $create = true)
91 if ($create && $this->points === null)
92 $this->points = new TypedDoublyLinkedList('libgpx\Point');
97 * Fetch a bounding box that covers the feature.
99 * @return Bounds|null A bounding box covering the extent of the feature or
100 * null if not applicable.
102 public function getBounds()
105 if ($this->points !== null) {
106 foreach ($this->points as $point) {
107 $bounds = $point->getBounds();
108 $result = ($result === null ? $bounds : $result->extend($bounds));
115 * Fetch the length of a route.
117 * @return float The length in meters.
119 public function getLength()
122 $points = $this->getPoints(false);
123 if ($points !== null && !$points->isEmpty()) {
125 foreach ($points as $current_point) {
126 if ($last_point !== null)
127 $length += libgpx::distance(
128 $last_point->getLatitude(),
129 $last_point->getLongitude(),
130 $current_point->getLatitude(),
131 $current_point->getLongitude()
133 $last_point = $current_point;
140 * Check if an offset holds a value.
142 * @see ArrayAccess::offsetExists
144 * @param mixed $offset The offset to search
147 public function offsetExists($offset)
149 return $this->getPoints()->offsetExists($offset);
153 * Fetch a point from this route.
155 * @see ArrayAccess::offsetGet
157 * @param mixed $offset The offset to retrieve
160 public function offsetGet($offset)
162 return $this->getPoints()->offsetGet($offset);
166 * Set the point at an offset.
168 * @see ArrayAccess::offsetSet
170 * @param mixed $offset Where to store the point.
171 * @param Point $value The point to store.
174 public function offsetSet($offset, $value)
176 return $this->getPoints()->offsetSet($offset, $value);
182 * @see ArrayAccess::offsetUnset
184 * @param mixed $offset Which point to remove
187 public function offsetUnset($offset)
189 return $this->getPoints()->offsetUnset($offset);
193 * Count the number of points in this route.
197 public function count()
199 return ($this->points === null ? 0 : $this->points->count());
203 * Fetch an iterator for the points contained in this route.
207 public function getIterator() {
208 return $this->getPoints();