diff --git a/drape/overlay_handle.hpp b/drape/overlay_handle.hpp index 1ed5027bc6..4401b7de0f 100644 --- a/drape/overlay_handle.hpp +++ b/drape/overlay_handle.hpp @@ -27,7 +27,7 @@ enum OverlayRank OverlayRank0 = 0, OverlayRank1, OverlayRank2, - + OverlayRank3, OverlayRanksCount }; diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp index 13b1c95244..fa55f4dfd2 100644 --- a/drape_frontend/apply_feature_functors.cpp +++ b/drape_frontend/apply_feature_functors.cpp @@ -603,8 +603,8 @@ void ApplyPointFeature::Finish(ref_ptr texMng) textParams.m_specialDisplacement = specialDisplacementMode ? SpecialDisplacement::SpecialMode : SpecialDisplacement::None; textParams.m_specialPriority = specialModePriority; - m_insertShape(make_unique_dp(m_centerPoint, textParams, m_tileKey, - hasPOI, symbolSize, + textParams.m_startOverlayRank = hasPOI ? dp::OverlayRank1 : dp::OverlayRank0; + m_insertShape(make_unique_dp(m_centerPoint, textParams, m_tileKey, symbolSize, dp::Center /* symbolAnchor */, 0 /* textIndex */)); } } @@ -989,6 +989,7 @@ void ApplyLineFeatureAdditional::GetRoadShieldsViewParams(ref_ptr texMng, if (!CheckShieldsNearby(shieldPos, shieldPixelSize, scaledMinDistance, generatedShieldRects)) continue; - m_insertShape(make_unique_dp(shieldPos, textParams, m_tileKey, true /* hasPOI */, + m_insertShape(make_unique_dp(shieldPos, textParams, m_tileKey, m2::PointF(0.0f, 0.0f) /* symbolSize */, dp::Center /* symbolAnchor */, textIndex)); if (IsColoredRoadShield(shield)) diff --git a/drape_frontend/colored_symbol_shape.cpp b/drape_frontend/colored_symbol_shape.cpp index 82b2453099..7ba174faef 100644 --- a/drape_frontend/colored_symbol_shape.cpp +++ b/drape_frontend/colored_symbol_shape.cpp @@ -235,6 +235,8 @@ void ColoredSymbolShape::Draw(ref_ptr batcher, make_unique_dp(overlayId, m_params.m_anchor, m_point, pixelSize, m_params.m_offset, GetOverlayPriority(), true /* isBound */, debugName, true /* isBillboard */) : nullptr; + if (m_needOverlay && m_params.m_specialDisplacement == SpecialDisplacement::UserMark) + handle->SetUserMarkOverlay(true); auto state = CreateGLState(gpu::COLORED_SYMBOL_PROGRAM, m_params.m_depthLayer); state.SetProgram3dIndex(gpu::COLORED_SYMBOL_BILLBOARD_PROGRAM); @@ -252,6 +254,9 @@ uint64_t ColoredSymbolShape::GetOverlayPriority() const if (m_params.m_specialDisplacement == SpecialDisplacement::SpecialMode) return dp::CalculateSpecialModePriority(m_params.m_specialPriority); + if (m_params.m_specialDisplacement == SpecialDisplacement::UserMark) + return dp::CalculateUserMarkPriority(m_params.m_minVisibleScale, m_params.m_specialPriority); + return dp::CalculateOverlayPriority(m_params.m_minVisibleScale, m_params.m_rank, m_params.m_depth); } } // namespace df diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index e0b4d183a2..c2c311fa06 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -239,9 +239,10 @@ void DrapeEngine::UpdateUserMarksGroup(MarkGroupID groupId, UserMarksProvider * renderInfo->m_isVisible = mark->IsVisible(); renderInfo->m_pivot = mark->GetPivot(); renderInfo->m_pixelOffset = mark->GetPixelOffset(); - renderInfo->m_symbolName = mark->GetSymbolName(); renderInfo->m_titleDecl = mark->GetTitleDecl(); renderInfo->m_symbolSizes = mark->GetSymbolSizes(); + renderInfo->m_symbolNames = mark->GetSymbolNames(); + renderInfo->m_coloredSymbols = mark->GetColoredSymbols(); renderInfo->m_hasSymbolPriority = mark->HasSymbolPriority(); renderInfo->m_hasTitlePriority = mark->HasTitlePriority(); renderInfo->m_priority = mark->GetPriority(); diff --git a/drape_frontend/poi_symbol_shape.cpp b/drape_frontend/poi_symbol_shape.cpp index 792babdf29..fb4ec6ea79 100644 --- a/drape_frontend/poi_symbol_shape.cpp +++ b/drape_frontend/poi_symbol_shape.cpp @@ -157,6 +157,7 @@ drape_ptr PoiSymbolShape::CreateOverlayHandle(m2::PointF cons handle->SetExtendingSize(m_params.m_extendingSize); if (m_params.m_specialDisplacement == SpecialDisplacement::UserMark) handle->SetUserMarkOverlay(true); + handle->SetOverlayRank(m_params.m_startOverlayRank); return handle; } diff --git a/drape_frontend/render_group.cpp b/drape_frontend/render_group.cpp index 5f807984c7..64e16d9931 100755 --- a/drape_frontend/render_group.cpp +++ b/drape_frontend/render_group.cpp @@ -101,7 +101,7 @@ void RenderGroup::Render(ScreenBase const & screen) int const programIndex = m_state.GetProgramIndex(); int const program3dIndex = m_state.GetProgram3dIndex(); - if (IsOverlay()) + if (IsOverlay() || GetDepthLayer(m_state) == RenderState::TransitMarkLayer) { if (programIndex == gpu::COLORED_SYMBOL_PROGRAM || programIndex == gpu::COLORED_SYMBOL_BILLBOARD_PROGRAM) diff --git a/drape_frontend/route_renderer.cpp b/drape_frontend/route_renderer.cpp index 8f1e86e219..38880f61b8 100644 --- a/drape_frontend/route_renderer.cpp +++ b/drape_frontend/route_renderer.cpp @@ -29,7 +29,6 @@ std::string const kRouteArrowsMaskBicycle = "RouteArrowsMaskBicycle"; std::string const kRouteMaskPedestrian = "RouteMaskPedestrian"; // TODO(@darina) Use separate colors. -std::string const kGateColor = "Route"; std::string const kTransitOutlineColor = "RouteMarkPrimaryTextOutline"; namespace diff --git a/drape_frontend/route_renderer.hpp b/drape_frontend/route_renderer.hpp index f197e92a3d..bf49fd1707 100644 --- a/drape_frontend/route_renderer.hpp +++ b/drape_frontend/route_renderer.hpp @@ -22,7 +22,6 @@ extern std::string const kRouteColor; extern std::string const kRouteOutlineColor; extern std::string const kRoutePedestrian; extern std::string const kRouteBicycle; -extern std::string const kGateColor; extern std::string const kTransitOutlineColor; class RouteRenderer final diff --git a/drape_frontend/rule_drawer.cpp b/drape_frontend/rule_drawer.cpp index c81caa07d6..eb1dea1dd3 100644 --- a/drape_frontend/rule_drawer.cpp +++ b/drape_frontend/rule_drawer.cpp @@ -557,7 +557,6 @@ void RuleDrawer::DrawTileNet(TInsertShapeFn const & insertShape) tp.m_titleDecl.m_primaryTextFont = dp::FontDecl(dp::Color::Red(), 30); tp.m_titleDecl.m_primaryOffset = {0.f, 0.f}; drape_ptr textShape = make_unique_dp(r.Center(), tp, key, - false /* hasPOI */, m2::PointF(0.0, 0.0) /* symbolSize */, dp::Anchor::Center, 0 /* textIndex */); diff --git a/drape_frontend/shaders/shader_index.txt b/drape_frontend/shaders/shader_index.txt index f6de9a5d5b..2541fb8f58 100644 --- a/drape_frontend/shaders/shader_index.txt +++ b/drape_frontend/shaders/shader_index.txt @@ -1,6 +1,6 @@ +COLORED_SYMBOL_PROGRAM colored_symbol.vsh.glsl colored_symbol.fsh.glsl TEXTURING_PROGRAM texturing.vsh.glsl texturing.fsh.glsl MASKED_TEXTURING_PROGRAM masked_texturing.vsh.glsl masked_texturing.fsh.glsl -COLORED_SYMBOL_PROGRAM colored_symbol.vsh.glsl colored_symbol.fsh.glsl TEXT_OUTLINED_PROGRAM text_outlined.vsh.glsl text.fsh.glsl TEXT_PROGRAM text.vsh.glsl text.fsh.glsl TEXT_FIXED_PROGRAM text.vsh.glsl text_fixed.fsh.glsl diff --git a/drape_frontend/shape_view_params.hpp b/drape_frontend/shape_view_params.hpp index 8e8418e1d9..904d24017e 100644 --- a/drape_frontend/shape_view_params.hpp +++ b/drape_frontend/shape_view_params.hpp @@ -17,6 +17,7 @@ namespace df { double const kShapeCoordScalar = 1000; int constexpr kBuildingOutlineSize = 16; +uint32_t constexpr kStartUserMarkOverlayIndex = 1000; struct CommonViewParams { @@ -38,6 +39,7 @@ struct CommonOverlayViewParams : public CommonViewParams { SpecialDisplacement m_specialDisplacement = SpecialDisplacement::None; uint16_t m_specialPriority = std::numeric_limits::max(); + int m_startOverlayRank = 0; }; struct PoiSymbolViewParams : CommonOverlayViewParams diff --git a/drape_frontend/text_shape.cpp b/drape_frontend/text_shape.cpp index cf23901959..b71cb633d8 100644 --- a/drape_frontend/text_shape.cpp +++ b/drape_frontend/text_shape.cpp @@ -110,13 +110,12 @@ private: } // namespace TextShape::TextShape(m2::PointD const & basePoint, TextViewParams const & params, - TileKey const & tileKey, bool hasPOI, + TileKey const & tileKey, m2::PointF const & symbolSize, dp::Anchor symbolAnchor, uint32_t textIndex) : m_basePoint(basePoint) , m_params(params) , m_tileCoords(tileKey.GetTileCoords()) - , m_hasPOI(hasPOI) , m_symbolSize(symbolSize) , m_symbolAnchor(symbolAnchor) , m_textIndex(textIndex) @@ -298,8 +297,10 @@ void TextShape::DrawSubStringPlain(StraightTextLayout const & layout, dp::FontDe std::move(dynamicBuffer), true); handle->SetPivotZ(m_params.m_posZ); - handle->SetOverlayRank(m_hasPOI ? (isPrimary ? dp::OverlayRank1 : dp::OverlayRank2) - : (isPrimary ? dp::OverlayRank0 : dp::OverlayRank1)); + + ASSERT_LESS(m_params.m_startOverlayRank + 1, dp::OverlayRanksCount, ()); + handle->SetOverlayRank(isPrimary ? m_params.m_startOverlayRank : m_params.m_startOverlayRank + 1); + handle->SetExtendingSize(m_params.m_extendingSize); if (m_params.m_specialDisplacement == SpecialDisplacement::UserMark) handle->SetUserMarkOverlay(true); @@ -349,9 +350,13 @@ void TextShape::DrawSubStringOutlined(StraightTextLayout const & layout, dp::Fon std::move(dynamicBuffer), true); handle->SetPivotZ(m_params.m_posZ); - handle->SetOverlayRank(m_hasPOI ? (isPrimary ? dp::OverlayRank1 : dp::OverlayRank2) - : (isPrimary ? dp::OverlayRank0 : dp::OverlayRank1)); + + ASSERT_LESS(m_params.m_startOverlayRank + 1, dp::OverlayRanksCount, ()); + handle->SetOverlayRank(isPrimary ? m_params.m_startOverlayRank : m_params.m_startOverlayRank + 1); + handle->SetExtendingSize(m_params.m_extendingSize); + if (m_params.m_specialDisplacement == SpecialDisplacement::UserMark) + handle->SetUserMarkOverlay(true); dp::AttributeProvider provider(2, static_cast(staticBuffer.size())); provider.InitStream(0, gpu::TextOutlinedStaticVertex::GetBindingInfo(), make_ref(staticBuffer.data())); diff --git a/drape_frontend/text_shape.hpp b/drape_frontend/text_shape.hpp index f520dcd783..89c4b5da54 100644 --- a/drape_frontend/text_shape.hpp +++ b/drape_frontend/text_shape.hpp @@ -16,7 +16,7 @@ class TextShape : public MapShape { public: TextShape(m2::PointD const & basePoint, TextViewParams const & params, - TileKey const & tileKey, bool hasPOI, m2::PointF const & symbolSize, + TileKey const & tileKey, m2::PointF const & symbolSize, dp::Anchor symbolAnchor, uint32_t textIndex); void Draw(ref_ptr batcher, ref_ptr textures) const override; @@ -42,7 +42,6 @@ private: m2::PointD m_basePoint; TextViewParams m_params; m2::PointI m_tileCoords; - bool m_hasPOI; m2::PointF m_symbolSize; dp::Anchor m_symbolAnchor; uint32_t m_textIndex; diff --git a/drape_frontend/user_mark_shapes.cpp b/drape_frontend/user_mark_shapes.cpp index d593e2f76a..2c3a28b373 100644 --- a/drape_frontend/user_mark_shapes.cpp +++ b/drape_frontend/user_mark_shapes.cpp @@ -1,5 +1,6 @@ #include "drape_frontend/user_mark_shapes.hpp" +#include "drape_frontend/colored_symbol_shape.hpp" #include "drape_frontend/line_shape.hpp" #include "drape_frontend/map_shape.hpp" #include "drape_frontend/poi_symbol_shape.hpp" @@ -117,24 +118,67 @@ void CacheUserMarks(TileKey const & tileKey, ref_ptr texture m2::PointD const tileCenter = tileKey.GetGlobalRect().Center(); depthLayer = renderInfo.m_depthLayer; + m2::PointF symbolSize; + std::string symbolName; + if (renderInfo.m_symbolNames != nullptr) + { + for (auto itName = renderInfo.m_symbolNames->rbegin(); itName != renderInfo.m_symbolNames->rend(); ++itName) + { + if (itName->first <= tileKey.m_zoomLevel) + { + symbolName = itName->second; + break; + } + } + } + if (renderInfo.m_hasSymbolPriority) { - PoiSymbolViewParams params(renderInfo.m_featureId); - params.m_tileCenter = tileCenter; - params.m_depth = renderInfo.m_depth; - params.m_depthLayer = renderInfo.m_depthLayer; - params.m_minVisibleScale = renderInfo.m_minZoom; - params.m_specialDisplacement = SpecialDisplacement::UserMark; - params.m_specialPriority = renderInfo.m_priority; - params.m_symbolName = renderInfo.m_symbolName; - PoiSymbolShape(renderInfo.m_pivot, params, tileKey, - 0 /* textIndex */).Draw(&batcher, textures); + if (renderInfo.m_coloredSymbols != nullptr) + { + for (auto itSym = renderInfo.m_coloredSymbols->rbegin(); itSym != renderInfo.m_coloredSymbols->rend(); ++itSym) + { + if (itSym->first <= tileKey.m_zoomLevel) + { + ColoredSymbolViewParams params = itSym->second; + if (params.m_shape == ColoredSymbolViewParams::Shape::Circle) + symbolSize = m2::PointF(params.m_radiusInPixels, params.m_radiusInPixels); + else + symbolSize = params.m_sizeInPixels; + + params.m_featureID = renderInfo.m_featureId; + params.m_tileCenter = tileCenter; + params.m_depth = renderInfo.m_depth; + params.m_depthLayer = renderInfo.m_depthLayer; + params.m_minVisibleScale = renderInfo.m_minZoom; + params.m_specialDisplacement = SpecialDisplacement::UserMark; + params.m_specialPriority = renderInfo.m_priority; + ColoredSymbolShape(renderInfo.m_pivot, params, tileKey, + kStartUserMarkOverlayIndex).Draw(&batcher, textures); + break; + } + } + } + if (renderInfo.m_symbolNames != nullptr) + { + PoiSymbolViewParams params(renderInfo.m_featureId); + params.m_tileCenter = tileCenter; + params.m_depth = renderInfo.m_depth; + params.m_depthLayer = renderInfo.m_depthLayer; + params.m_minVisibleScale = renderInfo.m_minZoom; + params.m_specialDisplacement = SpecialDisplacement::UserMark; + params.m_specialPriority = renderInfo.m_priority; + params.m_symbolName = symbolName; + params.m_startOverlayRank = renderInfo.m_coloredSymbols != nullptr ? dp::OverlayRank1 : dp::OverlayRank0; + PoiSymbolShape(renderInfo.m_pivot, params, tileKey, + kStartUserMarkOverlayIndex).Draw(&batcher, textures); + } } - else if (!renderInfo.m_symbolName.empty()) + else if (renderInfo.m_symbolNames != nullptr) { buffer.reserve(vertexCount); - textures->GetSymbolRegion(renderInfo.m_symbolName, region); + textures->GetSymbolRegion(symbolName, region); m2::RectF const & texRect = region.GetTexRect(); m2::PointF const pxSize = region.GetPixelSize(); dp::Anchor const anchor = renderInfo.m_anchor; @@ -157,42 +201,58 @@ void CacheUserMarks(TileKey const & tileKey, ref_ptr texture buffer.emplace_back(pos, right + up + offset, glsl::ToVec2(texRect.RightBottom()), runAnim); } - if (renderInfo.m_titleDecl != nullptr && !renderInfo.m_titleDecl->m_primaryText.empty()) + if (renderInfo.m_symbolSizes != nullptr) { - TextViewParams params; - params.m_featureID = renderInfo.m_featureId; - params.m_tileCenter = tileCenter; - params.m_titleDecl = *renderInfo.m_titleDecl; + symbolSize = renderInfo.m_symbolSizes->at(static_cast(tileKey.m_zoomLevel - 1)) * vs; + } + else + { + textures->GetSymbolRegion(symbolName, region); + symbolSize.x = max(region.GetPixelSize().x, symbolSize.x); + symbolSize.y = max(region.GetPixelSize().y, symbolSize.y); + } - // Here we use visual scale to adapt texts sizes and offsets - // to different screen resolutions and DPI. - params.m_titleDecl.m_primaryTextFont.m_size *= vs; - params.m_titleDecl.m_secondaryTextFont.m_size *= vs; - params.m_titleDecl.m_primaryOffset *= vs; - params.m_titleDecl.m_secondaryOffset *= vs; - - params.m_depth = renderInfo.m_depth; - params.m_depthLayer = renderInfo.m_depthLayer; - params.m_minVisibleScale = renderInfo.m_minZoom; - if (renderInfo.m_hasTitlePriority) + if (renderInfo.m_titleDecl != nullptr) + { + for (auto const & titleDecl : *renderInfo.m_titleDecl) { - params.m_specialDisplacement = SpecialDisplacement::UserMark; - params.m_specialPriority = renderInfo.m_priority; - } + if (titleDecl.m_primaryText.empty()) + continue; - m2::PointF symbolSize; - if (renderInfo.m_symbolSizes != nullptr) - { - symbolSize = renderInfo.m_symbolSizes->at(static_cast(tileKey.m_zoomLevel)) * vs; - } - else - { - textures->GetSymbolRegion(renderInfo.m_symbolName, region); - symbolSize = region.GetPixelSize(); - } + TextViewParams params; + params.m_featureID = renderInfo.m_featureId; + params.m_tileCenter = tileCenter; + params.m_titleDecl = titleDecl; - TextShape(renderInfo.m_pivot, params, tileKey, renderInfo.m_hasSymbolPriority /* hasPOI */, - symbolSize, renderInfo.m_anchor, 0 /* textIndex */).Draw(&batcher, textures); + // Here we use visual scale to adapt texts sizes and offsets + // to different screen resolutions and DPI. + params.m_titleDecl.m_primaryTextFont.m_size *= vs; + params.m_titleDecl.m_secondaryTextFont.m_size *= vs; + params.m_titleDecl.m_primaryOffset *= vs; + params.m_titleDecl.m_secondaryOffset *= vs; + + params.m_depth = renderInfo.m_depth; + params.m_depthLayer = renderInfo.m_depthLayer; + params.m_minVisibleScale = renderInfo.m_minZoom; + + uint32_t overlayIndex = 0; + if (renderInfo.m_hasTitlePriority) + { + params.m_specialDisplacement = SpecialDisplacement::UserMark; + params.m_specialPriority = renderInfo.m_priority; + overlayIndex = kStartUserMarkOverlayIndex; + + params.m_startOverlayRank = dp::OverlayRank0; + if (renderInfo.m_symbolNames != nullptr) + params.m_startOverlayRank++; + if (renderInfo.m_coloredSymbols != nullptr) + params.m_startOverlayRank++; + ASSERT_LESS(params.m_startOverlayRank, dp::OverlayRanksCount, ()); + } + + TextShape(renderInfo.m_pivot, params, tileKey, + symbolSize, renderInfo.m_anchor, overlayIndex).Draw(&batcher, textures); + } } renderInfo.m_justCreated = false; diff --git a/drape_frontend/user_mark_shapes.hpp b/drape_frontend/user_mark_shapes.hpp index a35e72ab9d..1686065234 100644 --- a/drape_frontend/user_mark_shapes.hpp +++ b/drape_frontend/user_mark_shapes.hpp @@ -18,10 +18,11 @@ struct UserMarkRenderParams int m_minZoom = 1; m2::PointD m_pivot = m2::PointD(0.0, 0.0); m2::PointD m_pixelOffset = m2::PointD(0.0, 0.0); - std::string m_symbolName; dp::Anchor m_anchor = dp::Center; - drape_ptr> m_symbolSizes; - drape_ptr m_titleDecl; + drape_ptr m_symbolSizes; + drape_ptr m_coloredSymbols; + drape_ptr m_symbolNames; + drape_ptr m_titleDecl; bool m_hasSymbolPriority = false; bool m_hasTitlePriority = false; uint16_t m_priority = 0; diff --git a/drape_frontend/user_marks_provider.hpp b/drape_frontend/user_marks_provider.hpp index df14bf0a7a..8685c764c2 100644 --- a/drape_frontend/user_marks_provider.hpp +++ b/drape_frontend/user_marks_provider.hpp @@ -1,6 +1,7 @@ #pragma once #include "drape_frontend/render_state.hpp" +#include "drape_frontend/shape_view_params.hpp" #include "drape/drape_global.hpp" #include "drape/pointers.hpp" @@ -38,6 +39,11 @@ struct MarkIDCollection class UserPointMark { public: + using ColoredSymbolZoomInfo = std::map; + using SymbolNameZoomInfo = std::map; + using SymbolSizesZoomInfo = std::vector; + using TitlesInfo = std::vector; + UserPointMark(); virtual ~UserPointMark() {} @@ -48,13 +54,14 @@ public: virtual m2::PointD const & GetPivot() const = 0; virtual m2::PointD GetPixelOffset() const = 0; - virtual std::string GetSymbolName() const = 0; virtual dp::Anchor GetAnchor() const = 0; virtual float GetDepth() const = 0; virtual RenderState::DepthLayer GetDepthLayer() const = 0; virtual bool IsVisible() const = 0; - virtual drape_ptr GetTitleDecl() const = 0; - virtual drape_ptr> GetSymbolSizes() const = 0; + virtual drape_ptr GetTitleDecl() const = 0; + virtual drape_ptr GetSymbolSizes() const = 0; + virtual drape_ptr GetSymbolNames() const = 0; + virtual drape_ptr GetColoredSymbols() const = 0; virtual uint16_t GetPriority() const = 0; virtual bool HasSymbolPriority() const = 0; virtual bool HasTitlePriority() const = 0; diff --git a/map/api_mark_point.cpp b/map/api_mark_point.cpp index 02d11589c0..fe24568d1f 100644 --- a/map/api_mark_point.cpp +++ b/map/api_mark_point.cpp @@ -41,9 +41,12 @@ ApiMarkPoint::ApiMarkPoint(string const & name, string const & id, string const m_style(style) {} -string ApiMarkPoint::GetSymbolName() const +drape_ptr ApiMarkPoint::GetSymbolNames() const { - return m_style.empty() ? "api-result" : m_style; + auto const name = m_style.empty() ? "api-result" : m_style; + auto symbol = make_unique_dp(); + symbol->insert(std::make_pair(1 /* zoomLevel */, name)); + return symbol; } UserMark::Type ApiMarkPoint::GetMarkType() const diff --git a/map/api_mark_point.hpp b/map/api_mark_point.hpp index c0b8868bc1..04e951e3ea 100644 --- a/map/api_mark_point.hpp +++ b/map/api_mark_point.hpp @@ -25,7 +25,7 @@ public: ApiMarkPoint(string const & name, string const & id, string const & style, m2::PointD const & ptOrg, UserMarkContainer * container); - string GetSymbolName() const override; + drape_ptr GetSymbolNames() const override; UserMark::Type GetMarkType() const override; m2::PointD GetPixelOffset() const override; diff --git a/map/bookmark.cpp b/map/bookmark.cpp index 6746df9eae..48c5bf9542 100644 --- a/map/bookmark.cpp +++ b/map/bookmark.cpp @@ -52,9 +52,12 @@ dp::Anchor Bookmark::GetAnchor() const return dp::Bottom; } -std::string Bookmark::GetSymbolName() const +drape_ptr Bookmark::GetSymbolNames() const { - return GetType(); + auto const name = GetType(); + auto symbol = make_unique_dp(); + symbol->insert(std::make_pair(1 /* zoomLevel */, name)); + return symbol; } bool Bookmark::HasCreationAnimation() const diff --git a/map/bookmark.hpp b/map/bookmark.hpp index 540274b611..5e46c03fdd 100644 --- a/map/bookmark.hpp +++ b/map/bookmark.hpp @@ -81,7 +81,7 @@ public: BookmarkData const & GetData() const; dp::Anchor GetAnchor() const override; - std::string GetSymbolName() const override; + drape_ptr GetSymbolNames() const override; bool HasCreationAnimation() const override; Type GetMarkType() const override; diff --git a/map/framework.cpp b/map/framework.cpp index 648a72cd12..be386c606d 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -370,7 +370,8 @@ Framework::Framework(FrameworkParams const & params) vector const & features) { return m_model.ReadFeatures(fn, features); - }), + }, + [this]() -> StringsBundle const & { return m_stringsBundle; }), static_cast(*this)) , m_trafficManager(bind(&Framework::GetMwmsByRect, this, _1, false /* rough */), kMaxTrafficCacheSizeBytes, m_routingManager.RoutingSession()) diff --git a/map/local_ads_mark.cpp b/map/local_ads_mark.cpp index 997c70fc1d..e990d132f3 100644 --- a/map/local_ads_mark.cpp +++ b/map/local_ads_mark.cpp @@ -30,15 +30,23 @@ LocalAdsMark::LocalAdsMark(m2::PointD const & ptOrg, m_titleDecl.m_secondaryOffset = m2::PointF(0, kSecondaryOffsetY); } +drape_ptr LocalAdsMark::GetSymbolNames() const +{ + auto symbol = make_unique_dp(); + symbol->insert(std::make_pair(1 /* zoomLevel */, m_data.m_symbolName)); + return symbol; +} + df::RenderState::DepthLayer LocalAdsMark::GetDepthLayer() const { return df::RenderState::LocalAdsMarkLayer; } -drape_ptr LocalAdsMark::GetTitleDecl() const +drape_ptr LocalAdsMark::GetTitleDecl() const { - drape_ptr titleDecl = make_unique_dp(m_titleDecl); - return titleDecl; + auto titles = make_unique_dp(); + titles->push_back(m_titleDecl); + return titles; } void LocalAdsMark::SetData(LocalAdsMarkData && data) diff --git a/map/local_ads_mark.hpp b/map/local_ads_mark.hpp index 5745ff1728..c7cfa68863 100644 --- a/map/local_ads_mark.hpp +++ b/map/local_ads_mark.hpp @@ -24,10 +24,10 @@ public: df::RenderState::DepthLayer GetDepthLayer() const override; - std::string GetSymbolName() const override { return m_data.m_symbolName; } + drape_ptr GetSymbolNames() const override; UserMark::Type GetMarkType() const override { return Type::LOCAL_ADS; } - drape_ptr GetTitleDecl() const override; + drape_ptr GetTitleDecl() const override; uint16_t GetPriority() const override { return m_data.m_priority; } bool HasSymbolPriority() const override { return true; } bool HasTitlePriority() const override { return true; } diff --git a/map/routing_manager.cpp b/map/routing_manager.cpp index b540b898e9..baf4837e32 100644 --- a/map/routing_manager.cpp +++ b/map/routing_manager.cpp @@ -19,6 +19,7 @@ #include "drape_frontend/color_constants.hpp" #include "drape_frontend/drape_engine.hpp" +#include "drape_frontend/visual_params.hpp" #include "indexer/map_style_reader.hpp" #include "indexer/scales.hpp" @@ -104,8 +105,19 @@ struct TransitTitle struct TransitMarkInfo { + enum class Type + { + Stop, + KeyStop, + Transfer, + Gate + }; + Type m_type = Type::Stop; m2::PointD m_point; vector m_titles; + std::string m_symbolName; + df::ColorConstant m_color; + FeatureID m_featureId; }; using GetMwmIdFn = function; @@ -150,7 +162,9 @@ void CollectTransitDisplayInfo(vector const & segments, GetMwmIdFn if (gate.m_featureId != transit::kInvalidFeatureId) { auto const featureId = FeatureID(mwmId, gate.m_featureId); - mwmTransit->m_features[featureId] = {}; + TransitFeatureInfo featureInfo; + featureInfo.m_isGate = true; + mwmTransit->m_features[featureId] = featureInfo; } break; } @@ -158,10 +172,10 @@ void CollectTransitDisplayInfo(vector const & segments, GetMwmIdFn } } -void AddTransitGateSegment(m2::PointD const & destPoint, df::Subroute & subroute) +void AddTransitGateSegment(m2::PointD const & destPoint, df::ColorConstant const & color, df::Subroute & subroute) { ASSERT_GREATER(subroute.m_polyline.GetSize(), 0, ()); - df::SubrouteStyle style(df::kGateColor, df::RoutePattern(1.0, 1.0)); + df::SubrouteStyle style(color, df::RoutePattern(4.0, 2.0)); style.m_startIndex = subroute.m_polyline.GetSize() - 1; auto const vec = destPoint - subroute.m_polyline.Back(); subroute.m_polyline.Add(destPoint); @@ -219,8 +233,10 @@ TransitType GetTransitType(string const & type) } void FillTransitStyleForRendering(vector const & segments, TransitReadManager & transitReadManager, - GetMwmIdFn const & getMwmIdFn, df::Subroute & subroute, - vector & transitMarks, TransitRouteInfo & routeInfo) + GetMwmIdFn const & getMwmIdFn, + RoutingManager::Callbacks::GetStringsBundleFn const & getStringsBundleFn, + df::Subroute & subroute, vector & transitMarks, + TransitRouteInfo & routeInfo) { TransitDisplayInfos transitDisplayInfos; CollectTransitDisplayInfo(segments, getMwmIdFn, transitDisplayInfos); @@ -238,6 +254,7 @@ void FillTransitStyleForRendering(vector const & segments, Transit df::SubrouteMarker marker; TransitMarkInfo transitMarkInfo; + std::string transitType; double prevDistance = routeInfo.m_totalDistInMeters; double prevTime = routeInfo.m_totalTimeInSec; @@ -257,6 +274,7 @@ void FillTransitStyleForRendering(vector const & segments, Transit AddTransitPedestrianSegment(s.GetJunction().GetPoint(), subroute); lastColor = ""; + transitType = ""; continue; } @@ -271,8 +289,9 @@ void FillTransitStyleForRendering(vector const & segments, Transit auto const & line = displayInfo.m_lines.at(edge.m_lineId); auto const currentColor = df::GetTransitColorName(line.GetColor()); + transitType = line.GetType(); - routeInfo.AddStep(TransitStepInfo(GetTransitType(line.GetType()), distance, time, + routeInfo.AddStep(TransitStepInfo(GetTransitType(transitType), distance, time, line.GetNumber(), ColorToARGB(currentColor))); auto const & stop1 = displayInfo.m_stops.at(edge.m_stop1Id); @@ -296,7 +315,10 @@ void FillTransitStyleForRendering(vector const & segments, Transit if (pendingEntrance) { - AddTransitGateSegment(marker.m_position, subroute); + transitMarkInfo.m_type = TransitMarkInfo::Type::KeyStop; + transitMarkInfo.m_symbolName = transitType; + transitMarkInfo.m_color = currentColor; + AddTransitGateSegment(marker.m_position, currentColor, subroute); pendingEntrance = false; } @@ -314,12 +336,16 @@ void FillTransitStyleForRendering(vector const & segments, Transit if (lastColor != currentColor) { if (!lastColor.empty()) + { marker.m_scale = kTransferMarkerScale; + transitMarkInfo.m_type = TransitMarkInfo::Type::Transfer; + } marker.m_colors.push_back(currentColor); if (stop1.GetFeatureId() != transit::kInvalidFeatureId) { auto const fid = FeatureID(mwmId, stop1.GetFeatureId()); + transitMarkInfo.m_featureId = fid; transitMarkInfo.m_titles.emplace_back(displayInfo.m_features.at(fid).m_title, df::GetTransitTextColorName(line.GetColor())); } @@ -361,6 +387,7 @@ void FillTransitStyleForRendering(vector const & segments, Transit if (stop2.GetFeatureId() != transit::kInvalidFeatureId) { auto const fid = FeatureID(mwmId, stop2.GetFeatureId()); + transitMarkInfo.m_featureId = fid; transitMarkInfo.m_titles.push_back(TransitTitle(displayInfo.m_features.at(fid).m_title, df::GetTransitTextColorName(line.GetColor()))); } @@ -372,11 +399,14 @@ void FillTransitStyleForRendering(vector const & segments, Transit { routeInfo.AddStep(TransitStepInfo(TransitType::Pedestrian, distance, time)); - AddTransitGateSegment(s.GetJunction().GetPoint(), subroute); + AddTransitGateSegment(s.GetJunction().GetPoint(), lastColor, subroute); subroute.m_markers.push_back(marker); marker = df::SubrouteMarker(); + transitMarkInfo.m_type = TransitMarkInfo::Type::KeyStop; + transitMarkInfo.m_symbolName = transitType; + transitMarkInfo.m_color = lastColor; transitMarks.push_back(transitMarkInfo); transitMarkInfo = TransitMarkInfo(); } @@ -384,17 +414,30 @@ void FillTransitStyleForRendering(vector const & segments, Transit { pendingEntrance = true; } + + auto gateMarkInfo = TransitMarkInfo(); + gateMarkInfo.m_point = pendingEntrance ? subroute.m_polyline.Back() : s.GetJunction().GetPoint(); + gateMarkInfo.m_type = TransitMarkInfo::Type::Gate; + if (gate.m_featureId != transit::kInvalidFeatureId) + { + auto const fid = FeatureID(mwmId, gate.m_featureId); + auto const & featureInfo = displayInfo.m_features.at(fid); + auto symbolName = featureInfo.m_gateSymbolName; + if (strings::EndsWith(symbolName, "-s") || strings::EndsWith(symbolName, "-m") || strings::EndsWith(symbolName, "-l")) + symbolName = symbolName.substr(0, symbolName.length() - 2); + + gateMarkInfo.m_featureId = fid; + gateMarkInfo.m_symbolName = symbolName; + string title = pendingEntrance ? "entrance" : "exit";//getStringsBundleFn().GetString(pendingEntrance ? "entrance" : "exit"); + gateMarkInfo.m_titles.push_back(TransitTitle(title, df::GetTransitTextColorName("default"))); + } + + transitMarks.push_back(gateMarkInfo); } } routeInfo.m_totalDistInMeters = prevDistance; routeInfo.m_totalTimeInSec = static_cast(ceil(prevTime)); - - if (subroute.m_markers.size() > 1) - { - subroute.m_markers.front().m_innerColor = df::kTransitOutlineColor; - subroute.m_markers.back().m_innerColor = df::kTransitOutlineColor; - } } vector GetTransitMarkerSizes(float markerScale) @@ -414,39 +457,125 @@ void CreateTransitMarks(vector const & transitMarks, UserMarksC static vector const kTransferMarkerSizes = GetTransitMarkerSizes(kTransferMarkerScale); static vector const kStopMarkerSizes = GetTransitMarkerSizes(kStopMarkerScale); + static const int kSmallIconZoom = 1; + static const int kMediumIconZoom = 10; + static const int kLargeIconZoom = 15; + + static const float kSmallStationR = 12.0f; + static const float kMediumStationR = 17.0f; + static const float kLargeStationR = 20.0f; + + auto const vs = df::VisualParams::Instance().GetVisualScale(); for (size_t i = 0; i < transitMarks.size(); ++i) { - auto const & mark = transitMarks[i]; - if (!mark.m_titles.empty()) + auto const &mark = transitMarks[i]; + + auto userMark = marksController.CreateUserMark(mark.m_point); + ASSERT(dynamic_cast(userMark) != nullptr, ()); + auto transitMark = static_cast(userMark); + dp::TitleDecl titleDecl; + + transitMark->SetFeatureId(mark.m_featureId); + + if (mark.m_type == TransitMarkInfo::Type::Gate) + { + if (!mark.m_titles.empty()) + { + TransitMark::GetDefaultTransitTitle(titleDecl); + titleDecl.m_primaryText = mark.m_titles.front().m_text; + titleDecl.m_anchor = dp::Anchor::Top; + titleDecl.m_primaryOptional = true; + transitMark->AddTitle(titleDecl); + } + df::UserPointMark::SymbolNameZoomInfo symbolNames; + symbolNames[kSmallIconZoom] = mark.m_symbolName + "-s"; + symbolNames[kMediumIconZoom] = mark.m_symbolName + "-m"; + symbolNames[kLargeIconZoom] = mark.m_symbolName + "-l"; + transitMark->SetSymbolNames(symbolNames); + transitMark->SetPriority(UserMark::Priority::Transit_Gate); + } + else if (mark.m_type == TransitMarkInfo::Type::Transfer) { - auto userMark = marksController.CreateUserMark(mark.m_point); - ASSERT(dynamic_cast(userMark) != nullptr, ()); - auto transitMark = static_cast(userMark); - - transitMark->SetPrimaryText(mark.m_titles.front().m_text); - transitMark->SetPrimaryTextColor(df::GetColorConstant(mark.m_titles.front().m_color)); - if (mark.m_titles.size() > 1) { - transitMark->SetTextPosition(dp::Bottom); - transitMark->SetSymbolSizes(kTransferMarkerSizes); + TransitMark::GetDefaultTransitTitle(titleDecl); + titleDecl.m_primaryText = mark.m_titles.front().m_text; + titleDecl.m_primaryTextFont.m_color = df::GetColorConstant(mark.m_titles.front().m_color); + titleDecl.m_anchor = dp::Anchor::Bottom; + titleDecl.m_primaryOptional = true; + transitMark->AddTitle(titleDecl); - userMark = marksController.CreateUserMark(mark.m_point); - ASSERT(dynamic_cast(userMark) != nullptr, ()); - auto transitMark2 = static_cast(userMark); + titleDecl.m_primaryText = mark.m_titles.back().m_text; + titleDecl.m_primaryTextFont.m_color = df::GetColorConstant(mark.m_titles.back().m_color); + titleDecl.m_anchor = dp::Anchor::Top; + titleDecl.m_primaryOptional = true; + transitMark->AddTitle(titleDecl); + } + df::UserPointMark::ColoredSymbolZoomInfo coloredSymbol; + for (size_t sizeIndex = 0; sizeIndex < kTransferMarkerSizes.size(); ++sizeIndex) + { + auto const zoomLevel = sizeIndex + 1; + auto const & sz = kTransferMarkerSizes[sizeIndex]; + df::ColoredSymbolViewParams params; + params.m_radiusInPixels = static_cast(max(sz.x, sz.y) * vs) / 2.0f; + params.m_color = dp::Color::Transparent(); + if (coloredSymbol.empty() || coloredSymbol.rbegin()->second.m_radiusInPixels != params.m_radiusInPixels) + coloredSymbol.insert(make_pair(zoomLevel, params)); + } + transitMark->SetColoredSymbols(coloredSymbol); + transitMark->SetPriority(UserMark::Priority::Transit_Transfer); + } + else + { + if (!mark.m_titles.empty()) + { + TransitMark::GetDefaultTransitTitle(titleDecl); + titleDecl.m_primaryText = mark.m_titles.front().m_text; + titleDecl.m_primaryTextFont.m_color = df::GetColorConstant(mark.m_titles.front().m_color); + titleDecl.m_anchor = dp::Anchor::Top; + titleDecl.m_primaryOptional = true; + transitMark->AddTitle(titleDecl); + } + if (mark.m_type == TransitMarkInfo::Type::KeyStop) + { + df::UserPointMark::SymbolNameZoomInfo symbolNames; + symbolNames[kSmallIconZoom] = mark.m_symbolName + "-s"; + symbolNames[kMediumIconZoom] = mark.m_symbolName + "-m"; + symbolNames[kLargeIconZoom] = mark.m_symbolName + "-l"; + transitMark->SetSymbolNames(symbolNames); - transitMark2->SetPrimaryText(mark.m_titles.back().m_text); - transitMark2->SetPrimaryTextColor(df::GetColorConstant(mark.m_titles.back().m_color)); - transitMark2->SetTextPosition(dp::Top); - transitMark2->SetSymbolSizes(kTransferMarkerSizes); + df::UserPointMark::ColoredSymbolZoomInfo coloredSymbol; + df::ColoredSymbolViewParams params; + params.m_color = df::GetColorConstant(mark.m_color); + + params.m_radiusInPixels = static_cast(kSmallStationR * vs); + coloredSymbol[kSmallIconZoom] = params; + + params.m_radiusInPixels = static_cast(kMediumStationR * vs); + coloredSymbol[kMediumIconZoom] = params; + + params.m_radiusInPixels = static_cast(kLargeStationR * vs); + coloredSymbol[kLargeIconZoom] = params; + + transitMark->SetColoredSymbols(coloredSymbol); + transitMark->SetPriority(UserMark::Priority::Transit_KeyStop); } else { - transitMark->SetTextPosition(dp::Left); - transitMark->SetSymbolSizes(kStopMarkerSizes); - int const kMinZoomSimpleStopLabel = 16; - if (i > 0 && i + 1 < transitMarks.size()) - transitMark->SetMinZoom(kMinZoomSimpleStopLabel); + df::UserPointMark::ColoredSymbolZoomInfo coloredSymbol; + for (size_t sizeIndex = 0; sizeIndex < kStopMarkerSizes.size(); ++sizeIndex) + { + auto const zoomLevel = sizeIndex + 1; + auto const & sz = kStopMarkerSizes[sizeIndex]; + df::ColoredSymbolViewParams params; + params.m_radiusInPixels = static_cast(max(sz.x, sz.y) * vs) / 2.0f; + params.m_color = dp::Color::Transparent(); + if (coloredSymbol.empty() || coloredSymbol.rbegin()->second.m_radiusInPixels != params.m_radiusInPixels) + coloredSymbol.insert(make_pair(zoomLevel, params)); + } + transitMark->SetMinZoom(16); + transitMark->SetColoredSymbols(coloredSymbol); + transitMark->SetPriority(UserMark::Priority::Transit_Stop); } } } @@ -925,8 +1054,8 @@ void RoutingManager::InsertRoute(Route const & route) transitRouteInfo.AddStep(step); } - FillTransitStyleForRendering(segments, m_transitReadManager, getMwmIdFn, *subroute.get(), - transitMarks, transitRouteInfo); + FillTransitStyleForRendering(segments, m_transitReadManager, getMwmIdFn, m_callbacks.m_stringsBundleGetter, + *subroute.get(), transitMarks, transitRouteInfo); if (subroute->m_polyline.GetSize() < 2) { diff --git a/map/routing_manager.hpp b/map/routing_manager.hpp index f8a6b3b0c8..defceffa84 100644 --- a/map/routing_manager.hpp +++ b/map/routing_manager.hpp @@ -123,21 +123,25 @@ public: using CountryParentNameGetterFn = std::function; using FeatureCallback = std::function; using ReadFeaturesFn = std::function const &)>; + using GetStringsBundleFn = std::function; - - template + template Callbacks(IndexGetter && featureIndexGetter, CountryInfoGetter && countryInfoGetter, - CountryParentNameGetter && countryParentNameGetter, FeatureReader && readFeatures) + CountryParentNameGetter && countryParentNameGetter, + FeatureReader && readFeatures, StringsBundleGetter && stringsBundleGetter) : m_indexGetter(std::forward(featureIndexGetter)) , m_countryInfoGetter(std::forward(countryInfoGetter)) , m_countryParentNameGetterFn(std::forward(countryParentNameGetter)) , m_readFeaturesFn(std::forward(readFeatures)) + , m_stringsBundleGetter(std::forward(stringsBundleGetter)) {} IndexGetterFn m_indexGetter; CountryInfoGetterFn m_countryInfoGetter; CountryParentNameGetterFn m_countryParentNameGetterFn; TReadFeaturesFn m_readFeaturesFn; + GetStringsBundleFn m_stringsBundleGetter; }; using RouteBuildingCallback = diff --git a/map/routing_mark.cpp b/map/routing_mark.cpp index 003fcee7b5..327b421251 100644 --- a/map/routing_mark.cpp +++ b/map/routing_mark.cpp @@ -96,12 +96,14 @@ void RouteMarkPoint::SetMarkData(RouteMarkData && data) m_titleDecl.m_secondaryText.clear(); } -drape_ptr RouteMarkPoint::GetTitleDecl() const +drape_ptr RouteMarkPoint::GetTitleDecl() const { if (m_followingMode) return nullptr; - return make_unique_dp(m_titleDecl); + auto titles = make_unique_dp(); + titles->push_back(m_titleDecl); + return titles; } void RouteMarkPoint::SetFollowingMode(bool enabled) @@ -113,23 +115,27 @@ void RouteMarkPoint::SetFollowingMode(bool enabled) m_followingMode = enabled; } -std::string RouteMarkPoint::GetSymbolName() const +drape_ptr RouteMarkPoint::GetSymbolNames() const { + std::string name; switch (m_markData.m_pointType) { - case RouteMarkType::Start: return "route-point-start"; + case RouteMarkType::Start: name = "route-point-start"; break; case RouteMarkType::Intermediate: { switch (m_markData.m_intermediateIndex) { - case 0: return "route-point-a"; - case 1: return "route-point-b"; - case 2: return "route-point-c"; - default: return ""; + case 0: name = "route-point-a"; break; + case 1: name = "route-point-b"; break; + case 2: name = "route-point-c"; break; + default: name = ""; break; } } - case RouteMarkType::Finish: return "route-point-finish"; + case RouteMarkType::Finish: name = "route-point-finish"; break; } + auto symbol = make_unique_dp(); + symbol->insert(std::make_pair(1 /* zoomLevel */, name)); + return symbol; } size_t const RoutePointsLayout::kMaxIntermediatePointsCount = 3; @@ -375,14 +381,18 @@ void RoutePointsLayout::NotifyChanges() TransitMark::TransitMark(m2::PointD const & ptOrg, UserMarkContainer * container) : UserMark(ptOrg, container) +{} + +void TransitMark::SetFeatureId(FeatureID featureId) { - m_titleDecl.m_anchor = dp::Center; - m_titleDecl.m_primaryTextFont.m_color = df::GetColorConstant(kTransitMarkText); - m_titleDecl.m_primaryTextFont.m_outlineColor = df::GetColorConstant(kTransitMarkTextOutline); - m_titleDecl.m_primaryTextFont.m_size = kTransitMarkTextSize; - m_titleDecl.m_secondaryTextFont.m_color = df::GetColorConstant(kTransitMarkText); - m_titleDecl.m_secondaryTextFont.m_outlineColor = df::GetColorConstant(kTransitMarkTextOutline); - m_titleDecl.m_secondaryTextFont.m_size = kTransitMarkTextSize; + SetDirty(); + m_featureId = featureId; +} + +void TransitMark::SetPriority(Priority priority) +{ + SetDirty(); + m_priority = priority; } void TransitMark::SetMinZoom(int minZoom) @@ -391,51 +401,65 @@ void TransitMark::SetMinZoom(int minZoom) m_minZoom = minZoom; } +void TransitMark::AddTitle(dp::TitleDecl const & titleDecl) +{ + SetDirty(); + m_titles.push_back(titleDecl); +} + +drape_ptr TransitMark::GetTitleDecl() const +{ + auto titles = make_unique_dp(m_titles); + return titles; +} + +void TransitMark::SetSymbolNames(std::map const & symbolNames) +{ + SetDirty(); + m_symbolNames = symbolNames; +} + void TransitMark::SetSymbolSizes(std::vector const & symbolSizes) { SetDirty(); m_symbolSizes = symbolSizes; } -void TransitMark::SetPrimaryText(std::string const & primary) +void TransitMark::SetColoredSymbols(std::map const & symbolParams) { SetDirty(); - m_titleDecl.m_primaryText = primary; + m_coloredSymbols = symbolParams; } -void TransitMark::SetSecondaryText(std::string const & secondary) +drape_ptr TransitMark::GetColoredSymbols() const { - SetDirty(); - m_titleDecl.m_secondaryText = secondary; + if (m_coloredSymbols.empty()) + return nullptr; + return make_unique_dp(m_coloredSymbols); } -void TransitMark::SetTextPosition(dp::Anchor anchor, - m2::PointF const & primaryOffset, m2::PointF const & secondaryOffset) +drape_ptr TransitMark::GetSymbolSizes() const { - SetDirty(); - m_titleDecl.m_primaryOffset = primaryOffset; - m_titleDecl.m_secondaryOffset = secondaryOffset; - m_titleDecl.m_anchor = anchor; + if (m_symbolSizes.empty()) + return nullptr; + return make_unique_dp(m_symbolSizes); } -void TransitMark::SetPrimaryTextColor(dp::Color color) +drape_ptr TransitMark::GetSymbolNames() const { - SetDirty(); - m_titleDecl.m_primaryTextFont.m_color = color; -} + if (m_symbolNames.empty()) + return nullptr; + return make_unique_dp(m_symbolNames); +}; -void TransitMark::SetSecondaryTextColor(dp::Color color) +// static +void TransitMark::GetDefaultTransitTitle(dp::TitleDecl & titleDecl) { - SetDirty(); - m_titleDecl.m_secondaryTextFont.m_color = color; -} - -drape_ptr TransitMark::GetTitleDecl() const -{ - return make_unique_dp(m_titleDecl); -} - -drape_ptr> TransitMark::GetSymbolSizes() const -{ - return make_unique_dp>(m_symbolSizes); -} + titleDecl = dp::TitleDecl(); + titleDecl.m_primaryTextFont.m_color = df::GetColorConstant(kTransitMarkText); + titleDecl.m_primaryTextFont.m_outlineColor = df::GetColorConstant(kTransitMarkTextOutline); + titleDecl.m_primaryTextFont.m_size = kTransitMarkTextSize; + titleDecl.m_secondaryTextFont.m_color = df::GetColorConstant(kTransitMarkText); + titleDecl.m_secondaryTextFont.m_outlineColor = df::GetColorConstant(kTransitMarkTextOutline); + titleDecl.m_secondaryTextFont.m_size = kTransitMarkTextSize; +} \ No newline at end of file diff --git a/map/routing_mark.hpp b/map/routing_mark.hpp index 01e19b9346..6a5df9ae71 100644 --- a/map/routing_mark.hpp +++ b/map/routing_mark.hpp @@ -36,7 +36,7 @@ public: dp::Anchor GetAnchor() const override; df::RenderState::DepthLayer GetDepthLayer() const override; - std::string GetSymbolName() const override; + drape_ptr GetSymbolNames() const override; UserMark::Type GetMarkType() const override { return Type::ROUTING; } bool IsAvailableForSearch() const override { return !IsPassed(); } @@ -58,7 +58,7 @@ public: RouteMarkData const & GetMarkData() const { return m_markData; } void SetMarkData(RouteMarkData && data); - drape_ptr GetTitleDecl() const override; + drape_ptr GetTitleDecl() const override; bool HasSymbolPriority() const override { return false; } bool HasTitlePriority() const override { return true; } @@ -109,28 +109,40 @@ public: dp::Anchor GetAnchor() const override { return dp::Center; } df::RenderState::DepthLayer GetDepthLayer() const override { return df::RenderState::TransitMarkLayer; } - std::string GetSymbolName() const override { return ""; } UserMark::Type GetMarkType() const override { return Type::TRANSIT; } - bool HasSymbolPriority() const override { return false; } + bool HasSymbolPriority() const override { return !m_symbolNames.empty() || !m_coloredSymbols.empty(); } bool HasTitlePriority() const override { return true; } + void SetFeatureId(FeatureID featureId); + FeatureID GetFeatureID() const override { return m_featureId; } + + void SetPriority(Priority priority); + uint16_t GetPriority() const override { return static_cast(m_priority); } + void SetMinZoom(int minZoom); int GetMinZoom() const override { return m_minZoom; } - void SetSymbolSizes(std::vector const & symbolSizes); - drape_ptr> GetSymbolSizes() const override; + void SetSymbolSizes(SymbolSizesZoomInfo const & symbolSizes); + drape_ptr GetSymbolSizes() const override; - void SetPrimaryText(std::string const & primary); - void SetSecondaryText(std::string const & secondary); - void SetTextPosition(dp::Anchor anchor, m2::PointF const & primaryOffset = m2::PointF(0.0f, 0.0f), - m2::PointF const & secondaryOffset = m2::PointF(0.0f, 0.0f)); - void SetPrimaryTextColor(dp::Color color); - void SetSecondaryTextColor(dp::Color color); - drape_ptr GetTitleDecl() const override; + void SetColoredSymbols(ColoredSymbolZoomInfo const & symbolParams); + drape_ptr GetColoredSymbols() const override; + + void SetSymbolNames(SymbolNameZoomInfo const & symbolNames); + drape_ptr GetSymbolNames() const override; + + void AddTitle(dp::TitleDecl const & titleDecl); + drape_ptr GetTitleDecl() const override; + + static void GetDefaultTransitTitle(dp::TitleDecl & titleDecl); private: int m_minZoom = 1; - dp::TitleDecl m_titleDecl; - std::vector m_symbolSizes; -}; + Priority m_priority; + FeatureID m_featureId; + TitlesInfo m_titles; + SymbolSizesZoomInfo m_symbolSizes; + SymbolNameZoomInfo m_symbolNames; + ColoredSymbolZoomInfo m_coloredSymbols; +}; \ No newline at end of file diff --git a/map/search_mark.cpp b/map/search_mark.cpp index eb0c6b71cb..055c4612b0 100644 --- a/map/search_mark.cpp +++ b/map/search_mark.cpp @@ -24,20 +24,26 @@ SearchMarkPoint::SearchMarkPoint(m2::PointD const & ptOrg, UserMarkContainer * c : UserMark(ptOrg, container) {} -std::string SearchMarkPoint::GetSymbolName() const +drape_ptr SearchMarkPoint::GetSymbolNames() const { + std::string name; if (m_isPreparing) { //TODO: set symbol for preparing state. - return "non-found-search-result"; + name = "non-found-search-result"; } - - if (m_type >= SearchMarkType::Count) + else if (m_type >= SearchMarkType::Count) { ASSERT(false, ("Unknown search mark symbol.")); - return kSymbols[static_cast(SearchMarkType::Default)]; + name = kSymbols[static_cast(SearchMarkType::Default)]; } - return kSymbols[static_cast(m_type)]; + else + { + name = kSymbols[static_cast(m_type)]; + } + auto symbol = make_unique_dp(); + symbol->insert(std::make_pair(1 /* zoomLevel */, name)); + return symbol; } UserMark::Type SearchMarkPoint::GetMarkType() const diff --git a/map/search_mark.hpp b/map/search_mark.hpp index 91b06530dd..b66d68fc90 100644 --- a/map/search_mark.hpp +++ b/map/search_mark.hpp @@ -30,7 +30,7 @@ class SearchMarkPoint : public UserMark public: SearchMarkPoint(m2::PointD const & ptOrg, UserMarkContainer * container); - std::string GetSymbolName() const override; + drape_ptr GetSymbolNames() const override; UserMark::Type GetMarkType() const override; FeatureID GetFeatureID() const override { return m_featureID; } diff --git a/map/transit_reader.cpp b/map/transit_reader.cpp index 377a1df838..d18b35bb81 100644 --- a/map/transit_reader.cpp +++ b/map/transit_reader.cpp @@ -1,7 +1,11 @@ #include "map/transit_reader.hpp" +#include "indexer/drawing_rules.hpp" +#include "indexer/drules_include.hpp" #include "indexer/feature_algo.hpp" +#include "drape_frontend/stylist.hpp" + using namespace routing; using namespace std; @@ -134,6 +138,19 @@ void ReadTransitTask::Do() { auto & featureInfo = m_transitInfo->m_features[ft.GetID()]; ft.GetReadableName(featureInfo.m_title); + if (featureInfo.m_isGate) + { + df::Stylist stylist; + if (df::InitStylist(ft, 0, 19, false, stylist)) + { + stylist.ForEachRule([&](df::Stylist::TRuleWrapper const & rule) + { + auto const * symRule = rule.first->GetSymbol(); + if (symRule != nullptr) + featureInfo.m_gateSymbolName = symRule->name(); + }); + } + } featureInfo.m_point = feature::GetCenter(ft); }, features); } diff --git a/map/transit_reader.hpp b/map/transit_reader.hpp index 72e9392ff7..d91f0754bf 100644 --- a/map/transit_reader.hpp +++ b/map/transit_reader.hpp @@ -66,6 +66,8 @@ private: struct TransitFeatureInfo { + bool m_isGate = false; + std::string m_gateSymbolName; std::string m_title; m2::PointD m_point; }; diff --git a/map/user_mark.cpp b/map/user_mark.cpp index fdf2d32c6e..2e4d6cc3b0 100644 --- a/map/user_mark.cpp +++ b/map/user_mark.cpp @@ -70,9 +70,11 @@ DebugMarkPoint::DebugMarkPoint(const m2::PointD & ptOrg, UserMarkContainer * con : UserMark(ptOrg, container) {} -string DebugMarkPoint::GetSymbolName() const +drape_ptr DebugMarkPoint::GetSymbolNames() const { - return "api-result"; + auto symbol = make_unique_dp(); + symbol->insert(std::make_pair(1 /* zoomLevel */, "api-result")); + return symbol; } string DebugPrint(UserMark::Type type) diff --git a/map/user_mark.hpp b/map/user_mark.hpp index ec337b9351..b57dd534bb 100644 --- a/map/user_mark.hpp +++ b/map/user_mark.hpp @@ -18,7 +18,14 @@ class UserMarkContainer; class UserMark : public df::UserPointMark { public: - static uint16_t constexpr kDefaultUserMarkPriority = 0xFFFF; + enum class Priority: uint16_t + { + Default = 0, + Transit_Stop, + Transit_Gate, + Transit_Transfer, + Transit_KeyStop + }; enum class Type { @@ -43,9 +50,10 @@ public: dp::Anchor GetAnchor() const override; float GetDepth() const override; df::RenderState::DepthLayer GetDepthLayer() const override; - drape_ptr GetTitleDecl() const override { return nullptr; } - drape_ptr> GetSymbolSizes() const override { return nullptr; } - uint16_t GetPriority() const override { return kDefaultUserMarkPriority; } + drape_ptr GetTitleDecl() const override { return nullptr; } + drape_ptr GetSymbolSizes() const override { return nullptr; } + drape_ptr GetColoredSymbols() const override { return nullptr; } + uint16_t GetPriority() const override { return static_cast(Priority::Default); } bool HasSymbolPriority() const override { return false; } bool HasTitlePriority() const override { return false; } int GetMinZoom() const override { return 1; } @@ -74,7 +82,7 @@ class StaticMarkPoint : public UserMark public: explicit StaticMarkPoint(UserMarkContainer * container); - string GetSymbolName() const override { return {}; } + drape_ptr GetSymbolNames() const override { return nullptr; } UserMark::Type GetMarkType() const override; void SetPtOrg(m2::PointD const & ptOrg); @@ -101,7 +109,7 @@ class DebugMarkPoint : public UserMark public: DebugMarkPoint(m2::PointD const & ptOrg, UserMarkContainer * container); - string GetSymbolName() const override; + drape_ptr GetSymbolNames() const override; Type GetMarkType() const override { return UserMark::Type::DEBUG_MARK; } };