void RulerHelper::Update(ScreenBase const & screen) { m2::PointD pivot = screen.PixelRect().Center(); int const minPxWidth = my::rounds(MinPixelWidth * df::VisualParams::Instance().GetVisualScale()); m2::PointD pt1 = screen.PtoG(pivot); m2::PointD pt0 = screen.PtoG(pivot - m2::PointD(minPxWidth, 0)); double const distanceInMetres = MercatorBounds::DistanceOnEarth(pt0, pt1); // convert metres to units for calculating m_metresDiff double metersDiff = CalcMetresDiff(distanceInMetres); bool const higherThanMax = metersDiff > MaxMetersWidth; bool const lessThanMin = metersDiff < MinMetersWidth; m_pixelLength = minPxWidth; if (higherThanMax) m_pixelLength = minPxWidth * 3 / 2; else if (!lessThanMin) { double const a = ang::AngleTo(pt1, pt0); pt0 = MercatorBounds::GetSmPoint(pt1, cos(a) * metersDiff, sin(a) * metersDiff); m_pixelLength = my::rounds(pivot.Length(screen.GtoP(pt0))); } int drawScale = df::GetDrawTileScale(screen); if (m_currentDrawScale < VISIBLE_RULER_BOTTOM_SCALE && drawScale >= VISIBLE_RULER_BOTTOM_SCALE) { SetTextDirty(); } m_currentDrawScale = drawScale; }
bool ApplyScale(m2::PointD const & pixelScaleCenter, double factor, ScreenBase & screen) { m2::PointD const globalScaleCenter = screen.PtoG(screen.P3dtoP(pixelScaleCenter)); ScreenBase tmp = screen; tmp.Scale(factor); tmp.MatchGandP3d(globalScaleCenter, pixelScaleCenter); if (!CheckMinScale(tmp)) return false; m2::RectD const & worldR = df::GetWorldRect(); if (!CheckBorders(tmp)) { if (CanShrinkInto(tmp, worldR)) tmp = ShrinkInto(tmp, worldR); else return false; } if (!CheckMaxScale(tmp)) return false; // re-checking the borders, as we might violate them a bit (don't know why). if (!CheckBorders(tmp)) tmp = ScaleInto(tmp, worldR); screen = tmp; return true; }
int GetTileScaleBase(ScreenBase const & s, uint32_t tileSize) { ScreenBase tmpS = s; tmpS.Rotate(-tmpS.GetAngle()); // slightly smaller than original to produce "antialiasing" effect using bilinear filtration. int const halfSize = static_cast<int>(tileSize / 1.05 / 2.0); m2::RectD glbRect; m2::PointD const pxCenter = tmpS.PixelRect().Center(); tmpS.PtoG(m2::RectD(pxCenter - m2::PointD(halfSize, halfSize), pxCenter + m2::PointD(halfSize, halfSize)), glbRect); return GetTileScaleBase(glbRect); }
/// @name Manipulating with model view //@{ inline m2::PointD PtoG(m2::PointD const & p) const { return m_currentModelView.PtoG(p); }