Route points implementation based on UserMark.

This commit is contained in:
Daria Volvenkova 2017-06-05 18:45:55 +03:00
parent 899a7f3878
commit d455c04c3b
9 changed files with 265 additions and 1 deletions

View file

@ -90,6 +90,8 @@ void CacheUserPoints(UserMarksProvider const * provider, ref_ptr<dp::TextureMana
for (size_t i = 0; i < markCount; ++i)
{
UserPointMark const * userMark = provider->GetUserPointMark(i);
if (!userMark->IsVisible())
continue;
TileKey const tileKey = GetTileKeyByPoint(userMark->GetPivot(), kZoomLevel);
marks[tileKey].push_back(userMark);
}

View file

@ -21,6 +21,7 @@ public:
virtual dp::Anchor GetAnchor() const = 0;
virtual float GetDepth() const = 0;
virtual bool RunCreationAnim() const = 0;
virtual bool IsVisible() const { return true; }
};
class UserLineMark

View file

@ -1,5 +1,6 @@
#include "map/bookmark_manager.hpp"
#include "map/framework.hpp"
#include "map/routing_mark.hpp"
#include "map/user_mark.hpp"
#include "platform/platform.hpp"
@ -23,6 +24,7 @@ BookmarkManager::BookmarkManager(Framework & f)
m_userMarkLayers.push_back(new SearchUserMarkContainer(0.0 /* activePinDepth */, m_framework));
m_userMarkLayers.push_back(new ApiUserMarkContainer(0.0 /* activePinDepth */, m_framework));
m_userMarkLayers.push_back(new DebugUserMarkContainer(0.0 /* debugDepth */, m_framework));
m_userMarkLayers.push_back(new RouteUserMarkContainer(0.0 /* activePinDepth */, m_framework));
UserMarkContainer::InitStaticMarks(FindUserMarksContainer(UserMarkType::SEARCH_MARK));
}

View file

@ -33,6 +33,7 @@ HEADERS += \
place_page_info.hpp \
reachable_by_taxi_checker.hpp \
routing_manager.hpp \
routing_mark.hpp \
track.hpp \
traffic_manager.hpp \
user_mark.hpp \
@ -63,6 +64,7 @@ SOURCES += \
place_page_info.cpp \
reachable_by_taxi_checker.cpp \
routing_manager.cpp \
routing_mark.cpp \
track.cpp \
traffic_manager.cpp \
user_mark.cpp \

192
map/routing_mark.cpp Normal file
View file

@ -0,0 +1,192 @@
#include "map/routing_mark.hpp"
#include <algorithm>
static int8_t const kMaxIntermediatePointsCount = 3;
RouteMarkPoint::RouteMarkPoint(const m2::PointD & ptOrg, UserMarkContainer * container)
: UserMark(ptOrg, container)
{}
bool RouteMarkPoint::IsVisible() const
{
return m_isVisible;
}
void RouteMarkPoint::SetIsVisible(bool isVisible)
{
m_isVisible = isVisible;
}
std::string RouteMarkPoint::GetSymbolName() const
{
switch (m_pointType)
{
case RouteMarkType::Start:
return "placemark-blue";
case RouteMarkType::Intermediate:
if (m_intermediateIndex == 0)
return "placemark-yellow";
if (m_intermediateIndex == 1)
return "placemark-orange";
return "placemark-red";
case RouteMarkType::Finish:
return "placemark-green";
}
}
RouteUserMarkContainer::RouteUserMarkContainer(double layerDepth, Framework & fm)
: UserMarkContainer(layerDepth, UserMarkType::ROUTING_MARK, fm)
{
}
UserMark * RouteUserMarkContainer::AllocateUserMark(m2::PointD const & ptOrg)
{
return new RouteMarkPoint(ptOrg, this);
}
RoutePointsLayout::RoutePointsLayout(UserMarksController & routeMarks)
: m_routeMarks(routeMarks)
{}
RouteMarkPoint * RoutePointsLayout::AddRoutePoint(m2::PointD const & ptOrg, RouteMarkType type, int8_t intermediateIndex)
{
if (m_routeMarks.GetUserMarkCount() == kMaxIntermediatePointsCount + 2)
return nullptr;
RouteMarkPoint * sameTypePoint = GetRoutePoint(type, intermediateIndex);
if (sameTypePoint != nullptr)
{
if (type == RouteMarkType::Finish)
{
int8_t const intermediatePointsCount = std::max((int)m_routeMarks.GetUserMarkCount() - 2, 0);
sameTypePoint->SetRoutePointType(RouteMarkType::Intermediate);
sameTypePoint->SetIntermediateIndex(intermediatePointsCount);
}
else
{
int8_t const offsetIndex = type == RouteMarkType::Start ? 0 : intermediateIndex;
ForEachIntermediatePoint([offsetIndex](RouteMarkPoint * mark)
{
if (mark->GetIntermediateIndex() >= offsetIndex)
mark->SetIntermediateIndex(mark->GetIntermediateIndex() + 1);
});
if (type == RouteMarkType::Start)
{
sameTypePoint->SetRoutePointType(RouteMarkType::Intermediate);
sameTypePoint->SetIntermediateIndex(0);
}
}
}
RouteMarkPoint * newPoint = static_cast<RouteMarkPoint*>(m_routeMarks.CreateUserMark(ptOrg));
newPoint->SetRoutePointType(type);
newPoint->SetIntermediateIndex(intermediateIndex);
return newPoint;
}
bool RoutePointsLayout::RemoveRoutePoint(RouteMarkType type, int8_t intermediateIndex)
{
RouteMarkPoint * point = nullptr;
size_t index = 0;
for (size_t sz = m_routeMarks.GetUserMarkCount(); index < sz; ++index)
{
RouteMarkPoint * mark = static_cast<RouteMarkPoint*>(m_routeMarks.GetUserMarkForEdit(index));
if (mark->GetRoutePointType() == type && mark->GetIntermediateIndex() == intermediateIndex)
{
point = mark;
break;
}
}
if (point == nullptr)
return false;
if (type == RouteMarkType::Finish)
{
RouteMarkPoint * lastIntermediate = nullptr;
int8_t maxIntermediateIndex = -1;
ForEachIntermediatePoint([&lastIntermediate, &maxIntermediateIndex](RouteMarkPoint * mark)
{
if (mark->GetIntermediateIndex() > maxIntermediateIndex)
{
lastIntermediate = mark;
maxIntermediateIndex = mark->GetIntermediateIndex();
}
});
if (lastIntermediate != nullptr)
lastIntermediate->SetRoutePointType(RouteMarkType::Finish);
}
else if (type == RouteMarkType::Start)
{
ForEachIntermediatePoint([](RouteMarkPoint * mark)
{
if (mark->GetIntermediateIndex() == 0)
mark->SetRoutePointType(RouteMarkType::Start);
else
mark->SetIntermediateIndex(mark->GetIntermediateIndex() - 1);
});
}
else
{
ForEachIntermediatePoint([point](RouteMarkPoint * mark)
{
if (mark->GetIntermediateIndex() > point->GetIntermediateIndex())
mark->SetIntermediateIndex(mark->GetIntermediateIndex() - 1);
});
}
m_routeMarks.DeleteUserMark(index);
return true;
}
bool RoutePointsLayout::MoveRoutePoint(RouteMarkType currentType, int8_t currentIntermediateIndex,
RouteMarkType destType, int8_t destIntermediateIndex)
{
RouteMarkPoint * point = GetRoutePoint(currentType, currentIntermediateIndex);
if (point == nullptr)
return false;
m2::PointD const pt = point->GetPivot();
bool const isVisible = point->IsVisible();
RemoveRoutePoint(currentType, currentIntermediateIndex);
RouteMarkPoint * point2 = AddRoutePoint(pt, destType, destIntermediateIndex);
point2->SetIsVisible(isVisible);
return true;
}
RouteMarkPoint * RoutePointsLayout::GetRoutePoint(RouteMarkType type, int8_t intermediateIndex)
{
for (size_t i = 0, sz = m_routeMarks.GetUserMarkCount(); i < sz; ++i)
{
RouteMarkPoint * mark = static_cast<RouteMarkPoint*>(m_routeMarks.GetUserMarkForEdit(i));
if (mark->GetRoutePointType() != type)
continue;
if (type == RouteMarkType::Intermediate)
{
if (mark->GetIntermediateIndex() == intermediateIndex)
return mark;
}
else
{
return mark;
}
}
return nullptr;
}
void RoutePointsLayout::ForEachIntermediatePoint(TRoutePointCallback const & fn)
{
for (size_t i = 0, sz = m_routeMarks.GetUserMarkCount(); i < sz; ++i)
{
RouteMarkPoint * mark = static_cast<RouteMarkPoint*>(m_routeMarks.GetUserMarkForEdit(i));
if (mark->GetRoutePointType() == RouteMarkType::Intermediate)
fn(mark);
}
}

62
map/routing_mark.hpp Normal file
View file

@ -0,0 +1,62 @@
#pragma once
#include "map/user_mark_container.hpp"
#include <string>
enum class RouteMarkType
{
Start,
Intermediate,
Finish
};
class RouteMarkPoint : public UserMark
{
public:
RouteMarkPoint(m2::PointD const & ptOrg, UserMarkContainer * container);
virtual ~RouteMarkPoint() {}
bool IsVisible() const override;
void SetIsVisible(bool isVisible);
std::string GetSymbolName() const override;
UserMark::Type GetMarkType() const override { return Type::ROUTING; }
RouteMarkType GetRoutePointType() const { return m_pointType; }
void SetRoutePointType(RouteMarkType type) { m_pointType = type; }
void SetIntermediateIndex(int8_t index) { m_intermediateIndex = index; }
int8_t GetIntermediateIndex() { return m_intermediateIndex; }
private:
RouteMarkType m_pointType;
int8_t m_intermediateIndex = 0;
bool m_isVisible = true;
};
class RouteUserMarkContainer : public UserMarkContainer
{
public:
RouteUserMarkContainer(double layerDepth, Framework & fm);
protected:
UserMark * AllocateUserMark(m2::PointD const & ptOrg) override;
};
class RoutePointsLayout
{
public:
RoutePointsLayout(UserMarksController & routeMarks);
RouteMarkPoint * GetRoutePoint(RouteMarkType type, int8_t intermediateIndex);
RouteMarkPoint * AddRoutePoint(m2::PointD const & ptOrg, RouteMarkType type, int8_t intermediateIndex = 0);
bool RemoveRoutePoint(RouteMarkType type, int8_t intermediateIndex = 0);
bool MoveRoutePoint(RouteMarkType currentType, int8_t currentIntermediateIndex,
RouteMarkType destType, int8_t destIntermediateIndex);
private:
using TRoutePointCallback = function<void (RouteMarkPoint * mark)>;
void ForEachIntermediatePoint(TRoutePointCallback const & fn);
UserMarksController & m_routeMarks;
};

View file

@ -106,5 +106,6 @@ string DebugPrint(UserMark::Type type)
case UserMark::Type::BOOKMARK: return "BOOKMARK";
case UserMark::Type::MY_POSITION: return "MY_POSITION";
case UserMark::Type::DEBUG_MARK: return "DEBUG_MARK";
case UserMark::Type::ROUTING: return "ROUTING";
}
}

View file

@ -28,6 +28,7 @@ public:
POI,
BOOKMARK,
MY_POSITION,
ROUTING,
DEBUG_MARK
};

View file

@ -21,7 +21,8 @@ enum class UserMarkType
SEARCH_MARK,
API_MARK,
DEBUG_MARK,
BOOKMARK_MARK
BOOKMARK_MARK,
ROUTING_MARK
};
class UserMarksController