/** * Get a workout from a string. * * @param string $string The data. * @return \SportTrackerConnector\Workout\Workout */ public function fromString($string) { $simpleXML = new SimpleXMLElement($string); $workout = new Workout(); foreach ($simpleXML->Activities[0] as $simpleXMLActivity) { $workoutTrack = new Track(); // Sport. $attributes = $simpleXMLActivity->attributes(); if (isset($attributes['Sport'])) { $workoutTrack->setSport(SportGuesser::getSportFromCode((string) $attributes['Sport'])); } // Track points. foreach ($simpleXMLActivity->Lap as $lap) { foreach ($lap->Track as $track) { foreach ($track->Trackpoint as $trackPoint) { $dateTime = new DateTime($trackPoint->Time); $latitude = (string) $trackPoint->Position->LatitudeDegrees; $longitude = (string) $trackPoint->Position->LongitudeDegrees; $workoutTrackPoint = new TrackPoint($latitude, $longitude, $dateTime); $workoutTrackPoint->setElevation(round((double) $trackPoint->AltitudeMeters, 2)); if ($trackPoint->DistanceMeters) { $workoutTrackPoint->setDistance($trackPoint->DistanceMeters); } $extensions = $this->parseExtensions($trackPoint); $workoutTrackPoint->setExtensions($extensions); $workoutTrack->addTrackPoint($workoutTrackPoint); } } } $workout->addTrack($workoutTrack); } return $workout; }
/** * Download a workout. * * @param integer $idWorkout The ID of the workout to download. * @return Workout */ public function downloadWorkout($idWorkout) { $this->logger->debug('Downloading JSON for workout "' . $idWorkout . '"'); $json = $this->getEndomondoAPI()->getWorkout($idWorkout); $workout = new Workout(); $track = new Track(); $track->setSport($this->getSportMapper()->getSportFromCode($json['sport'])); if (isset($json['points'])) { $this->logger->debug('Writing track points.'); foreach ($json['points'] as $point) { $trackPoint = new TrackPoint($point['lat'], $point['lng'], new DateTime($point['time'], $this->getTimeZone())); if (isset($point['alt'])) { $trackPoint->setElevation($point['alt']); } if (isset($point['hr'])) { $trackPoint->addExtension(new HR($point['hr'])); } $track->addTrackPoint($trackPoint); } } else { $this->logger->warning('No track points found for workout "' . $idWorkout . '".'); } $workout->addTrack($track); return $workout; }
/** * Get a workout from a string. * * @param string $string The data. * @return \SportTrackerConnector\Workout\Workout */ public function fromString($string) { $simpleXML = new SimpleXMLElement($string); $workout = new Workout(); if (isset($simpleXML->metadata->author->name)) { $workout->setAuthor(new Author($simpleXML->metadata->author->name)); } foreach ($simpleXML->trk as $simpleXMLTrack) { $track = new Track(); // Sport. if (isset($simpleXMLTrack->type)) { $track->setSport(SportGuesser::getSportFromCode($simpleXMLTrack->type)); } // Track points. foreach ($simpleXMLTrack->trkseg->trkpt as $point) { $attributes = $point->attributes(); $dateTime = new DateTime($point->time); $trackPoint = new TrackPoint((string) $attributes['lat'], (string) $attributes['lon'], $dateTime); $trackPoint->setElevation((int) $point->ele); if (isset($point->extensions)) { $trackPoint->setExtensions($this->parseExtensions($point->extensions)); } $track->addTrackPoint($trackPoint); } $workout->addTrack($track); } return $workout; }
/** * Write the heart rate data for a lap. * * @param XMLWriter $xmlWriter The XML writer. * @param \SportTrackerConnector\Workout\Workout\Track $track The track to write. */ private function writeLapHeartRateDate(XMLWriter $xmlWriter, Track $track) { $averageHeartRate = array(); $maxHearRate = null; foreach ($track->getTrackPoints() as $trackPoint) { if ($trackPoint->hasExtension(HR::ID) === true) { $pointHearRate = $trackPoint->getExtension(HR::ID)->getValue(); $maxHearRate = max($maxHearRate, $pointHearRate); $averageHeartRate[] = $pointHearRate; } } if ($averageHeartRate !== array()) { $xmlWriter->startElement('AverageHeartRateBpm'); $xmlWriter->writeAttributeNs('xsi', 'type', null, 'HeartRateInBeatsPerMinute_t'); $xmlWriter->writeElement('Value', array_sum($averageHeartRate) / count($averageHeartRate)); $xmlWriter->endElement(); } if ($maxHearRate !== null) { $xmlWriter->startElement('MaximumHeartRateBpm'); $xmlWriter->writeAttributeNs('xsi', 'type', null, 'HeartRateInBeatsPerMinute_t'); $xmlWriter->writeElement('Value', $maxHearRate); $xmlWriter->endElement(); } }
/** * Test downloading a workout with points. */ public function testDownloadWorkoutWithPoints() { $idWorkout = 1; $stravaAPI = $this->getStravaAPIMock(array('getWorkout')); $stravaAPI->expects($this->once())->method('getWorkout')->with($idWorkout)->willReturn(array('latlng' => array(array('10.0', '53.0'), array('10.1', '53.1'), array('10.2', '53.2')), 'time' => array(new \DateTime('2014-07-27 20:33:15', new \DateTimeZone('UTC')), new \DateTime('2014-07-27 20:33:16', new \DateTimeZone('UTC')), new \DateTime('2014-07-27 20:33:17', new \DateTimeZone('UTC'))), 'altitude' => array(0, 10, -2), 'heartrate' => array(130, 140, 150))); $logger = $this->getMockForAbstractClass('Psr\\Log\\LoggerInterface'); $accessToken = '1234567890abc'; $strava = $this->getMock('SportTrackerConnector\\Tracker\\Strava\\Tracker', array('getStravaAPI'), array($logger, $accessToken)); $strava->expects($this->once())->method('getStravaAPI')->willReturn($stravaAPI); $actual = $strava->downloadWorkout($idWorkout); $expected = new Workout(); $track = new Track(); $track->addTrackPoint($this->getTrackPoint(10, 53, '2014-07-27 20:33:15', 0, 130)); $track->addTrackPoint($this->getTrackPoint(10.1, 53.1, '2014-07-27 20:33:16', 10, 140)); $track->addTrackPoint($this->getTrackPoint(10.2, 53.2, '2014-07-27 20:33:17', -2, 150)); $expected->addTrack($track); $this->assertEquals($expected, $actual); }
/** * Download a workout. * * @param integer $idWorkout The ID of the workout to download. * @return Workout */ public function downloadWorkout($idWorkout) { $this->logger->debug('Downloading JSON summary for workout "' . $idWorkout . '"'); $workout = new Workout(); $track = new Track(); try { $workoutDetails = $this->getStravaAPI()->getWorkout($idWorkout); $this->logger->debug('Writing track points.'); $pointsSize = count(reset($workoutDetails)); for ($i = 0; $i < $pointsSize; $i++) { $latitude = $workoutDetails['latlng'][$i][0]; $longitude = $workoutDetails['latlng'][$i][1]; $dateTime = $workoutDetails['time'][$i]; $dateTime->setTimezone($this->getTimeZone()); $trackPoint = new TrackPoint($latitude, $longitude, $dateTime); if (isset($workoutDetails['altitude'])) { $trackPoint->setElevation($workoutDetails['altitude'][$i]); } if (isset($workoutDetails['heartrate'])) { $trackPoint->addExtension(new HR($workoutDetails['heartrate'][$i])); } $track->addTrackPoint($trackPoint); } } catch (NoTrackPointsFoundException $e) { $this->logger->warning('No track points found for workout "' . $idWorkout . '".'); } $workout->addTrack($track); return $workout; }
/** * Test downloading a workout with points. */ public function testDownloadWorkoutWithPoints() { $idWorkout = 1; $endomondoAPI = $this->getEndomondoAPIMock(array('getWorkout')); $endomondoAPI->expects($this->once())->method('getWorkout')->with($idWorkout)->willReturn(array('sport' => 15, 'points' => array(array('lat' => '10.0', 'lng' => '53.0', 'time' => '2014-07-27 20:33:15'), array('lat' => '10.1', 'lng' => '53.1', 'time' => '2014-07-27 20:33:16', 'alt' => 10, 'hr' => 140), array('lat' => '10.2', 'lng' => '53.2', 'time' => '2014-07-27 20:33:17', 'alt' => -2, 'hr' => 150)))); $logger = $this->getMockForAbstractClass('Psr\\Log\\LoggerInterface'); $endomondo = $this->getMock('SportTrackerConnector\\Tracker\\Endomondo\\Tracker', array('getEndomondoAPI'), array($logger)); $endomondo->expects($this->once())->method('getEndomondoAPI')->willReturn($endomondoAPI); $actual = $endomondo->downloadWorkout($idWorkout); $expected = new Workout(); $track = new Track(); $track->setSport(SportMapperInterface::GOLF); $track->addTrackPoint($this->getTrackPoint(10, 53, '2014-07-27 20:33:15')); $track->addTrackPoint($this->getTrackPoint(10.1, 53.1, '2014-07-27 20:33:16', 10, 140)); $track->addTrackPoint($this->getTrackPoint(10.2, 53.2, '2014-07-27 20:33:17', -2, 150)); $expected->addTrack($track); $this->assertEquals($expected, $actual); }
/** * Post the workout end data. * * TODO Implement. * * @param Track $track The track. * @param float $speed The speed for the last point. * @return string The workout ID. */ private function flattenEndWorkoutTrackPoint(Track $track, $speed) { $endDateTime = clone $track->getEndDateTime(); $endDateTime->setTimezone(new \DateTimeZone('UTC')); $distance = $track->getLength(); $lastTrackPoint = $track->getLastTrackPoint(); $totalAscent = $lastTrackPoint->getElevation(); // TODO Compute it from the track, this is not correct. return $this->formatEndomondoTrackPoint($endDateTime, self::INSTRUCTION_STOP, $lastTrackPoint->getLatitude(), $lastTrackPoint->getLongitude(), $distance, $speed, $totalAscent, $lastTrackPoint->hasExtension(HR::ID) ? $lastTrackPoint->getExtension(HR::ID)->getValue() : ''); }