#pragma once #include "geometry/point2d.hpp" #include "geometry/rect2d.hpp" #include "geometry/distance.hpp" #include "base/internal/message.hpp" #include "std/initializer_list.hpp" #include "std/vector.hpp" namespace m2 { template class PolylineT { vector > m_points; public: PolylineT() {} PolylineT(initializer_list > points) : m_points(points) { ASSERT_GREATER(m_points.size(), 1, ()); } explicit PolylineT(vector > const & points) : m_points(points) { ASSERT_GREATER(m_points.size(), 1, ()); } template PolylineT(IterT beg, IterT end) : m_points(beg, end) { ASSERT_GREATER(m_points.size(), 1, ()); } double GetLength() const { // @todo add cached value and lazy init double dist = 0; for (size_t i = 1; i < m_points.size(); ++i) dist += m_points[i-1].Length(m_points[i]); return dist; } double GetShortestSquareDistance(m2::Point const & point) const { double res = numeric_limits::max(); m2::DistanceToLineSquare > d; TIter i = Begin(); for (TIter j = i + 1; j != End(); ++i, ++j) { d.SetBounds(*i, *j); res = min(res, d(point)); } return res; } Rect GetLimitRect() const { // @todo add cached value and lazy init m2::Rect rect; for (size_t i = 0; i < m_points.size(); ++i) rect.Add(m_points[i]); return rect; } void Clear() { m_points.clear(); } void Add(Point const & pt) { m_points.push_back(pt); } void Swap(PolylineT & rhs) { m_points.swap(rhs.m_points); } size_t GetSize() const { return m_points.size(); } bool operator==(PolylineT const & rhs) const { return m_points == rhs.m_points; } typedef vector > TContainer; typedef typename TContainer::const_iterator TIter; TIter Begin() const { return m_points.begin(); } TIter End() const { return m_points.end(); } Point const & Front() const { return m_points.front(); } Point const & Back() const { return m_points.back(); } Point const & GetPoint(size_t idx) const { ASSERT_LESS(idx, m_points.size(), ()); return m_points[idx]; } vector > const & GetPoints() const { return m_points; } friend string DebugPrint(PolylineT const & p) { return ::DebugPrint(p.m_points); } }; typedef PolylineT PolylineD; }