string ToString<m2::RectD>(m2::RectD const & rect) { ostringstream stream; stream.precision(12); stream << rect.minX() << " " << rect.minY() << " " << rect.maxX() << " " << rect.maxY(); return stream.str(); }
void SendStatistics(SearchParams const & params, m2::RectD const & viewport, Results const & res) { size_t const kMaxNumResultsToSend = 10; size_t const numResultsToSend = min(kMaxNumResultsToSend, res.GetCount()); string resultString = strings::to_string(numResultsToSend); for (size_t i = 0; i < numResultsToSend; ++i) resultString.append("\t" + res.GetResult(i).ToStringForStats()); string posX, posY; if (params.IsValidPosition()) { posX = strings::to_string(MercatorBounds::LonToX(params.m_lon)); posY = strings::to_string(MercatorBounds::LatToY(params.m_lat)); } alohalytics::TStringMap const stats = { {"posX", posX}, {"posY", posY}, {"viewportMinX", strings::to_string(viewport.minX())}, {"viewportMinY", strings::to_string(viewport.minY())}, {"viewportMaxX", strings::to_string(viewport.maxX())}, {"viewportMaxY", strings::to_string(viewport.maxY())}, {"query", params.m_query}, {"locale", params.m_inputLocale}, {"results", resultString}, }; alohalytics::LogEvent("searchEmitResultsAndCoords", stats); }
m2::AnyRectD ToRotated(m2::RectD const & rect, Navigator const & navigator) { double const dx = rect.SizeX(); double const dy = rect.SizeY(); return m2::AnyRectD(rect.Center(), navigator.Screen().GetAngle(), m2::RectD(-dx/2, -dy/2, dx/2, dy/2)); }
vector<m2::SharedSpline> ClipSplineByRect(m2::RectD const & rect, m2::SharedSpline const & spline) { vector<m2::SharedSpline> result; vector<m2::PointD> const & path = spline->GetPath(); if (path.size() < 2) return result; m2::RectD splineRect; for (m2::PointD const & p : path) splineRect.Add(p); // Check for spline is inside. if (rect.IsRectInside(splineRect)) { result.push_back(spline); return result; } // Check for spline is outside. if (!rect.IsIntersect(splineRect)) return result; // Divide spline into parts. result.reserve(2); m2::PointD p1, p2; int code1 = 0; int code2 = 0; m2::SharedSpline s; s.Reset(new m2::Spline(path.size())); for (size_t i = 0; i < path.size() - 1; i++) { p1 = path[i]; p2 = path[i + 1]; if (m2::Intersect(rect, p1, p2, code1, code2)) { if ((p1 - p2).IsAlmostZero()) continue; if (s.IsNull()) s.Reset(new m2::Spline(path.size() - i)); s->AddPoint(p1); if (code2 != 0 || i + 2 == path.size()) { s->AddPoint(p2); result.push_back(s); s.Reset(nullptr); } } } return result; }
void ScreenBase::SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect) { double hScale = glbRect.GetLocalRect().SizeX() / pxRect.SizeX(); double vScale = glbRect.GetLocalRect().SizeY() / pxRect.SizeY(); m_Scale = max(hScale, vScale); m_Angle = glbRect.Angle(); m_Org = glbRect.GlobalCenter(); UpdateDependentParameters(); }
void Framework::ShowNode(TCountryId const & idx, bool zoomToDownloadButton) { if (zoomToDownloadButton) { m2::RectD const rect = CalcLimitRect(idx, m_work.GetStorage(), m_work.GetCountryInfoGetter()); m_work.SetViewportCenter(rect.Center(), 10); } else { m_work.ShowNode(idx); } }
void Init() { m_depthLayer = m_f.GetLayer(); if (m_depthLayer == feature::LAYER_TRANSPARENT_TUNNEL) m_depthLayer = feature::LAYER_EMPTY; if (m_geomType == feature::GEOM_POINT) m_priorityModifier = (double)m_f.GetPopulation() / 7E9; else { m2::RectD const r = m_f.GetLimitRect(m_zoomLevel); m_priorityModifier = min(1.0, r.SizeX() * r.SizeY() * 10000.0); } }
void Engine::SetRankPivot(SearchParams const & params, m2::RectD const & viewport, bool viewportSearch, Query & processor) { if (!viewportSearch && params.IsValidPosition()) { m2::PointD const pos = MercatorBounds::FromLatLon(params.m_lat, params.m_lon); if (m2::Inflate(viewport, viewport.SizeX() / 4.0, viewport.SizeY() / 4.0).IsPointInside(pos)) { processor.SetRankPivot(pos); return; } } processor.SetRankPivot(viewport.Center()); }
vector<TCountryId> CountryInfoGetter::GetRegionsCountryIdByRect(m2::RectD const & rect) const { size_t constexpr kAverageSize = 10; vector<TCountryId> result; result.reserve(kAverageSize); for (size_t id = 0; id < m_countries.size(); ++id) { if (rect.IsRectInside(m_countries[id].m_rect) || (rect.IsIntersect(m_countries[id].m_rect) && IsIntersectedByRegionImpl(id, rect))) { result.push_back(m_countries[id].m_countryId); } } return result; }
m2::PointD CalculateCenter(double scale, m2::RectD const & pixelRect, m2::PointD const & userPos, m2::PointD const & pixelPos, double azimuth) { m2::PointD formingVector = (pixelRect.Center() - pixelPos) * scale; formingVector.y = -formingVector.y; formingVector.Rotate(azimuth); return userPos + formingVector; }
drape_ptr<SequenceAnimation> GetPrettyFollowAnimation(ScreenBase const & startScreen, m2::PointD const & userPos, double targetScale, double targetAngle, m2::PointD const & endPixelPos) { auto sequenceAnim = make_unique_dp<SequenceAnimation>(); sequenceAnim->SetCustomType(kPrettyFollowAnim); m2::RectD const viewportRect = startScreen.PixelRectIn3d(); ScreenBase tmp = startScreen; tmp.SetAngle(targetAngle); tmp.MatchGandP3d(userPos, viewportRect.Center()); double const moveDuration = PositionInterpolator::GetMoveDuration(startScreen.GetOrg(), tmp.GetOrg(), startScreen); ASSERT_GREATER(moveDuration, 0.0, ()); double const scaleFactor = moveDuration / kMaxAnimationTimeSec * 2.0; tmp = startScreen; if (moveDuration > 0.0) { tmp.SetScale(startScreen.GetScale() * scaleFactor); auto zoomOutAnim = make_unique_dp<MapLinearAnimation>(); zoomOutAnim->SetScale(startScreen.GetScale(), tmp.GetScale()); zoomOutAnim->SetMaxDuration(kMaxAnimationTimeSec * 0.5); sequenceAnim->AddAnimation(move(zoomOutAnim)); tmp.MatchGandP3d(userPos, viewportRect.Center()); auto moveAnim = make_unique_dp<MapLinearAnimation>(); moveAnim->SetMove(startScreen.GetOrg(), tmp.GetOrg(), viewportRect, tmp.GetScale()); moveAnim->SetMaxDuration(kMaxAnimationTimeSec); sequenceAnim->AddAnimation(move(moveAnim)); } auto followAnim = make_unique_dp<MapFollowAnimation>(tmp, userPos, endPixelPos, tmp.GetScale(), targetScale, tmp.GetAngle(), targetAngle, false /* isAutoZoom */); followAnim->SetMaxDuration(kMaxAnimationTimeSec * 0.5); sequenceAnim->AddAnimation(move(followAnim)); return sequenceAnim; }
bool FromString<m2::RectD>(string const & str, m2::RectD & rect) { double val[4]; if (!impl::FromStringArray(str, val)) return false; // Will get an assertion in DEBUG and false return in RELEASE. rect = m2::RectD(val[0], val[1], val[2], val[3]); return rect.IsValid(); }
ScreenBase const ScaleInto(ScreenBase const & screen, m2::RectD boundRect) { ReduceRectHack(boundRect); ScreenBase res = screen; double scale = 1; m2::RectD clipRect = res.ClipRect(); ASSERT(boundRect.IsPointInside(clipRect.Center()), ("center point should be inside boundRect")); if (clipRect.minX() < boundRect.minX()) { double k = (boundRect.minX() - clipRect.Center().x) / (clipRect.minX() - clipRect.Center().x); scale /= k; clipRect.Scale(k); } if (clipRect.maxX() > boundRect.maxX()) { double k = (boundRect.maxX() - clipRect.Center().x) / (clipRect.maxX() - clipRect.Center().x); scale /= k; clipRect.Scale(k); } if (clipRect.minY() < boundRect.minY()) { double k = (boundRect.minY() - clipRect.Center().y) / (clipRect.minY() - clipRect.Center().y); scale /= k; clipRect.Scale(k); } if (clipRect.maxY() > boundRect.maxY()) { double k = (boundRect.maxY() - clipRect.Center().y) / (clipRect.maxY() - clipRect.Center().y); scale /= k; clipRect.Scale(k); } res.Scale(scale); res.SetOrg(clipRect.Center()); return res; }
void FrontendRenderer::OnResize(ScreenBase const & screen) { m2::RectD const viewportRect = screen.isPerspective() ? screen.PixelRectIn3d() : screen.PixelRect(); m_myPositionController->UpdatePixelPosition(screen); m_myPositionController->OnNewPixelRect(); m_viewport.SetViewport(0, 0, viewportRect.SizeX(), viewportRect.SizeY()); m_contextFactory->getDrawContext()->resize(viewportRect.SizeX(), viewportRect.SizeY()); RefreshProjection(screen); RefreshPivotTransform(screen); m_framebuffer->SetSize(viewportRect.SizeX(), viewportRect.SizeY()); }
void Editor::ForEachFeatureInMwmRectAndScale(MwmSet::MwmId const & id, TFeatureTypeFunctor const & f, m2::RectD const & rect, uint32_t /*scale*/) { auto mwmFound = m_features.find(id); if (mwmFound == m_features.end()) return; // TODO(AlexZ): Check that features are visible at this scale. // Process only new (created) features. for (auto & index : mwmFound->second) { FeatureTypeInfo & ftInfo = index.second; if (ftInfo.m_status == FeatureStatus::Created && rect.IsPointInside(ftInfo.m_feature.GetCenter())) f(ftInfo.m_feature); } }
ScreenBase const ShrinkInto(ScreenBase const & screen, m2::RectD boundRect) { ReduceRectHack(boundRect); ScreenBase res = screen; m2::RectD clipRect = res.ClipRect(); if (clipRect.minX() < boundRect.minX()) clipRect.Offset(boundRect.minX() - clipRect.minX(), 0); if (clipRect.maxX() > boundRect.maxX()) clipRect.Offset(boundRect.maxX() - clipRect.maxX(), 0); if (clipRect.minY() < boundRect.minY()) clipRect.Offset(0, boundRect.minY() - clipRect.minY()); if (clipRect.maxY() > boundRect.maxY()) clipRect.Offset(0, boundRect.maxY() - clipRect.maxY()); res.SetOrg(clipRect.Center()); // This assert fails near x = 180 (Philipines). //ASSERT ( boundRect.IsRectInside(res.ClipRect()), (clipRect, res.ClipRect()) ); return res; }
void ShapeRenderer::drawRectangle(m2::RectD const & r, graphics::Color const & c, double depth) { uint32_t id = base_t::mapInfo(Brush::Info(c)); Resource const * res = base_t::fromID(id); if (res == 0) { LOG(LDEBUG, ("cannot map color")); return; } m2::PointF rectPts[4] = { m2::PointF(r.minX(), r.minY()), m2::PointF(r.maxX(), r.minY()), m2::PointF(r.minX(), r.maxY()), m2::PointF(r.maxX(), r.maxY()) }; GeometryPipeline & p = pipeline(res->m_pipelineID); shared_ptr<gl::BaseTexture> texture = p.texture(); if (!texture) { LOG(LDEBUG, ("returning as no texture is reserved")); return; } m2::PointF texPt = texture->mapPixel(m2::RectF(res->m_texRect).Center()); m2::PointF normal(0, 0); addTexturedStripStrided( rectPts, sizeof(m2::PointF), &normal, 0, &texPt, 0, 4, depth, res->m_pipelineID ); }
double CalculateScale(ScreenBase const & screen, m2::RectD const & localRect) { m2::RectD const pixelRect = screen.PixelRect(); return max(localRect.SizeX() / pixelRect.SizeX(), localRect.SizeY() / pixelRect.SizeY()); }
void Navigator::Move(double azDir, double factor) { m2::RectD const r = m_Screen.ClipRect(); m_Screen.MoveG(m2::PointD(r.SizeX() * factor * cos(azDir), r.SizeY() * factor * sin(azDir))); }
ScreenBase const ShrinkAndScaleInto(ScreenBase const & screen, m2::RectD boundRect) { ReduceRectHack(boundRect); ScreenBase res = screen; m2::RectD globalRect = res.ClipRect(); m2::PointD newOrg = res.GetOrg(); double scale = 1; double offs = 0; if (globalRect.minX() < boundRect.minX()) { offs = boundRect.minX() - globalRect.minX(); globalRect.Offset(offs, 0); newOrg.x += offs; if (globalRect.maxX() > boundRect.maxX()) { double k = boundRect.SizeX() / globalRect.SizeX(); scale /= k; /// scaling always occur pinpointed to the rect center... globalRect.Scale(k); /// ...so we should shift a rect after scale globalRect.Offset(boundRect.minX() - globalRect.minX(), 0); } } if (globalRect.maxX() > boundRect.maxX()) { offs = boundRect.maxX() - globalRect.maxX(); globalRect.Offset(offs, 0); newOrg.x += offs; if (globalRect.minX() < boundRect.minX()) { double k = boundRect.SizeX() / globalRect.SizeX(); scale /= k; globalRect.Scale(k); globalRect.Offset(boundRect.maxX() - globalRect.maxX(), 0); } } if (globalRect.minY() < boundRect.minY()) { offs = boundRect.minY() - globalRect.minY(); globalRect.Offset(0, offs); newOrg.y += offs; if (globalRect.maxY() > boundRect.maxY()) { double k = boundRect.SizeY() / globalRect.SizeY(); scale /= k; globalRect.Scale(k); globalRect.Offset(0, boundRect.minY() - globalRect.minY()); } } if (globalRect.maxY() > boundRect.maxY()) { offs = boundRect.maxY() - globalRect.maxY(); globalRect.Offset(0, offs); newOrg.y += offs; if (globalRect.minY() < boundRect.minY()) { double k = boundRect.SizeY() / globalRect.SizeY(); scale /= k; globalRect.Scale(k); globalRect.Offset(0, boundRect.maxY() - globalRect.maxY()); } } res.SetOrg(globalRect.Center()); res.Scale(scale); return res; }
int GetTileScaleBase(m2::RectD const & r) { double const sz = max(r.SizeX(), r.SizeY()); return max(1, my::rounds(log((MercatorBounds::maxX - MercatorBounds::minX) / sz) / log(2.0))); }
double CalculateScale(m2::RectD const & pixelRect, m2::RectD const & localRect) { return max(localRect.SizeX() / pixelRect.SizeX(), localRect.SizeY() / pixelRect.SizeY()); }
void ShapeRenderer::drawRoundedRectangle(m2::RectD const & r, double rad, graphics::Color const & c, double depth) { uint32_t id = base_t::mapInfo(Brush::Info(c)); Resource const * res = base_t::fromID(id); if (res == 0) { LOG(LDEBUG, ("cannot map color")); return; } GeometryPipeline & p = pipeline(res->m_pipelineID); shared_ptr<gl::BaseTexture> texture = p.texture(); if (!texture) { LOG(LDEBUG, ("returning as no texture is reserved")); return; } m2::PointF texPt = texture->mapPixel(m2::RectF(res->m_texRect).Center()); vector<m2::PointD> seg00; vector<m2::PointD> seg10; vector<m2::PointD> seg11; vector<m2::PointD> seg01; approximateArc(m2::PointD(r.minX() + rad, r.minY() + rad), math::pi, 3 * math::pi / 2, rad, seg00); approximateArc(m2::PointD(r.minX() + rad, r.maxY() - rad), math::pi / 2, math::pi, rad, seg01); approximateArc(m2::PointD(r.maxX() - rad, r.maxY() - rad), 0, math::pi / 2, rad, seg11); approximateArc(m2::PointD(r.maxX() - rad, r.minY() + rad), 3 * math::pi / 2, math::pi * 2, rad, seg10); vector<m2::PointF> pts; for (unsigned i = 0; i < seg11.size(); ++i) pts.push_back(m2::PointF(seg11[i])); for (unsigned i = 0; i < seg01.size(); ++i) pts.push_back(m2::PointF(seg01[i])); for (unsigned i = 0; i < seg00.size(); ++i) pts.push_back(m2::PointF(seg00[i])); for (unsigned i = 0; i < seg10.size(); ++i) pts.push_back(m2::PointF(seg10[i])); m2::PointF normal(0, 0); addTexturedFanStrided( &pts[0], sizeof(m2::PointF), &normal, 0, &texPt, 0, pts.size(), depth, res->m_pipelineID ); }
bool CanShrinkInto(ScreenBase const & screen, m2::RectD const & boundRect) { m2::RectD clipRect = screen.ClipRect(); return (boundRect.SizeX() >= clipRect.SizeX()) && (boundRect.SizeY() >= clipRect.SizeY()); }
void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, ScreenBase const & screen) { m2::PointD const oldPos = GetDrawablePosition(); double const oldAzimut = GetDrawableAzimut(); m2::RectD const rect = MercatorBounds::MetresToXY(info.m_longitude, info.m_latitude, info.m_horizontalAccuracy); // Use FromLatLon instead of rect.Center() since in case of large info.m_horizontalAccuracy // there is significant difference between the real location and the estimated one. m_position = MercatorBounds::FromLatLon(info.m_latitude, info.m_longitude); m_errorRadius = rect.SizeX() * 0.5; bool const hasBearing = info.HasBearing(); if ((isNavigable && hasBearing) || (!isNavigable && hasBearing && info.HasSpeed() && info.m_speed > kMinSpeedThresholdMps)) { SetDirection(my::DegToRad(info.m_bearing)); m_lastGPSBearing.Reset(); } if (m_listener) m_listener->PositionChanged(Position()); if (m_isPositionAssigned && (!AlmostCurrentPosition(oldPos) || !AlmostCurrentAzimut(oldAzimut))) { CreateAnim(oldPos, oldAzimut, screen); m_isDirtyViewport = true; } if (m_notFollowAfterPending && m_mode == location::PendingPosition) { ChangeMode(location::NotFollow); if (m_isInRouting) m_routingNotFollowTimer.Reset(); m_notFollowAfterPending = false; } else if (!m_isPositionAssigned) { ChangeMode(m_isFirstLaunch ? location::Follow : m_desiredInitMode); if (!m_isFirstLaunch || !AnimationSystem::Instance().AnimationExists(Animation::MapPlane)) { if (m_mode == location::Follow) ChangeModelView(m_position, kDoNotChangeZoom); else if (m_mode == location::FollowAndRotate) ChangeModelView(m_position, m_drawDirection, m_isInRouting ? GetRoutingRotationPixelCenter() : m_pixelRect.Center(), kDoNotChangeZoom); } } else if (m_mode == location::PendingPosition || m_mode == location::NotFollowNoPosition) { if (m_isInRouting) { ChangeMode(location::FollowAndRotate); UpdateViewport(kMaxScaleZoomLevel); } else { ChangeMode(location::Follow); if (!m_isFirstLaunch) { if (GetZoomLevel(screen, m_position, m_errorRadius) <= kMaxScaleZoomLevel) { m2::PointD const size(m_errorRadius, m_errorRadius); ChangeModelView(m2::RectD(m_position - size, m_position + size)); } else { ChangeModelView(m_position, kMaxScaleZoomLevel); } } else { if (!AnimationSystem::Instance().AnimationExists(Animation::MapPlane)) ChangeModelView(m_position, kDoNotChangeZoom); } } } m_isPositionAssigned = true; SetIsVisible(true); double const kEps = 1e-5; if (fabs(m_lastLocationTimestamp - info.m_timestamp) > kEps) { m_lastLocationTimestamp = info.m_timestamp; m_updateLocationTimer.Reset(); } }
void ScreenBase::PtoG(m2::RectD const & pxRect, m2::RectD & glbRect) const { glbRect = m2::RectD(PtoG(pxRect.LeftTop()), PtoG(pxRect.RightBottom())); }
static bool empty_scr_rect(m2::RectD const & r) { double const eps = 1.0; return (r.SizeX() < eps && r.SizeY() < eps); }
void ClipTriangleByRect(m2::RectD const & rect, m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3, ClipTriangleByRectResultIt const & resultIterator) { if (resultIterator == nullptr) return; if (rect.IsPointInside(p1) && rect.IsPointInside(p2) && rect.IsPointInside(p3)) { resultIterator(p1, p2, p3); return; } const double kEps = 1e-8; vector<m2::PointD> poligon; auto const addPoligonPoint = [&poligon, kEps](m2::PointD const & pt) { if (poligon.empty() || !poligon.back().EqualDxDy(pt, kEps)) poligon.push_back(pt); }; vector<m2::PointD> const corners = { rect.LeftTop(), rect.RightTop(), rect.RightBottom(), rect.LeftBottom() }; int firstClipCode[3]; int lastClipCode[3]; bool intersected[3]; intersected[0] = IntersectEdge(rect, corners, p1, p2, p3, addPoligonPoint, 0, 0, firstClipCode[0], lastClipCode[0]); intersected[1] = IntersectEdge(rect, corners, p2, p3, p1, addPoligonPoint, lastClipCode[0], 0, firstClipCode[1], lastClipCode[1]); intersected[2] = IntersectEdge(rect, corners, p3, p1, p2, addPoligonPoint, lastClipCode[1] != 0 ? lastClipCode[1] : lastClipCode[0], firstClipCode[0] != 0 ? firstClipCode[0] : firstClipCode[1], firstClipCode[2], lastClipCode[2]); int const intersectCount = intersected[0] + intersected[1] + intersected[2]; if (intersectCount == 0) { if (IsPointInsideTriangle(rect.Center(), p1, p2, p3)) { resultIterator(rect.LeftTop(), rect.RightTop(), rect.RightBottom()); resultIterator(rect.RightBottom(), rect.LeftBottom(), rect.LeftTop()); } return; } if (intersectCount == 1 && intersected[2]) InsertCorners(corners, p1, p2, p3, addPoligonPoint, lastClipCode[2], firstClipCode[2]); if (!poligon.empty() && poligon.back().EqualDxDy(poligon[0], kEps)) poligon.pop_back(); if (poligon.size() < 3) return; for (size_t i = 0; i < poligon.size() - 2; ++i) resultIterator(poligon[0], poligon[i + 1], poligon[i + 2]); }
m2::RectD PixelRectIn3d() const { return m2::RectD(0.0, 0.0, m_PixelRect.maxX() / m_3dScaleX, m_PixelRect.maxY() / m_3dScaleY); }
void ScreenBase::GtoP(m2::RectD const & glbRect, m2::RectD & pxRect) const { pxRect = m2::RectD(GtoP(glbRect.LeftTop()), GtoP(glbRect.RightBottom())); }