* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * */ namespace libgpx; use \ArrayAccess; use \Countable; use \DomainException; use \IteratorAggregate; /** * A GPX trk type. * * @author Andy Street */ class Track extends DataType implements Geographic, ArrayAccess, Countable, IteratorAggregate { /** * GPS track number. * * @var int */ protected $number; /** * A list of track segments. * * @var DoublyLinkedList (TrackSegment) * */ protected $segments; /** * Fetch the track number. * * @return int|null The route number or null if not set. */ public function getNumber() { return $this->number; } /** * Set the number of the track. * * @param int $number The route number or null to delete. * @return void * @throws DomainException If the number is < 0 */ public function setNumber(int $number = null) { if ($number !== null && $number < 0) throw new DomainException( sprintf('Number must be >= 0 but got "%s"', $number) ); $this->number = $number; } /** * Count the number of track points. * * @return The number of track points contained in all the segments of this * track. */ public function countTrackPoints() { $count = 0; if ($this->segments !== null) { foreach ($this->segments as $segment) { $count += count($segment); } } return $count; } /** * Fetch an ordered list of track segments. * * @param boolean $create Create the list if it does not already exist. * @return TypedDoublyLinkedList|null A list of track segments. */ public function getSegments(bool $create = true) { if ($create && $this->segments === null) $this->segments = new TypedDoublyLinkedList('libgpx\TrackSegment'); return $this->segments; } /** * Fetch a bounding box that covers the feature. * * @return Bounds|null A bounding box covering the extent of the feature or * null if not applicable. */ public function getBounds() { $result = null; if ($this->segments !== null) { foreach ($this->segments as $segment) { $bounds = $segment->getBounds(); if ($result === null) { $result = $bounds; } else { $result->extend($bounds); } } } return $result; } /** * Fetch the length of a track. * * @return float The length in meters. */ public function getLength() { $length = 0; $segments = $this->getSegments(false); if ($segments !== null) { foreach ($segments as $segment) { $length += $segment->getLength(); } } return $length; } /** * Check if an offset holds a value. * * @see ArrayAccess::offsetExists * * @param mixed $offset The offset to search * @return boolean */ public function offsetExists($offset) { return $this->getSegments()->offsetExists($offset); } /** * Fetch a segment from this track. * * @see ArrayAccess::offsetGet * * @param mixed $offset The offset to retrieve * @return TrackSegment */ public function offsetGet($offset) { return $this->getSegments()->offsetGet($offset); } /** * Set the segment at an offset. * * @see ArrayAccess::offsetSet * * @param mixed $offset Where to store the segment. * @param TrackSegment $value The segment to store. * @return void */ public function offsetSet($offset, $value) { return $this->getSegments()->offsetSet($offset, $value); } /** * Remove a segment. * * @see ArrayAccess::offsetUnset * * @param mixed $offset Which segment to remove * @return void */ public function offsetUnset($offset) { return $this->getSegments()->offsetUnset($offset); } /** * Count the number of segments in this track. * * @return int */ public function count() { return ($this->segments === null ? 0 : $this->segments->count()); } /** * Fetch an iterator for the segments contained in this track. * * @return \Iterator */ public function getIterator() { return $this->getSegments(); } }