added smooth transition of compass to newly received values for all platforms, except iOS.

This commit is contained in:
rachytski 2012-09-26 19:42:40 +03:00 committed by Alex Zolotarev
parent 7f507fda18
commit b7c0883f04
2 changed files with 83 additions and 2 deletions

View file

@ -7,6 +7,7 @@
#include "../yg/display_list.hpp"
#include "../anim/controller.hpp"
#include "../anim/angle_interpolation.hpp"
#include "../gui/controller.hpp"
@ -22,13 +23,13 @@ namespace location
{
State::State(Params const & p)
: base_t(p),
m_compassFilter(this),
m_hasPosition(false),
m_hasCompass(false),
m_isCentered(false),
m_locationProcessMode(ELocationDoNothing),
m_compassProcessMode(ECompassDoNothing)
{
m_drawHeading = m_compassFilter.GetHeadingRad();
m_locationAreaColor = p.m_locationAreaColor;
m_locationBorderColor = p.m_locationBorderColor;
m_compassAreaColor = p.m_compassAreaColor;
@ -149,6 +150,7 @@ namespace location
m_framework->ShowRectFixed(m2::AnyRectD(rect.Center(), a, m2::RectD(-dx/2, -dy/2, dx/2, dy/2)));
SetIsCentered(true);
CheckCompassRotation();
CheckFollowCompass();
m_locationProcessMode = ELocationCenterOnly;
@ -159,6 +161,7 @@ namespace location
m_framework->SetViewportCenter(center);
SetIsCentered(true);
CheckCompassRotation();
CheckFollowCompass();
break;
@ -178,7 +181,22 @@ namespace location
void State::OnCompassUpdate(location::CompassInfo const & info)
{
m_hasCompass = true;
double oldHeadingHalfError = m_compassFilter.GetHeadingHalfErrorRad();
m_compassFilter.OnCompassUpdate(info);
double newHeadingHalfError = m_compassFilter.GetHeadingHalfErrorRad();
/// re-caching threshold for compass accuracy is 5 degrees.
double reCachingThreshold = ang::DegreeToRad(5);
if (fabs(oldHeadingHalfError - newHeadingHalfError) > reCachingThreshold)
setIsDirtyDrawing(true);
CheckCompassRotation();
CheckFollowCompass();
m_framework->Invalidate();
}
@ -348,7 +366,7 @@ namespace location
{
double const orientationRadius = max(pxErrorRadius, 30.0 * visualScale());
// 0 angle is for North ("up"), but in our coordinates it's to the right.
double const headingRad = m_compassFilter.GetHeadingRad() - math::pi / 2.0;
double const headingRad = m_drawHeading - math::pi / 2.0;
double const halfErrorRad = m_compassFilter.GetHeadingHalfErrorRad();
r->drawSector(pxPosition,
@ -374,6 +392,60 @@ namespace location
return false;
}
void State::CheckCompassRotation()
{
#ifndef OMIM_OS_IPHONE
if (m_headingInterpolation)
m_headingInterpolation->Lock();
double headingDelta = 0;
bool isRunning = m_headingInterpolation
&& m_headingInterpolation->IsRunning();
if (isRunning)
headingDelta = fabs(ang::GetShortestDistance(m_headingInterpolation->EndAngle(), m_compassFilter.GetHeadingRad()));
double angleThreshold = ang::DegreeToRad(10);
if (headingDelta > angleThreshold)
m_headingInterpolation->SetEndAngle(m_compassFilter.GetHeadingRad());
else
{
if (!isRunning)
{
headingDelta = fabs(ang::GetShortestDistance(m_drawHeading, m_compassFilter.GetHeadingRad()));
if (headingDelta > angleThreshold)
{
if (m_headingInterpolation
&&!m_headingInterpolation->IsCancelled()
&&!m_headingInterpolation->IsEnded())
{
m_headingInterpolation->Unlock();
m_headingInterpolation->Cancel();
m_headingInterpolation.reset();
}
m_headingInterpolation.reset(new anim::AngleInterpolation(m_drawHeading,
m_compassFilter.GetHeadingRad(),
1,
m_drawHeading));
m_framework->GetAnimController()->AddTask(m_headingInterpolation);
return;
}
}
}
if (m_headingInterpolation)
m_headingInterpolation->Unlock();
#else
m_drawHeading = m_compassFilter.GetHeadingRad();
#endif
}
void State::CheckFollowCompass()
{
if (m_hasCompass

View file

@ -13,6 +13,11 @@
class Framework;
class RotateScreenTask;
namespace anim
{
class AngleInterpolation;
}
namespace yg
{
namespace gl
@ -51,6 +56,7 @@ namespace location
m2::PointD m_position; //< position in mercator
CompassFilter m_compassFilter;
double m_drawHeading;
bool m_hasPosition;
bool m_hasCompass;
@ -90,6 +96,8 @@ namespace location
mutable vector<m2::AnyRectD> m_boundRects;
m2::RectD m_boundRect;
shared_ptr<anim::AngleInterpolation> m_headingInterpolation;
public:
struct Params : base_t::Params
@ -121,6 +129,7 @@ namespace location
void SetIsCentered(bool flag);
bool IsCentered() const;
void CheckCompassRotation();
void CheckFollowCompass();
/// @name GPS location updates routine.