Exemplo n.º 1
0
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));
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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);
  }
}
Exemplo n.º 5
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());
}
Exemplo n.º 6
0
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]);
}
Exemplo n.º 7
0
void Engine::DoSearch(SearchParams const & params, m2::RectD const & viewport,
                      shared_ptr<QueryHandle> handle, Query & processor)
{
  bool const viewportSearch = params.GetMode() == Mode::Viewport;

  // Initialize query processor.
  processor.Init(viewportSearch);
  handle->Attach(processor);
  MY_SCOPE_GUARD(detach, [&handle] { handle->Detach(); });

  // Early exit when query processing is cancelled.
  if (processor.IsCancelled())
  {
    params.m_onResults(Results::GetEndMarker(true /* isCancelled */));
    return;
  }

  SetRankPivot(params, viewport, viewportSearch, processor);

  if (params.IsValidPosition())
    processor.SetPosition(MercatorBounds::FromLatLon(params.m_lat, params.m_lon));
  else
    processor.SetPosition(viewport.Center());

  processor.SetMode(params.GetMode());
  processor.SetSuggestsEnabled(params.GetSuggestsEnabled());

  // This flag is needed for consistency with old search algorithm
  // only. It will be gone when we remove old search code.
  processor.SetSearchInWorld(true);

  processor.SetInputLocale(params.m_inputLocale);

  ASSERT(!params.m_query.empty(), ());
  processor.SetQuery(params.m_query);

  Results res;

  processor.SearchCoordinates(res);

  try
  {
    if (params.m_onStarted)
      params.m_onStarted();

    processor.SetViewport(viewport, true /* forceUpdate */);
    if (viewportSearch)
      processor.SearchViewportPoints(res);
    else
      processor.Search(res, kResultsCount);

    if (!processor.IsCancelled())
      EmitResults(params, res);
  }
  catch (Query::CancelException const &)
  {
    LOG(LDEBUG, ("Search has been cancelled."));
  }

  if (!viewportSearch && !processor.IsCancelled())
    SendStatistics(params, viewport, res);

  // Emit finish marker to client.
  params.m_onResults(Results::GetEndMarker(processor.IsCancelled()));
}