/** * Tasks after insertion */ protected function after() { parent::after(); if (Cache::is('trackdata' . $this->NewObject->activityID())) { Cache::delete('trackdata' . $this->NewObject->activityID()); } }
/** * Collect data */ protected function collectData() { $data = $this->Trackdata->get($this->IndexKey); $time = $this->Trackdata->get(Trackdata\Entity::TIME); $rawdata = array(); foreach (array_merge($this->SumDifferencesKeys, $this->AvgValuesKeys) as $key) { $rawdata[$key] = $this->Trackdata->get($key); } foreach ($data as $i => $val) { if (!isset($this->Data[$val])) { $this->Data[$val] = array(); foreach (array_merge($this->SumDifferencesKeys, $this->AvgValuesKeys) as $key) { $this->Data[$val][$key] = 0; } } foreach ($this->SumDifferencesKeys as $key) { $prev = $i == 0 ? 0 : $rawdata[$key][$i - 1]; $this->Data[$val][$key] += $rawdata[$key][$i] - $prev; } $timeDiff = $i == 0 ? $time[0] : $time[$i] - $time[$i - 1]; foreach ($this->AvgValuesKeys as $key) { $this->Data[$val][$key] += $rawdata[$key][$i] * $timeDiff; } } $this->calculateAverages(); }
/** * Calculate by trackdata * @param \Runalyze\Model\Trackdata\Entity $trackdata */ public function calculateByTrackdata(Trackdata\Entity $trackdata) { if (!$trackdata->has(Trackdata\Entity::HEARTRATE)) { return; } return $this->calculateByHeartrate(new TimeSeries($trackdata->get(Trackdata\Entity::HEARTRATE), $trackdata->get(Trackdata\Entity::TIME))); }
/** * Calculate average stride length * @return int [cm] */ public function average() { if (empty($this->Strides)) { return 0; } $Series = new TimeSeries($this->Strides, $this->Trackdata->time()); $Series->calculateStatistic(); return round($Series->mean()); }
/** * Init data * @param \Runalyze\Model\Trackdata\Entity $trackdata * @param string $key */ protected function fillGaps(Trackdata $trackdata, $key) { $data = $trackdata->get($key); $last = $data[0]; foreach ($data as &$val) { if ($val == 0) { $val = $last; } $last = $val; } $trackdata->set($key, $data); }
/** * Construct collector * @param \Runalyze\Model\Trackdata\Entity $trackdata * @param int $key * @param \Runalyze\Model\Swimdata\Entity $swimdata * @throws \InvalidArgumentException */ public function __construct(Trackdata $trackdata, $key, Swimdata $swimdata) { if (!$swimdata->has($key)) { throw new \InvalidArgumentException('Swimdata has no data for "' . $key . '".'); } $this->Key = $key; $this->Precision = Configuration::ActivityView()->plotPrecision(); $this->KnowsDistance = $trackdata->has(Trackdata::DISTANCE); $this->init($trackdata); $this->LoopSwimdata = new Loop($swimdata); $this->collect(); }
/** * Calculate average Vertical Ratio * @return int [%o] */ public function average() { if (empty($this->VerticalRatio)) { return 0; } if (!$this->Trackdata->has(Trackdata\Entity::TIME)) { return round(array_sum($this->VerticalRatio) / $this->Trackdata->num()); } $Series = new TimeSeries($this->VerticalRatio, $this->Trackdata->time()); $Series->calculateStatistic(); return round($Series->mean()); }
/** * Run fast smoothing for step size * * Although this does not look nice and is not the cleanest code, * direct access to the arrays is approx. 5-times faster. * (0.02s vs 0.11s for an array of 10.000 elements) */ protected function runFastSmoothingForSteps() { $distance = $this->Trackdata->distance(); $time = $this->Trackdata->time(); $lastDist = 0; $lastTime = 0; foreach ($distance as $i => $dist) { if ($i != 0 && $i % $this->StepSize == 0) { $pace = $dist - $lastDist > 0 ? round(($time[$i] - $lastTime) / ($dist - $lastDist)) : 0; if ($this->KeepArraySize) { for ($j = 0; $j < $this->StepSize; ++$j) { $this->Smoothed[] = $pace; } } else { $this->Smoothed[] = $pace; } $lastDist = $dist; $lastTime = $time[$i]; } } if ($this->KeepArraySize && !empty($distance)) { $pace = $dist - $lastDist > 0 ? round(($time[$i] - $lastTime) / ($dist - $lastDist)) : 0; for ($j = count($this->Smoothed), $num = $this->Trackdata->num(); $j < $num; ++$j) { $this->Smoothed[] = $pace; } } }
/** * Update power for trackdata * @param array $powerData */ protected function updatePowerForTrackdata(array $powerData) { if (null !== $this->Trackdata && (empty($powerData) && $this->Trackdata->has(Model\Trackdata\Entity::POWER) || !empty($powerData) && !$this->Trackdata->has(Model\Trackdata\Entity::POWER))) { $this->Trackdata->set(Model\Trackdata\Entity::POWER, $powerData); $TrackdataUpdater = new Model\Trackdata\Updater($this->PDO); $TrackdataUpdater->setAccountID($this->AccountID); $TrackdataUpdater->update($this->Trackdata, array(Model\Trackdata\Entity::POWER)); } }
/** * Add icon for current pause */ protected function addCurrentPauseIcon() { $Pause = $this->Trackdata->pauses()->at($this->PauseIndex); $Index = $this->RouteLoop->index(); $Tooltip = sprintf(__('<strong>Pause</strong> of %s'), Duration::format($Pause->duration())); $Tooltip .= '<br>' . sprintf(__('<strong>Distance:</strong> %s'), Distance::format($this->Trackdata->at($Index, Trackdata\Entity::DISTANCE))); $Tooltip .= '<br>' . sprintf(__('<strong>Time:</strong> %s'), Duration::format($this->Trackdata->at($Index, Trackdata\Entity::TIME))); if ($Pause->hasHeartRateInfo()) { $Tooltip .= '<br>' . sprintf(__('<strong>Heart rate:</strong>') . ' ' . __('%s to %s'), $Pause->hrStart(), $Pause->hrEnd() . ' bpm'); } $this->addMarkerGeohash($this->Route->at($Index, Route\Entity::GEOHASHES), $this->pauseIcon(), $Tooltip); }
/** * Calculate swim values */ protected function calculateSwimValues() { if (null !== $this->Trackdata && null !== $this->Swimdata) { if ($this->Swimdata->stroke()) { $this->Object->set(Entity::TOTAL_STROKES, array_sum($this->Swimdata->stroke())); } if ($this->Object->totalStrokes() && $this->Trackdata->totalTime()) { $num = $this->Trackdata->num(); $totaltime = $this->Trackdata->totalTime(); $totalstrokes = $this->Object->totalStrokes(); if (!empty($totalstrokes) && !empty($totaltime) & !empty($num) && $totalstrokes != 0) { $this->Object->set(Entity::SWOLF, round(($totalstrokes + $totaltime) / $num)); } } } }
/** * Save changes for trackdata */ protected function saveChangesForTrackdata() { if (null === $this->Trackdata || $this->OldTrackdata->isEmpty()) { return; } $this->Trackdata->synchronize(); if ($this->Trackdata->isEmpty()) { $Deleter = new Model\Trackdata\Deleter($this->PDO, $this->Trackdata); $Deleter->setAccountID($this->AccountID); $Deleter->delete(); $this->Trackdata = null; } else { $Updater = new Model\Trackdata\Updater($this->PDO, $this->Trackdata, $this->OldTrackdata); $Updater->setAccountID($this->AccountID); $Updater->update(); } }
/** * Calculate trimp * @return int */ public function calculateTrimp() { if ($this->knowsTrackdata() && $this->Trackdata->has(Model\Trackdata\Entity::HEARTRATE)) { $Collector = new Trimp\DataCollector($this->Trackdata->heartRate(), $this->Trackdata->time()); $data = $Collector->result(); } elseif ($this->Activity->hrAvg() > 0) { $data = array($this->Activity->hrAvg() => $this->Activity->duration()); } else { $Factory = Context::Factory(); if ($this->Activity->typeid() > 0) { $data = array($Factory->type($this->Activity->typeid())->hrAvg() => $this->Activity->duration()); } else { $data = array($Factory->sport($this->Activity->sportid())->avgHR() => $this->Activity->duration()); } } $Athlete = Context::Athlete(); $Calculator = new Trimp\Calculator($Athlete, $data); return round($Calculator->value()); }
/** * Calculate pace array * @param \Runalyze\Model\Trackdata\Entity $trackdata */ public function __construct(Trackdata\Entity $trackdata) { if ($trackdata->has(Trackdata\Entity::TIME) && $trackdata->has(Trackdata\Entity::DISTANCE)) { $this->Smoother = new PaceSmoother($trackdata, true); } }
/** * @return boolean */ public function hasTrackdata() { return !$this->Trackdata->isEmpty(); }
public function fillSwolfArray(Trackdata\Entity &$trackdata) { if ($this->stroke() && $trackdata->has(Trackdata\Entity::TIME)) { $TrackLoop = new Trackdata\Loop($trackdata); $Loop = new Loop($this); $max = $Loop->num(); $swolf = array(); $swolfcycles = array(); for ($i = 1; $i <= $max; ++$i) { $duration = $TrackLoop->difference(Trackdata\Entity::TIME); $swolf[] = $duration + $Loop->stroke(); $swolfcycles[] = $duration + $Loop->stroke() / 2; $Loop->nextStep(); $TrackLoop->nextStep(); } $this->set(Entity::SWOLF, $swolf); $this->set(Entity::SWOLFCYCLES, $swolfcycles); } }
/** * @param \Runalyze\Model\Trackdata\Entity $Object * @param array $AdditionalData */ protected function addTrackdataAveragesToDataFrom(Trackdata\Entity $Object, array &$AdditionalData) { $KeysToAverage = array(Activity\Entity::CADENCE => Trackdata\Entity::CADENCE, Activity\Entity::STRIDE_LENGTH => Trackdata\Entity::STRIDE_LENGTH, Activity\Entity::GROUNDCONTACT => Trackdata\Entity::GROUNDCONTACT, Activity\Entity::GROUNDCONTACT_BALANCE => Trackdata\Entity::GROUNDCONTACT_BALANCE, Activity\Entity::VERTICAL_OSCILLATION => Trackdata\Entity::VERTICAL_OSCILLATION, Activity\Entity::VERTICAL_RATIO => Trackdata\Entity::VERTICAL_RATIO, Activity\Entity::POWER => Trackdata\Entity::POWER); $NewLoop = new Trackdata\Loop($Object); $NewLoop->goToEnd(); foreach ($KeysToAverage as $objectKey => $trackdataKey) { if ($Object->has($trackdataKey)) { $AdditionalData[$objectKey] = $NewLoop->average($trackdataKey); } } }
/** * Keys to insert * @return array */ protected function keys() { return array_merge(array(self::ACCOUNTID), Entity::allDatabaseProperties()); }
/** * Define x-axis * @param \Runalyze\Model\Trackdata\Entity $trackdata */ protected function defineXAxis(Trackdata $trackdata) { if (Configuration::ActivityView()->usesTimeAsXAxis() && $trackdata->has(Trackdata::TIME) && $trackdata->totalTime() > 0) { $this->XAxis = self::X_AXIS_TIME; } elseif ($trackdata->has(Trackdata::DISTANCE) && $trackdata->totalDistance() > 0) { $this->XAxis = self::X_AXIS_DISTANCE; } elseif ($trackdata->has(Trackdata::TIME) && $trackdata->totalTime() > 0) { $this->XAxis = self::X_AXIS_TIME; } else { $this->XAxis = self::X_AXIS_INDEX; } }