| 113 | /// |points| is any standard container of m2::Point with random access iterator. |
| 114 | template <typename Container> |
| 115 | impl::MultiPolygon TrianglesToPolygon(Container const & points) |
| 116 | { |
| 117 | size_t constexpr kTriangleSize = 3; |
| 118 | if (points.size() % kTriangleSize != 0) |
| 119 | MYTHROW(geometry::NotAPolygonException, ("Count of points must be multiple of", kTriangleSize)); |
| 120 | |
| 121 | std::vector<impl::MultiPolygon> polygons; |
| 122 | for (size_t i = 0; i < points.size(); i += kTriangleSize) |
| 123 | { |
| 124 | impl::MultiPolygon polygon; |
| 125 | polygon.resize(1); |
| 126 | auto & p = polygon[0]; |
| 127 | auto & outer = p.outer(); |
| 128 | for (size_t j = i; j < i + kTriangleSize; ++j) |
| 129 | outer.push_back(impl::PointXY(points[j].x, points[j].y)); |
| 130 | boost::geometry::correct(p); |
| 131 | if (!boost::geometry::is_valid(polygon)) |
| 132 | MYTHROW(geometry::NotAPolygonException, ("The triangle is not valid")); |
| 133 | polygons.push_back(polygon); |
| 134 | } |
| 135 | |
| 136 | if (polygons.empty()) |
| 137 | return {}; |
| 138 | |
| 139 | auto & result = polygons[0]; |
| 140 | for (size_t i = 1; i < polygons.size(); ++i) |
| 141 | { |
| 142 | impl::MultiPolygon u; |
| 143 | boost::geometry::union_(result, polygons[i], u); |
| 144 | u.swap(result); |
| 145 | } |
| 146 | return result; |
| 147 | } |
| 148 | } // namespace geometry |