]> git.street.me.uk Git - andy/gpx.git/blame - src/libgpx/track.php
Bugfix: Timestamps not converted to UTC when writing GPX
[andy/gpx.git] / src / libgpx / track.php
CommitLineData
35c309cc
AS
1<?php
2/**
3 * tracksegment.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
893cb1f3
AS
27use \ArrayAccess;
28use \Countable;
35c309cc 29use \DomainException;
893cb1f3 30use \IteratorAggregate;
35c309cc
AS
31
32/**
33 * A GPX trk type.
34 *
35 * @author Andy Street <andy@street.me.uk>
36 */
893cb1f3
AS
37class Track extends DataType
38 implements Geographic, ArrayAccess, Countable, IteratorAggregate
35c309cc
AS
39{
40
41 /**
42 * GPS track number.
43 *
44 * @var int
45 */
46 protected $number;
47
48 /**
49 * A list of track segments.
50 *
51 * @var DoublyLinkedList (TrackSegment)
52 *
53 */
54 protected $segments;
55
56 /**
57 * Fetch the track number.
58 *
59 * @return int|null The route number or null if not set.
60 */
61 public function getNumber()
62 {
63 return $this->number;
64 }
65
66 /**
67 * Set the number of the track.
68 *
69 * @param int $number The route number or null to delete.
70 * @return void
71 * @throws DomainException If the number is < 0
72 */
73 public function setNumber(int $number = null)
74 {
75 if ($number !== null && $number < 0)
76 throw new DomainException(
77 sprintf('Number must be >= 0 but got "%s"', $number)
78 );
79 $this->number = $number;
80 }
81
893cb1f3
AS
82 /**
83 * Count the number of track points.
84 *
85 * @return The number of track points contained in all the segments of this
86 * track.
87 */
88 public function countTrackPoints()
89 {
90 $count = 0;
91 if ($this->segments !== null) {
92 foreach ($this->segments as $segment) {
93 $count += count($segment);
94 }
95 }
96 return $count;
97 }
98
35c309cc
AS
99 /**
100 * Fetch an ordered list of track segments.
101 *
102 * @param boolean $create Create the list if it does not already exist.
103 * @return TypedDoublyLinkedList|null A list of track segments.
104 */
105 public function getSegments(bool $create = true)
106 {
107 if ($create && $this->segments === null)
108 $this->segments = new TypedDoublyLinkedList('libgpx\TrackSegment');
109 return $this->segments;
110 }
111
112 /**
113 * Fetch a bounding box that covers the feature.
114 *
115 * @return Bounds|null A bounding box covering the extent of the feature or
116 * null if not applicable.
117 */
118 public function getBounds()
119 {
120 $result = null;
121 if ($this->segments !== null) {
122 foreach ($this->segments as $segment) {
123 $bounds = $segment->getBounds();
edfdcdd3
AS
124 if ($result === null) {
125 $result = $bounds;
126 } else {
127 $result->extend($bounds);
128 }
35c309cc
AS
129 }
130 }
131 return $result;
132 }
133
d23d8f6f
AS
134 /**
135 * Fetch the length of a track.
136 *
137 * @return float The length in meters.
138 */
139 public function getLength()
140 {
141 $length = 0;
142 $segments = $this->getSegments(false);
143 if ($segments !== null) {
144 foreach ($segments as $segment) {
145 $length += $segment->getLength();
146 }
147 }
148 return $length;
149 }
150
893cb1f3
AS
151 /**
152 * Check if an offset holds a value.
153 *
154 * @see ArrayAccess::offsetExists
155 *
156 * @param mixed $offset The offset to search
157 * @return boolean
158 */
159 public function offsetExists($offset)
160 {
161 return $this->getSegments()->offsetExists($offset);
162 }
163
164 /**
165 * Fetch a segment from this track.
166 *
167 * @see ArrayAccess::offsetGet
168 *
169 * @param mixed $offset The offset to retrieve
170 * @return TrackSegment
171 */
172 public function offsetGet($offset)
173 {
174 return $this->getSegments()->offsetGet($offset);
175 }
176
177 /**
178 * Set the segment at an offset.
179 *
180 * @see ArrayAccess::offsetSet
181 *
182 * @param mixed $offset Where to store the segment.
183 * @param TrackSegment $value The segment to store.
184 * @return void
185 */
186 public function offsetSet($offset, $value)
187 {
188 return $this->getSegments()->offsetSet($offset, $value);
189 }
190
191 /**
192 * Remove a segment.
193 *
194 * @see ArrayAccess::offsetUnset
195 *
196 * @param mixed $offset Which segment to remove
197 * @return void
198 */
199 public function offsetUnset($offset)
200 {
201 return $this->getSegments()->offsetUnset($offset);
202 }
203
204 /**
205 * Count the number of segments in this track.
206 *
207 * @return int
208 */
209 public function count()
210 {
211 return ($this->segments === null ? 0 : $this->segments->count());
212 }
213
214 /**
215 * Fetch an iterator for the segments contained in this track.
216 *
217 * @return \Iterator
218 */
219 public function getIterator() {
220 return $this->getSegments();
221 }
222
35c309cc 223}