/** * @return array */ public function sliceElevation() { if ($this->Object->hasCorrectedElevations()) { return $this->slice(Object::ELEVATIONS_CORRECTED); } elseif ($this->Object->hasOriginalElevations()) { return $this->slice(Object::ELEVATIONS_ORIGINAL); } return array(); }
/** * Tasks before insertion */ protected function before() { parent::before(); $Calculator = new Calculator($this->Object); if (Configuration::ActivityForm()->correctElevation() && !$this->Object->hasCorrectedElevations()) { $Calculator->tryToCorrectElevation(); } $Calculator->calculateElevation(); }
public function testElevationCalculation() { $R = new Object(array(Object::ELEVATIONS_CORRECTED => array(100, 120, 110))); $I = new Inserter($this->PDO, $R); $I->setAccountID(0); $I->insert(); $data = $this->PDO->query('SELECT * FROM `' . PREFIX . 'route` WHERE `accountid`=0')->fetch(PDO::FETCH_ASSOC); $N = new Object($data); $this->assertGreaterThan(0, $N->elevation()); $this->assertGreaterThan(0, $N->elevationUp()); $this->assertGreaterThan(0, $N->elevationDown()); }
/** * Construct collector * @param \Runalyze\Model\Trackdata\Object $trackdata * @param enum $key * @param \Runalyze\Model\Route\Object $route * @throws \InvalidArgumentException */ public function __construct(Trackdata $trackdata, $key, Route $route) { if (!$route->has($key)) { throw new \InvalidArgumentException('Route has no data for "' . $key . '".'); } $this->Key = $key; $this->Precision = Configuration::ActivityView()->plotPrecision(); $this->KnowsDistance = $trackdata->has(Trackdata::DISTANCE); $this->init($trackdata); $this->LoopRoute = new Loop($route); $this->collect(); }
public function testCorrection() { $Route = new Route\Object(array(Route\Object::LATITUDES => array(49.44, 49.441, 49.442, 49.443, 49.444, 49.445, 49.446, 49.447, 49.448, 49.449, 49.45), Route\Object::LONGITUDES => array(7.76, 7.761, 7.762, 7.763, 7.764, 7.765, 7.766, 7.767, 7.768, 7.769, 7.77))); $Calc = new Calculator($Route); if ($Calc->tryToCorrectElevation()) { $this->assertEmpty($Route->elevationsOriginal()); $this->assertNotEmpty($Route->elevationsCorrected()); $this->assertNotEmpty($Route->get(Route\Object::ELEVATIONS_SOURCE)); } else { $this->markTestSkipped('No elevation correction was not available.'); } }
public function testSimpleUpdate() { $Inserter = new Inserter($this->PDO); $Inserter->setAccountID(0); $Inserter->insert(new Object(array(Object::NAME => 'Route name', Object::DISTANCE => 3.14))); $Route = new Object($this->PDO->query('SELECT * FROM `' . PREFIX . 'route` WHERE `id`=' . $Inserter->insertedID())->fetch(PDO::FETCH_ASSOC)); $Route->set(Object::DISTANCE, 0); $Changed = clone $Route; $Changed->set(Object::NAME, 'New route name'); $Updater = new Updater($this->PDO, $Changed, $Route); $Updater->setAccountID(0); $Updater->update(); $Result = new Object($this->PDO->query('SELECT * FROM `' . PREFIX . 'route` WHERE `id`=' . $Inserter->insertedID())->fetch(PDO::FETCH_ASSOC)); $this->assertEquals('New route name', $Result->name()); $this->assertEquals(3.14, $Result->distance()); }
/** * Calculate VDOT by heart rate with elevation influence * @return float */ public function calculateVDOTbyHeartRateWithElevation() { if ($this->knowsRoute()) { if ($this->Route->elevationUp() > 0 || $this->Route->elevationDown() > 0) { return $this->calculateVDOTbyHeartRateWithElevationFor($this->Route->elevationUp(), $this->Route->elevationDown()); } return $this->calculateVDOTbyHeartRateWithElevationFor($this->Route->elevation(), $this->Route->elevation()); } return $this->calculateVDOTbyHeartRateWithElevationFor($this->Activity->elevation(), $this->Activity->elevation()); }
/** * 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\Object::DISTANCE))); $Tooltip .= '<br>' . sprintf(__('<strong>Time:</strong> %s'), Duration::format($this->Trackdata->at($Index, Trackdata\Object::TIME))); if ($Pause->hasHeartRateInfo()) { $Tooltip .= '<br>' . sprintf(__('<strong>Heart rate:</strong>') . ' ' . __('%s to %s'), $Pause->hrStart(), $Pause->hrEnd() . ' bpm'); } $this->addMarker($this->Route->at($Index, Route\Object::LATITUDES), $this->Route->at($Index, Route\Object::LONGITUDES), $this->pauseIcon(), $Tooltip); }
/** * Save changes for route */ protected function saveChangesForRoute() { if (null === $this->Route || $this->OldRoute->isEmpty()) { return; } $this->Route->synchronize(); if ($this->Route->isEmpty()) { $Deleter = new Model\Route\Deleter($this->PDO, $this->Route); $Deleter->setAccountID($this->AccountID); $Deleter->delete(); $this->Route = null; $this->Activity->set(Object::ROUTEID, 0); $this->Activity->set(Object::ELEVATION, 0); } else { $Updater = new Model\Route\Updater($this->PDO, $this->Route, $this->OldRoute); $Updater->setAccountID($this->AccountID); $Updater->update(); } }
/** * Correct elevation data * * This method does directly update the route object. * * @return boolean false if correction did not work */ public function tryToCorrectElevation() { if (!$this->Route->hasPositionData()) { return false; } $Corrector = new Corrector(); $Corrector->correctElevation($this->Route->latitudes(), $this->Route->longitudes()); $result = $Corrector->getCorrectedElevation(); if (!empty($result)) { $this->Route->set(Route\Object::ELEVATIONS_CORRECTED, $result); $this->Route->set(Route\Object::ELEVATIONS_SOURCE, $Corrector->getNameOfUsedStrategy()); return true; } return false; }
/** * Calculate power array * * A constant factor of 1.5 was used in previous versions - and I don't know why. * Without this factor results equal standard tools. * * @author Nils Frohberg * @author Hannes Christiansen * @see http://www.blog.ultracycle.net/2010/05/cycling-power-calculations * @param int $weight [kg] Weight of rider and bike * @param float $powerFactor constant factor * @return array */ public function calculate($weight = 75, $powerFactor = 1.0) { if (!$this->Trackdata->has(Trackdata\Object::TIME) || !$this->Trackdata->has(Trackdata\Object::DISTANCE)) { return; } $everyNthPoint = ceil($this->Size / 1000); //self::$everyNthElevationPoint * ceil($this->Size/1000); $n = $everyNthPoint; $distance = 0; $grade = 0; $calcGrade = $this->knowsRoute() && $this->Route->hasElevations(); $ArrayTime = $this->Trackdata->time(); $ArrayDist = $this->Trackdata->distance(); $ArrayElev = $this->knowsRoute() ? $this->Route->elevations() : array(); $Frl = $weight * self::GRAVITY * self::CRR; $Fwpr = 0.5 * self::AREA * self::CW * $this->rho(); $Fslp = $weight * self::GRAVITY; for ($i = 0; $i < $this->Size - 1; $i++) { if ($i % $everyNthPoint == 0) { if ($i + $n > $this->Size - 1) { $n = $this->Size - $i - 1; } $distance = ($ArrayDist[$i + $n] - $ArrayDist[$i]) * 1000; $grade = $distance == 0 || !$calcGrade ? 0 : ($ArrayElev[$i + $n] - $ArrayElev[$i]) / $distance; } $distance = $ArrayDist[$i + 1] - $ArrayDist[$i]; $time = $ArrayTime[$i + 1] - $ArrayTime[$i]; if ($time > 0) { $Vmps = $distance * 1000 / $time; $Fw = $Fwpr * $Vmps * $Vmps; $Fsl = $Fslp * $grade; $this->Power[] = round(max($powerFactor * ($Frl + $Fw + $Fsl) * $Vmps, 0)); } else { $this->Power[] = 0; } } $this->Power[] = $this->Power[$this->Size - 2]; /* XXX */ return $this->Power; }
/** * Keys to insert * @return array */ protected function keys() { return array_merge(array(self::ACCOUNTID), Object::allProperties()); }