diff --git a/indexer/displacement_manager.hpp b/indexer/displacement_manager.hpp index 75f6f923b7..59161d6977 100644 --- a/indexer/displacement_manager.hpp +++ b/indexer/displacement_manager.hpp @@ -18,7 +18,7 @@ namespace { -double constexpr kPOIPerTileSizeCount = 6; +double constexpr kPOIPerTileSizeCount = 5; } // namespace namespace covering @@ -88,94 +88,81 @@ class DisplacementManager public: DisplacementManager(TSorter & sorter) : m_sorter(sorter) {} - /// Add feature at bucket (zoom) to displacable queue if possible. Pass to bucket otherwise. + /// Add feature at bucket (zoom) to displaceable queue if possible. Pass to bucket otherwise. template void Add(vector const & cells, uint32_t bucket, TFeature const & ft, uint32_t index) { + // Add to displaceable storage if we need to displace POI. if (bucket != scales::GetUpperScale() && IsDisplaceable(ft)) { - m_storage[bucket].emplace_back(cells, ft, index, bucket); + m_storage.emplace_back(cells, ft, index, bucket); return; } + // Pass feature to the index otherwise. for (auto const & cell : cells) m_sorter.Add(CellFeatureBucketTuple(CellFeaturePair(cell, index), bucket)); } - /// Check features intersection and pass result to sorter. + /// Check features intersection and supress drawing of intersected features. + /// As a result some features may have bigger scale parameter than style describes. + /// But every feature has MaxScale at least. + /// After all features passed to sorter. void Displace() { m4::Tree acceptedNodes; - list deferredNodes; - for (uint32_t scale = 0; scale < scales::GetUpperScale(); ++scale) + + sort(m_storage.begin(), m_storage.end()); + for (auto const & node : m_storage) { - // Initialize queue. - priority_queue displaceableQueue; - for (auto const & node : m_storage[scale]) - displaceableQueue.push(node); - for (auto const & node : deferredNodes) - displaceableQueue.push(node); - deferredNodes.clear(); - - float const delta = CalculateDeltaForZoom(scale); - size_t accepted = 0; - - // Process queue. - while (!displaceableQueue.empty()) + uint32_t scale = node.m_minScale; + for (; scale < scales::GetUpperScale(); ++scale) { - DisplaceableNode const maxNode = displaceableQueue.top(); - displaceableQueue.pop(); + float const delta = CalculateDeltaForZoom(scale); + float const squaredDelta = delta * delta; - // Check if this node is displaced by higher features. - m2::RectD const displacementRect(maxNode.center, maxNode.center); + m2::RectD const displacementRect(node.m_center, node.m_center); bool isDisplaced = false; acceptedNodes.ForEachInRect(m2::Inflate(displacementRect, {delta, delta}), - [&isDisplaced, &maxNode, &delta, &scale](DisplaceableNode const & node) + [&isDisplaced, &node, &squaredDelta, &scale](DisplaceableNode const & rhs) { - if (maxNode.center.SquareLength(node.center) < delta * delta && node.maxScale > scale) + if (node.m_center.SquareLength(rhs.m_center) < squaredDelta && rhs.m_maxScale > scale) isDisplaced = true; }); if (isDisplaced) - { - deferredNodes.push_back(maxNode); continue; - } // Add feature to index otherwise. - AddNodeToSorter(maxNode, scale); - acceptedNodes.Add(maxNode); - accepted++; + AddNodeToSorter(node, scale); + acceptedNodes.Add(node); + break; } - - LOG(LINFO, ("Displacement for scale", scale, "Features accepted:", accepted, - "Features discarded:", deferredNodes.size())); + if (scale == scales::GetUpperScale()) + AddNodeToSorter(node, scale); } - - // Add all fully displaced features to the bottom scale. - for (auto const & node : deferredNodes) - AddNodeToSorter(node, scales::GetUpperScale()); } private: struct DisplaceableNode { - uint32_t index; - m2::PointD center; - vector cells; + uint32_t m_index; + m2::PointD m_center; + vector m_cells; - int maxScale; - uint32_t priority; + int m_minScale; + int m_maxScale; + uint32_t m_priority; - DisplaceableNode() : index(0), maxScale(0), priority(0) {} + DisplaceableNode() : m_index(0), m_minScale(0), m_maxScale(0), m_priority(0) {} template DisplaceableNode(vector const & cells, TFeature const & ft, uint32_t index, int zoomLevel) - : index(index), center(ft.GetCenter()), cells(cells) + : m_index(index), m_center(ft.GetCenter()), m_cells(cells), m_minScale(zoomLevel) { feature::TypesHolder const types(ft); auto scaleRange = feature::GetDrawableScaleRange(types); - maxScale = scaleRange.second; + m_maxScale = scaleRange.second; // Calculate depth field drule::KeysT keys; @@ -192,15 +179,15 @@ private: float const kMaxDepth = 100000.0f; float const d = my::clamp(depth, kMinDepth, kMaxDepth) - kMinDepth; uint8_t rank = ft.GetRank(); - priority = (static_cast(d) << 8) | rank; + m_priority = (static_cast(d) << 8) | rank; } - bool operator<(DisplaceableNode const & node) const { return priority < node.priority; } - m2::RectD const GetLimitRect() const { return m2::RectD(center, center); } + bool operator<(DisplaceableNode const & rhs) const { return m_priority < rhs.m_priority; } + m2::RectD const GetLimitRect() const { return m2::RectD(m_center, m_center); } }; template - bool IsDisplaceable(TFeature const & ft) const + static bool IsDisplaceable(TFeature const & ft) { feature::TypesHolder const types(ft); return types.GetGeoType() == feature::GEOM_POINT; @@ -216,11 +203,11 @@ private: void AddNodeToSorter(DisplaceableNode const & node, uint32_t scale) { - for (auto const & cell : node.cells) - m_sorter.Add(CellFeatureBucketTuple(CellFeaturePair(cell, node.index), scale)); + for (auto const & cell : node.m_cells) + m_sorter.Add(CellFeatureBucketTuple(CellFeaturePair(cell, node.m_index), scale)); } TSorter & m_sorter; - map> m_storage; + vector m_storage; }; } // namespace indexer